diff --git a/nbconvert.py b/nbconvert.py index 0c3e963..f062eac 100755 --- a/nbconvert.py +++ b/nbconvert.py @@ -86,7 +86,10 @@ class Converter(object): infile_dir = str() infile_root = str() files_dir = str() - + with_preamble = True + user_preamble = None + output = str() + def __init__(self, infile): self.infile = infile self.infile_dir = os.path.dirname(infile) @@ -283,7 +286,7 @@ class ConverterRST(Converter): @DocInherit def _img_lines(self, img_file): - return ['.. image:: %s' % figfile, ''] + return ['.. image:: %s' % img_file, ''] @DocInherit def render_stream(self, output): @@ -298,6 +301,7 @@ class ConverterRST(Converter): def render_unknown(self, cell): return rst_directive('.. warning:: Unknown cell') + [repr(cell)] + class ConverterQuickHTML(Converter): extension = 'html' @@ -400,12 +404,14 @@ class ConverterLaTeX(Converter): (or set the equivalent flag at startup or in your configuration profile). """ extension = 'tex' - heading_marker = {1: r'\section', - 2: r'\subsection', - 3: r'\subsubsection', - 4: r'\paragraph', - 5: r'\subparagraph', - 6: r'\subparagraph'} + documentclass = 'article' + documentclass_options = '11pt,english' + heading_map = {1: r'\section', + 2: r'\subsection', + 3: r'\subsubsection', + 4: r'\paragraph', + 5: r'\subparagraph', + 6: r'\subparagraph'} def env(self, environment, lines): """Return list of environment lines for input lines @@ -423,10 +429,49 @@ class ConverterLaTeX(Converter): out.extend(lines) out.append(r'\end{%s}' % environment) return out - + + def convert(self): + # The main body is done by the logic in the parent class, and that's + # all we need if preamble support has been turned off. + body = super(ConverterLaTeX, self).convert() + if not self.with_preamble: + return body + # But if preamble is on, then we need to construct a proper, standalone + # tex file. + + # Tag the document at the top and set latex class + final = [ r'%% This file was auto-generated by IPython, do NOT edit', + r'%% Conversion from the original notebook file:', + r'%% {0}'.format(self.infile), + r'%%', + r'\documentclass[%s]{%s}' % (self.documentclass_options, + self.documentclass), + '', + ] + # Load our own preamble, which is stored next to the main file. We + # need to be careful in case the script entry point is a symlink + myfile = __file__ if not os.path.islink(__file__) else \ + os.readlink(__file__) + with open(os.path.join(os.path.dirname(myfile), 'preamble.tex')) as f: + final.append(f.read()) + + # Load any additional user-supplied preamble + if self.user_preamble: + final.extend(['', '%% Adding user preamble from file:', + '%% {0}'.format(self.user_preamble), '']) + with open(self.user_preamble) as f: + final.append(f.read()) + + # Include document body + final.extend([ r'\begin{document}', '', + body, + r'\end{document}', '']) + # Retun value must be a string + return '\n'.join(final) + @DocInherit def render_heading(self, cell): - marker = self.heading_marker[cell.level] + marker = self.heading_map[cell.level] return ['%s{%s}\n\n' % (marker, cell.source) ] @DocInherit diff --git a/preamble.tex b/preamble.tex new file mode 100644 index 0000000..4507790 --- /dev/null +++ b/preamble.tex @@ -0,0 +1,89 @@ +%% This is the automatic preamble used by IPython. Note that it does *not* +%% include a documentclass declaration, that is added at runtime to the overall +%% document. + +\usepackage{amsmath} +\usepackage{amssymb} +\usepackage{graphicx} + +% Slightly bigger margins than the latex defaults +\usepackage{geometry} +\geometry{verbose,tmargin=3cm,bmargin=3cm,lmargin=2.5cm,rmargin=2.5cm} + +% Define a few colors for use in code, links and cell shading +\usepackage{color} +\definecolor{orange}{cmyk}{0,0.4,0.8,0.2} +\definecolor{darkorange}{rgb}{.71,0.21,0.01} +\definecolor{darkgreen}{rgb}{.12,.54,.11} +\definecolor{myteal}{rgb}{.26, .44, .56} +\definecolor{gray}{rgb}{0.45, 0.45, 0.45} +\definecolor{lightgray}{rgb}{.95, .95, .95} +\definecolor{inputbackground}{rgb}{.95, .95, .85} +\definecolor{outputbackground}{rgb}{.95, .95, .95} +\definecolor{traceback}{rgb}{1, .95, .95} + +% Framed environments for code cells (inputs, outputs, errors, ...). The +% various uses of \unskip (or not) at the end were fine-tuned by hand, so don't +% randomly change them unless you're sure of the effect it will have. +\usepackage{framed} + +% remove extraneous vertical space in boxes +\setlength\fboxsep{0pt} + +% codecell is the whole input+output set of blocks that a Code cell can +% generate. +\newenvironment{codecell}{% + \def\FrameCommand{\vrule width 0.5pt \hspace{5pt}}% + \MakeFramed{\FrameRestore}} + {\unskip\endMakeFramed} + + \newenvironment{codeinput}{% + \def\FrameCommand{\colorbox{inputbackground}}% + \MakeFramed{\advance\hsize-\width \FrameRestore}} + {\unskip\endMakeFramed} + +\newenvironment{codeoutput}{% + \def\FrameCommand{\colorbox{outputbackground}}% + \MakeFramed{\advance\hsize-\width \FrameRestore}} + {\unskip\medskip\endMakeFramed} + +\newenvironment{traceback}{% + \def\FrameCommand{\colorbox{traceback}}% + \MakeFramed{\advance\hsize-\width \FrameRestore}} + {\endMakeFramed} + +% The hyperref package gives us a pdf with properly built +% internal navigation ('pdf bookmarks' for the table of contents, +% internal cross-reference links, web links for URLs, etc.) +\usepackage{hyperref} +\hypersetup{ + breaklinks=true, % so long urls are correctly broken across lines + colorlinks=true, + urlcolor=blue, + linkcolor=darkorange, + citecolor=darkgreen, + } + +% Use and configure listings package for nicely formatted code +\usepackage{listings} +\lstset{ + language=python, + aboveskip=\smallskipamount, + belowskip=\smallskipamount, + %xleftmargin=3mm, + breaklines=true, + basicstyle=\small \ttfamily, + showstringspaces=false, + keywordstyle=\color{blue}\bfseries, + commentstyle=\color{myteal}, + stringstyle=\color{darkgreen}, + identifierstyle=\color{darkorange}, +} + +% hardcode size of all verbatim environments to be a bit smaller +\makeatletter +\g@addto@macro\@verbatim\small +\makeatother + +% Prevent overflowing lines due to urls and other hard-to-break entities. +\sloppy