通过IPython笔记本转换更改PDF乳胶输出的样式

2024-04-29 12:26:03 发布

您现在位置:Python中文网/ 问答频道 /正文

当前使用我的.ipynb file的以下命令:

$ ipython nbconvert --to latex --post PDF Untitled1.ipynb --SphinxTransformer.author="John Doe"
[NbConvertApp] Using existing profile dir: u'/Users/me-macmini/.ipython/profile_default'
[NbConvertApp] Converting notebook Untitled1.ipynb to latex
[NbConvertApp] Support files will be in Untitled1_files/
[NbConvertApp] Loaded template article.tplx
[NbConvertApp] Writing 12876 bytes to Untitled1.tex
[NbConvertApp] Building PDF
[NbConvertApp] Running pdflatex 3 times: [u'pdflatex', u'Untitled1.tex']
[NbConvertApp] Running bibtex 1 time: [u'bibtex', u'Untitled1']
[NbConvertApp] WARNING | bibtex had problems, most likely because there were no citations
[NbConvertApp] Removing temporary LaTeX files
[NbConvertApp] PDF successfully created

使用IPython 2.1,我得到了用标准古典风格格式化的乳胶文件:

enter image description here

我的问题是:

  1. 我该怎么做才能从ipython命令获得以下样式? enter image description here

  2. 为什么上面的命令不能让作者出现?


Tags: to命令pdfipythonfilesbibtexprofilerunning
3条回答

和OP一样,我对nbconvert的输出不太满意。由于转换器不再使用Sphinx documentclass或Sphinx预处理系统,因此不能在nbconverter行上使用SphinxTransformer调用。

粗鲁的方式

删除--post PDF,这样nbconvert只创建.tex文件。然后,编辑.tex文件,使其更漂亮。然后,对它运行pdflatex几次。

要使自己成为作者,请在he.tex文件中的\title行之后添加一行如下:

\author{Never Saint}

您可以在latextemplates.com找到很好的模板来帮助您使输出看起来像您想要的那样。

根用户的方式

另一种方法是滚动一个新模板,从.../IPython/nbconvert/templates/latex中的模板开始。作为根用户,在article.tplxreport.tplx旁边添加一个article1.tplx文件。下面的版本创建了一个我个人认为有用的不同输出样式。“margins”块生成乳胶的前页,“predoc”块生成插入文档开头的命令和文本。我把“maketitle”块清空,这样就没有标题页了。如果你想有一个有作者和日期的标题页,请删除我的空“maketitle”块。

用法:nbconvert --to latex yourNotebook.ipynb --template article1 --to PDF

% Default to the notebook output style
((* if not cell_style is defined *))
    ((* set cell_style = 'style_ipython.tplx' *))
((* endif *))

% Inherit from the specified cell style.
((* extends cell_style *))


%===============================================================================
% Latex article1, based on Article 
%===============================================================================

((* block docclass *))
\documentclass{article}
((* endblock docclass *))
((* block margins *))
\usepackage{blindtext}
\usepackage{mathptmx}% Times Roman font
\usepackage[scaled=.90]{helvet}
\usepackage{xcolor}
\usepackage{titlesec}
\titleformat{\title}[display]
  {\normalfont\sffamily\huge\bfseries\color{blue}}
  {\titlename}{20pt}{\Huge}
\titleformat{\section}
  {\normalfont\sffamily\Large\bfseries\color{darkgray}}
  {\subsection}{1em}{} 
\titleformat{\subsection}
  {\normalfont\sffamily\Large\bfseries\color{darkgray}}
  {\thesubsection}{1em}{} 
\parindent=0pt
\parskip=6pt
((* endblock margins *))

((* block predoc *))
\begin{document}

\pagestyle{plain}
\thispagestyle{plain}
\pagenumbering{arabic}
\setcounter{page}{5}
\lfoot{\copyright 2014}

This document is composed as an
\href{http://ipython.org/notebook.html}{IPython} notebook. The printed
version of this document was generated from the \texttt{IPython}
notebook, using the \texttt{ipython nbconvert} utility to generate a
\texttt{Latex} document. 
((* block maketitle *))((* endblock maketitle *))
((* block author *))\author{Put Your Name Here}((* endblock author *))
((* endblock predoc *))

您可能必须选择不同的template,或者构建自己的。尝试将--template book参数添加到nbconvert命令中。

由于IPython 2不再有book模板,您可能需要自己滚动。

解决这个问题真是令人痛心。我也喜欢iPython 0.x和1.x的样式。如果你必须拥有它,这里是你如何做到的。

人们提到你可以创建自己的模板。嗯,iPython 1.x有非常好的模板,所以让我们使用它们。我假设你的机器上有根目录,因为我们要破解iPython的templates/latex目录。

# set for your python/ipython install
PYTHONLIB=/usr/lib64/python2.7/site-packages/
cd ${PYTHONLIB}/IPython/nbconvert/templates/latex

# download the files
for tplx in sphinx.tplx latex_article.tplx latex_book.tplx latex_basic.tplx; do
    wget https://raw.githubusercontent.com/ipython/ipython/1.x/IPython/nbconvert/templates/latex/${tplx} -O old_${tplx}
done

# update for some renaming that we just did
for tplx in old_latex_*.tplx; do
    sed -i 's|sphinx.tplx|old_sphinx.tplx|' ${tplx}
done

现在,下一步是对sphinx.tplx应用补丁。

% cat sphinx_patch.patch
--- old_sphinx.tplx     2015-02-13 14:52:14.000000000 -0500
+++ mod_old_sphinx.tplx 2015-02-13 14:53:00.000000000 -0500
@@ -71,6 +71,7 @@
     % Pygments requirements
     \usepackage{fancyvrb}
     \usepackage{color}
+
     % ansi colors additions
     \definecolor{darkgreen}{rgb}{.12,.54,.11}
     \definecolor{lightgray}{gray}{.95}
@@ -83,6 +84,29 @@
     \definecolor{lightpurple}{rgb}{0.87,0.63,0.87}
     \definecolor{lightcyan}{rgb}{0.5,1.0,0.83}

+    %
+    % MEF NEW NEW MEF
+    %
+    \DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}}
+    \newenvironment{Shaded}{}{}
+    \newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{{#1}}}}
+    \newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.56,0.13,0.00}{{#1}}}
+    \newcommand{\DecValTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}}
+    \newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}}
+    \newcommand{\FloatTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}}
+    \newcommand{\CharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}}
+    \newcommand{\StringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}}
+    \newcommand{\CommentTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textit{{#1}}}}
+    \newcommand{\OtherTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{{#1}}}
+    \newcommand{\AlertTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}}
+    \newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.02,0.16,0.49}{{#1}}}
+    \newcommand{\RegionMarkerTok}[1]{{#1}}
+    \newcommand{\ErrorTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}}
+    \newcommand{\NormalTok}[1]{{#1}}
+    %
+    % MEF NEW NEW MEF
+    %
+    
     % Needed to box output/input
     \usepackage{tikz}
         \usetikzlibrary{calc,arrows,shadows}
@@ -374,7 +398,6 @@
 ((* if resources.sphinx.centeroutput *))
     \begin{center}
 ((* endif -*))
-((( output.latex | strip_math_space )))
 ((*- if resources.sphinx.centeroutput *))
     \end{center}
 ((* endif -*))

剪切并粘贴上述代码以创建修补程序文件。然后您可以将其应用于:

patch -p0 < sphinx_patch.patch

我们还没结束。这些模板需要一些支持。

我们将在你想要转换生命的笔记本所在的目录中执行此操作。我们将创建两个python文件。第一个(我称之为oldschool.py)执行使用旧模板所需的预处理。它主要是从1.x版iPython的nbconvert/transformers/sphinx.py中删除的,并被黑客攻击为一个现代的预处理器:

from __future__ import print_function, absolute_import
from IPython.nbconvert.preprocessors.base import Preprocessor
from IPython.utils.traitlets import Bool, Unicode
import os

class MySphinxyLatexPreprocessor(Preprocessor):
    interactive = Bool(False, config=True, help="""
        Allows you to define whether or not the Sphinx exporter will prompt
        you for input during the conversion process.  If this is set to false,
        the author, version, release, date, and chapter_style traits should
        be set.
        """)

    author = Unicode("Unknown Author", config=True, help="Author name")

    version = Unicode("", config=True, help="""
        Version number
        You can leave this blank if you do not want to render a version number.
        Example: "1.0.0"
        """)

    release = Unicode("", config=True, help="""
        Release name
        You can leave this blank if you do not want to render a release name.
        Example: "Rough Draft"
        """)

    publish_date = Unicode("", config=True, help="""
        Publish date
        This is the date to render on the document as the publish date.
        Leave this blank to default to todays date.  
        Example: "June 12, 1990"
        """)

    chapter_style = Unicode("Bjarne", config=True, help="""
        Sphinx chapter style
        This is the style to use for the chapter headers in the document.
        You may choose one of the following:
            "Bjarne"    (default)
            "Lenny"
            "Glenn"
            "Conny"
            "Rejne"
            "Sonny"    (used for international documents)
        """)

    output_style = Unicode("notebook", config=True, help="""
        Nbconvert Ipython
        notebook input/output formatting style.
        You may choose one of the following:
            "simple     (recommended for long code segments)"
            "notebook"  (default)
        """)

    center_output = Bool(False, config=True, help="""
        Optional attempt to center all output.  If this is false, no additional
        formatting is applied.
        """)

    use_headers = Bool(True, config=True, help="""
        Whether not a header should be added to the document.
        """)

    #Allow the user to override the title of the notebook (useful for
    #fancy document titles that the file system doesn't support.)
    overridetitle = Unicode("", config=True, help="")



    def preprocess(self, nb, resources):
        """
        Sphinx and LaTeX transformation to apply on each notebook.

        Parameters
        ----------
        nb : NotebookNode
            Notebook being converted
        resources : dictionary
            Additional resources used in the conversion process.  Allows
            transformers to pass variables into the Jinja engine.
        """
        # Generate Pygments definitions for Latex
        from pygments.formatters import LatexFormatter
        import sphinx
        sphinxPath = os.path.realpath(os.path.join(sphinx.package_dir,
                                                   "texinputs"))

        #
        # MEF:  set a latex resource
        # old from latex preprocessor
        # resources["latex"]["pygments_definitions"] = LatexFormatter(style='emacs').get_style_defs()
        # Generate Pygments definitions for Latex 
        # old from sphinx transformer
        # resources["sphinx"]["pygment_definitions"] = self._generate_pygments_latex_def()
        # the mashup:
        #resources["sphinx"]["pygment_definitions"] = \
        #         LatexFormatter(style='emacs').get_style_defs()
        # used below

        # MEF edit
        resources.setdefault("sphinx", {})
        #if not "sphinx" in resources:
        #    resources["sphinx"] = {}

        #
        # set sphinx resources
        #
        resources["sphinx"]["pygment_definitions"] = LatexFormatter().get_style_defs()
                                                   # LatexFormatter(style='emacs').get_style_defs()



        # Try to use the traitlets.
        resources["sphinx"]["author"] = self.author
        resources["sphinx"]["version"] = self.version
        resources["sphinx"]["release"] = self.release

        # Use todays date if none is provided.
        if self.publish_date:
            resources["sphinx"]["date"] = self.publish_date
        elif len(resources['metadata']['modified_date'].strip()) == 0:
            resources["sphinx"]["date"] = date.today().strftime(text.date_format)
        else:
            resources["sphinx"]["date"] = resources['metadata']['modified_date']

        # Sphinx traitlets.
        resources["sphinx"]["chapterstyle"] = self.chapter_style
        resources["sphinx"]["outputstyle"] = self.output_style
        resources["sphinx"]["centeroutput"] = self.center_output
        resources["sphinx"]["header"] = self.use_headers

        # Find and pass in the path to the Sphinx dependencies.
        resources["sphinx"]["texinputs"] = sphinxPath


        #
        # MEF edit
        #
        if self.overridetitle and len(self.overridetitle.strip()):
                resources['metadata']['name'] = self.overridetitle.strip()

        return nb, resources

最后一个文件很简单({config.py})。

c = get_config()
c.Exporter.preprocessors = ['oldschool.MySphinxyLatexPreprocessor']

现在,在命令行中,您可以执行以下操作:

ipython nbconvert example.ipynb --to latex --config config.py --template old_latex_article.tplx --post PDF
ipython nbconvert example.ipynb --to latex --config config.py --template old_latex_book.tplx --post PDF

如果你想使用basic(又称{the old_latex_basic.tplx}文件),你必须破解我们添加到sphinx.tplx的主要代码块(在%MEF NEW MEF注释之间的部分)。

相关问题 更多 >