Changing style of PDF-Latex output through IPython Notebook conversion

后端 未结 3 1233
梦如初夏
梦如初夏 2021-02-15 23:42

Currently with the following command of my .ipynb file:

$ ipython nbconvert --to latex --post PDF Untitled1.ipynb --SphinxTransformer.author=\"John Doe\"
[NbConv         


        
3条回答
  •  滥情空心
    2021-02-16 00:02

    Solving this problem is a real pain-in-the-butt. I also liked the iPython 0.x and 1.x styling. If you must have it, here's how you can do it.

    Folks mentioned that you can create your own template. Well, iPython 1.x had perfectly good templates, so let's use them. I'm going to assume you have root on your machine, because we're going to hack our iPython's templates/latex directory.

    # 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
    

    Now, the next step is to apply a patch to 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 -*))
    

    Cut and paste the above code to create the patch file. Then you can apply it with:

    patch -p0 < sphinx_patch.patch
    

    We're not done yet. Those templates need some support.

    We'll do this back in the directory where the notebook you want to convert lives. We're going to create two python files. The first (I called it oldschool.py) does the preprocessing necessary to use the older templates. It is mostly scraped out of version 1.x iPython's nbconvert/transformers/sphinx.py and hacked to be a modern Preprocessor:

    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
    

    The last file is easy ({config.py}).

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

    Now, at the command line, you can do:

    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
    

    If you want to use basic (aka, {the old_latex_basic.tplx} file), you'll have to hack in the the main block of code we added to sphinx.tplx (the portion between the % MEF NEW NEW MEF comments).

提交回复
热议问题