【问题标题】:Changing style of PDF-Latex output through IPython Notebook conversion通过 IPython Notebook 转换改变 PDF-Latex 输出的风格
【发布时间】:2014-07-08 05:37:41
【问题描述】:

目前使用我.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,我得到了使用标准经典样式格式化的乳胶文件:

我的问题是:

  1. 我应该怎么做才能直接从 ipython 命令获得以下样式?

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

【问题讨论】:

标签: python pdf latex type-conversion ipython


【解决方案1】:

和 OP 一样,我对来自 nbconvertIPython 2 输出不太满意。由于转换器不再使用 Sphinx 文档类或 Sphinx 预处理系统,因此您不能在 nbconverter 行上使用 SphinxTransformer 调用。

粗鲁的方式

删除--post PDF,所以nbconvert 只创建.tex 文件。然后,编辑.tex 文件使其更漂亮。然后,在其上运行pdflatex 几次。

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

\author{Never Saint}

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

根用户的方式

另一种方法是滚动一个新模板,从.../IPython/nbconvert/templates/latex 中的模板开始。作为 root 用户,在article.tplxreport.tplx 旁边添加一个article1.tplx 文件。以下版本创建了我个人认为有用的不同输出样式。 “margins”块为 LaTex 生成前文,“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 *))

【讨论】:

    【解决方案2】:

    解决这个问题真的很麻烦。我也喜欢 iPython 0.x 和 1.x 样式。如果你必须拥有它,那么你可以这样做。

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

    # 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
    

    如果你想使用基本的(又名,{old_latex_basic.tplx} 文件),你必须破解我们添加到 sphinx.tplx 的主要代码块(% MEF NEW NEW MEF 之间的部分厘米)。

    【讨论】:

      【解决方案3】:

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

      由于 IPython 2 不再具有 book 模板,您可能需要自己编写。

      【讨论】:

      • 我试过了。我使用 IPython 2.1.0,“书”作为模板不再。所以,我试着用“报告”代替。仍然没有产生我想要的结果。
      • @neversaint 那么您可能需要使用适当的字体选择制作自己的模板。
      猜你喜欢
      • 1970-01-01
      • 2015-07-24
      • 2013-01-01
      • 2020-06-27
      • 2016-03-27
      • 2017-09-23
      • 1970-01-01
      • 2014-06-11
      相关资源
      最近更新 更多