##// END OF EJS Templates
lots of modification for latex
Matthias BUSSONNIER -
Show More
@@ -0,0 +1,65
1 #!/usr/bin/env python
2 #-----------------------------------------------------------------------------
3 # Imports
4 #-----------------------------------------------------------------------------
5 from __future__ import print_function
6 import sys
7 import io
8
9 from converters.template import *
10 from converters.template import ConverterTemplate
11 from converters.html import ConverterHTML
12 # From IPython
13
14 # All the stuff needed for the configurable things
15 from IPython.config.application import Application
16 from IPython.utils.traitlets import List, Unicode, Type, Bool, Dict, CaselessStrEnum
17
18
19 class NbconvertApp(Application):
20
21
22 def __init__(self, **kwargs):
23 super(NbconvertApp, self).__init__(**kwargs)
24 self.classes.insert(0,ConverterTemplate)
25 # ensure those are registerd
26
27
28 def initialize(self, argv=None):
29 self.parse_command_line(argv)
30 cl_config = self.config
31 self.update_config(cl_config)
32
33
34
35 def run(self):
36 """Convert a notebook to html in one step"""
37 template_file = (self.extra_args or [None])[0]
38 ipynb_file = (self.extra_args or [None])[1]
39
40 template_file = sys.argv[1]
41
42 if template_file.startswith('latex'):
43 tex_environement=True
44 else:
45 tex_environement=False
46
47 C = ConverterTemplate(tplfile=sys.argv[1], tex_environement=tex_environement, config=self.config)
48 C.read(ipynb_file)
49
50 output,rest = C.convert()
51
52 print(output.encode('utf-8'))
53
54 def main():
55 """Convert a notebook to html in one step"""
56 app = NbconvertApp.instance()
57 app.initialize()
58 app.start()
59 app.run()
60 #-----------------------------------------------------------------------------
61 # Script main
62 #-----------------------------------------------------------------------------
63
64 if __name__ == '__main__':
65 main()
@@ -1,221 +1,232
1 1 """Base classes for the notebook conversion pipeline.
2 2
3 3 This module defines Converter, from which all objects designed to implement
4 4 a conversion of IPython notebooks to some other format should inherit.
5 5 """
6 6 #-----------------------------------------------------------------------------
7 7 # Copyright (c) 2012, the IPython Development Team.
8 8 #
9 9 # Distributed under the terms of the Modified BSD License.
10 10 #
11 11 # The full license is in the file COPYING.txt, distributed with this software.
12 12 #-----------------------------------------------------------------------------
13 13
14 14 #-----------------------------------------------------------------------------
15 15 # Imports
16 16 #-----------------------------------------------------------------------------
17 17
18 18 from __future__ import print_function, absolute_import
19 19
20 20 # Stdlib imports
21 21 import io
22 22 import os
23 23 import re
24 24 from IPython.utils import path
25 25
26 26 from jinja2 import Environment, FileSystemLoader
27 27 env = Environment(
28 28 loader=FileSystemLoader('./templates/'),
29 29 extensions=['jinja2.ext.loopcontrols']
30 30 )
31 31
32 32 texenv = Environment(
33 33 loader=FileSystemLoader('./templates/tex/'),
34 34 extensions=['jinja2.ext.loopcontrols']
35 35 )
36 36
37 37 # IPython imports
38 38 from IPython.nbformat import current as nbformat
39 39 from IPython.config.configurable import Configurable
40 from IPython.utils.traitlets import ( Unicode, Any)
40 from IPython.utils.traitlets import ( Unicode, Any, List)
41 41
42 42 # Our own imports
43 43 from IPython.utils.text import indent
44 44 from .utils import remove_ansi
45 45 from markdown import markdown
46 46 from .utils import highlight, ansi2html
47 47 from .utils import markdown2latex
48 48 #-----------------------------------------------------------------------------
49 49 # Class declarations
50 50 #-----------------------------------------------------------------------------
51 51 def rm_fake(strng):
52 52 return strng.replace('/files/', '')
53 53
54 54 class ConversionException(Exception):
55 55 pass
56 56
57 57
58 58 def python_comment(string):
59 59 return '# '+'\n# '.join(string.split('\n'))
60 60
61 61
62 62
63 63 def header_body():
64 64 """Return the body of the header as a list of strings."""
65 65
66 66 from pygments.formatters import HtmlFormatter
67 67
68 68 header = []
69 69 static = os.path.join(path.get_ipython_package_dir(),
70 70 'frontend', 'html', 'notebook', 'static',
71 71 )
72 72 here = os.path.split(os.path.realpath(__file__))[0]
73 73 css = os.path.join(static, 'css')
74 74 for sheet in [
75 75 # do we need jquery and prettify?
76 76 # os.path.join(static, 'jquery', 'css', 'themes', 'base',
77 77 # 'jquery-ui.min.css'),
78 78 # os.path.join(static, 'prettify', 'prettify.css'),
79 79 os.path.join(css, 'boilerplate.css'),
80 80 os.path.join(css, 'fbm.css'),
81 81 os.path.join(css, 'notebook.css'),
82 82 os.path.join(css, 'renderedhtml.css'),
83 83 # our overrides:
84 84 os.path.join(here, '..', 'css', 'static_html.css'),
85 85 ]:
86 86
87 87 with io.open(sheet, encoding='utf-8') as f:
88 88 s = f.read()
89 89 header.append(s)
90 90
91 91 pygments_css = HtmlFormatter().get_style_defs('.highlight')
92 92 header.append(pygments_css)
93 93 return header
94 94
95 95 inlining = {}
96 96 inlining['css'] = header_body()
97 97
98 98
99 def filter_data_type(output):
100 for fmt in ['html', 'pdf', 'svg', 'latex', 'png', 'jpg', 'jpeg' , 'text']:
101 if fmt in output:
102 return [fmt]
103 99
104 100
105 env.filters['filter_data_type'] = filter_data_type
101
102
106 103 env.filters['pycomment'] = python_comment
107 104 env.filters['indent'] = indent
108 105 env.filters['rm_fake'] = rm_fake
109 106 env.filters['rm_ansi'] = remove_ansi
110 107 env.filters['markdown'] = markdown
111 108 env.filters['highlight'] = highlight
112 109 env.filters['ansi2html'] = ansi2html
113 110
114 111
115 112
116 113 LATEX_SUBS = (
117 114 (re.compile(r'\\'), r'\\textbackslash'),
118 115 (re.compile(r'([{}_#%&$])'), r'\\\1'),
119 116 (re.compile(r'~'), r'\~{}'),
120 117 (re.compile(r'\^'), r'\^{}'),
121 118 (re.compile(r'"'), r"''"),
122 119 (re.compile(r'\.\.\.+'), r'\\ldots'),
123 120 )
124 121
125 122 def escape_tex(value):
126 123 newval = value
127 124 for pattern, replacement in LATEX_SUBS:
128 125 newval = pattern.sub(replacement, newval)
129 126 return newval
130 127
131 128 texenv.block_start_string = '((*'
132 129 texenv.block_end_string = '*))'
133 130 texenv.variable_start_string = '((('
134 131 texenv.variable_end_string = ')))'
135 132 texenv.comment_start_string = '((='
136 133 texenv.comment_end_string = '=))'
137 134 texenv.filters['escape_tex'] = escape_tex
138 135
139 texenv.filters['filter_data_type'] = filter_data_type
140 136 texenv.filters['pycomment'] = python_comment
141 137 texenv.filters['indent'] = indent
142 138 texenv.filters['rm_fake'] = rm_fake
143 139 texenv.filters['rm_ansi'] = remove_ansi
144 140 texenv.filters['markdown'] = markdown
145 141 texenv.filters['highlight'] = highlight
146 142 texenv.filters['ansi2html'] = ansi2html
147 143 texenv.filters['markdown2latex'] = markdown2latex
148 144 markdown2latex
149 145
150 146
151 147 def haspyout_transformer(nb,_):
152 148 print('calling...')
153 149 for worksheet in nb.worksheets:
154 150 print('worksheet')
155 151 for cell in worksheet.cells:
156 152 cell.type = cell.cell_type
157 153 cell.haspyout = False
158 154 for out in cell.get('outputs', []):
159 155 if out.output_type == 'pyout':
160 156 cell.haspyout = True
161 157 break
162 158 return nb
163 159
164 160 class ConverterTemplate(Configurable):
165 161 """ A Jinja2 base converter templates"""
166 162
167 display_data_priority = ['pdf', 'svg', 'png', 'jpg', 'text']
163 display_data_priority = List(['html', 'pdf', 'svg', 'latex', 'png', 'jpg', 'jpeg' , 'text'],
164 config=True,
165 help= """
166 A list of ast.NodeTransformer subclass instances, which will be applied
167 to user input before code is run.
168 """
169 )
168 170 #-------------------------------------------------------------------------
169 171 # Instance-level attributes that are set in the constructor for this
170 172 # class.
171 173 #-------------------------------------------------------------------------
172 174 infile = Any()
173 175
174 176
175 177 infile_dir = Unicode()
178 def display_data_priority_changed(self, name, old, new):
179 print('== changed', name,old,new)
180
181 def filter_data_type(self,output):
182 for fmt in self.display_data_priority:
183 if fmt in output:
184 return [fmt]
176 185
177 186 def __init__(self, tplfile='fullhtml', preprocessors=[], config=None,tex_environement=False, **kw):
178 187 """
179 188 tplfile : jinja template file to process.
180 189
181 190 config: the Configurable confg object to pass around
182 191
183 192 preprocessors: list of function to run on ipynb json data before conversion
184 193 to extract/inline file,
185 194
186 195 """
187 196 self.env = texenv if tex_environement else env
188 197 self.ext = '.tplx' if tex_environement else '.tpl'
189 self.template = self.env.get_template(tplfile+self.ext)
190 198 self.nb = None
191 199 self.preprocessors = preprocessors
192 200 self.preprocessors.append(haspyout_transformer)
193 201 super(ConverterTemplate, self).__init__(config=config, **kw)
202 self.env.filters['filter_data_type'] = self.filter_data_type
203 self.template = self.env.get_template(tplfile+self.ext)
204
194 205
195 206
196 207 def process(self):
197 208 """
198 209 preprocess the notebook json for easier use with the templates.
199 210 will call all the `preprocessor`s in order before returning it.
200 211 """
201 212 nb = self.nb
202 213
203 214 for preprocessor in self.preprocessors:
204 215 nb = preprocessor(nb,{})
205 216
206 217 return nb
207 218
208 219 def convert(self):
209 220 """ convert the ipynb file
210 221
211 222 return both the converted ipynb file and a dict containing potential
212 223 other resources
213 224 """
214 225 return self.template.render(nb=self.process(), inlining=inlining), {}
215 226
216 227
217 228 def read(self, filename):
218 229 "read and parse notebook into NotebookNode called self.nb"
219 230 with io.open(filename) as f:
220 231 self.nb = nbformat.read(f, 'json')
221 232
@@ -1,21 +1,22
1 1 #!/usr/bin/env python
2 2 # coding: utf-8
3 3
4 4 from __future__ import print_function
5 5 import sys
6 6 import io
7 7 from converters.template import *
8 8
9
9 10 template_file = sys.argv[1]
10 11
11 12 if template_file.startswith('latex'):
12 13 tex_environement=True
13 14 else:
14 15 tex_environement=False
15 16
16 17 C = ConverterTemplate(tplfile=sys.argv[1], tex_environement=tex_environement)
17 18 C.read(sys.argv[2])
18 19
19 20 output,rest = C.convert()
20 21
21 22 print(output.encode('utf-8'))
@@ -1,22 +1,23
1 1
2 2
3 3 all: tex/null.tplx tex/display_priority.tplx
4 4
5 5 # convert jinja syntax to tex
6 6 # cf http://flask.pocoo.org/snippets/55/
7 7 tex/%.tplx: %.tpl
8 8 @echo 'generating tex equivalent of $^: $@'
9 9 @echo '((= autogenerated file do not edit =))' > $@
10 10 @sed \
11 11 -e 's/{%/((*/g' \
12 12 -e 's/%}/*))/g' \
13 13 -e 's/{{/(((/g' \
14 14 -e 's/}}/)))/g' \
15 15 -e 's/{#/((=/g' \
16 16 -e 's/#}/=))/g' \
17 -e "s/tpl'/tplx'/g" \
17 18 $^ >> $@
18 19
19 20
20 21 clean:
21 22 @echo "cleaning generated tplx files..."
22 23 @rm tex/*
@@ -1,46 +1,46
1 1 ((= autogenerated file do not edit =))
2 ((*- extends 'null.tpl' -*))
2 ((*- extends 'null.tplx' -*))
3 3
4 4 ((=display data priority=))
5 5
6 6
7 7 ((*- block data_priority scoped -*))
8 8 ((*- for type in output | filter_data_type -*))
9 9 ((*- if type in ['pdf']*))
10 10 ((*- block data_pdf -*))
11 11 ->> pdf
12 12 ((*- endblock -*))
13 13 ((*- endif -*))
14 14 ((*- if type in ['svg']*))
15 15 ((*- block data_svg -*))
16 16 ->> svg
17 17 ((*- endblock -*))
18 18 ((*- endif -*))
19 19 ((*- if type in ['png']*))
20 20 ((*- block data_png -*))
21 21 ->> png
22 22 ((*- endblock -*))
23 23 ((*- endif -*))
24 24 ((*- if type in ['html']*))
25 25 ((*- block data_html -*))
26 26 ->> html
27 27 ((*- endblock -*))
28 28 ((*- endif -*))
29 29 ((*- if type in ['jpeg']*))
30 30 ((*- block data_jpg -*))
31 31 ->> jpg
32 32 ((*- endblock -*))
33 33 ((*- endif -*))
34 34 ((*- if type in ['text']*))
35 35 ((*- block data_text -*))
36 36 ->> text
37 37 ((*- endblock -*))
38 38 ((*- endif -*))
39 39
40 40 ((*- if type in ['latex']*))
41 41 ((*- block data_latex -*))
42 42 ->> latext
43 43 ((*- endblock -*))
44 44 ((*- endif -*))
45 45 ((*- endfor -*))
46 46 ((*- endblock data_priority -*))
@@ -1,198 +1,201
1 ((*- extends 'null.tplx' -*))
1 ((*- extends 'display_priority.tplx' -*))
2 2
3 ((* block in_prompt *))
4 # In[(((cell.prompt_number if cell.prompt_number else ' ')))]:
5 ((* endblock in_prompt *))
3 ((* block in_prompt *))((* endblock in_prompt *))
6 4
7 ((* block output_prompt *))
8 # Out[(((cell.prompt_number)))]:((* endblock output_prompt *))
5 ((* block output_prompt *))((* endblock output_prompt *))
9 6
10 ((* block codecell *))
11 \begin{codecell}
12 ((( super() )))
7 ((* block codecell *))\begin{codecell}((( super() )))
13 8 \end{codecell}
14 9 ((* endblock *))
15 10
16 11 ((* block input *))
17 12 \begin{codeinput}
18 13 \begin{lstlisting}
19 14 ((( cell.input )))
20 15 \end{lstlisting}
21 16 \end{codeinput}
22 17 ((* endblock input *))
23 18
24 19
25 20 ((= Those Two are for error displaying
26 21 even if the first one seem to do nothing,
27 22 it introduces a new line
28 23
29 24 =))
30 25 ((* block pyerr *))((( super() )))
31 26 ((* endblock pyerr *))
32 27
33 28 ((* block traceback_line *))
34 29 ((( line |indent| rm_ansi )))((* endblock traceback_line *))
35 30 ((= .... =))
36 31
37 32
33 ((*- block output_group -*))
34 \begin{codeoutput}
35 ((( super() )))
36 \end{codeoutput}((* endblock *))
37
38
38 39 ((* block pyout *))
39 ((( output.text| indent | pycomment)))
40 ((( output.text)))
40 41 ((* endblock pyout *))
41 42
43 ((* block data_text *))
44 \begin{verbatim}
45 ((( output.text )))
46 \end{verbatim}
47 ((* endblock *))
48
42 49 ((* block stream *))
43 ((( output.text| indent | pycomment)))
50 \begin{verbatim}
51 ((( output.text)))
52 \end{verbatim}
44 53 ((* endblock stream *))
45 54
46 55
47 56
48 57
49 ((* block display_data scoped *))
50 # image file:
51 ((* endblock display_data *))
52
53 ((* block markdowncell scoped *))
54 ((( cell.source | markdown2latex )))
58 ((* block markdowncell scoped *))((( cell.source | markdown2latex )))
55 59 ((* endblock markdowncell *))
56 60
57 61 ((* block headingcell scoped *))
58 62 \section{((( cell.source)))}
59 63 ((* endblock headingcell *))
60 64
61 65 ((* block rawcell scoped *))
62 66 ((( cell.source | pycomment )))
63 67 ((* endblock rawcell *))
64 68
65 69 ((* block unknowncell scoped *))
66 70 unknown type (((cell.type)))
67 71 ((* endblock unknowncell *))
68 72
69 73
70 74
71 ((* block body *))
72 \begin{document}
75 ((* block body *))\begin{document}
73 76 ((( super() )))
74 77 \end{document}
75 78 ((* endblock*))
76 79
77 80 ((* block header *))
78 81 %% This file was auto-generated by IPython.
79 82 %% Conversion from the original notebook file:
80 83 %% tests/ipynbref/Gun_Data.orig.ipynb
81 84 %%
82 85 \documentclass[11pt,english]{article}
83 86
84 87 %% This is the automatic preamble used by IPython. Note that it does *not*
85 88 %% include a documentclass declaration, that is added at runtime to the overall
86 89 %% document.
87 90
88 91 \usepackage{amsmath}
89 92 \usepackage{amssymb}
90 93 \usepackage{graphicx}
91 94 \usepackage{ucs}
92 95 \usepackage[utf8x]{inputenc}
93 96
94 97 % needed for markdown enumerations to work
95 98 \usepackage{enumerate}
96 99
97 100 % Slightly bigger margins than the latex defaults
98 101 \usepackage{geometry}
99 102 \geometry{verbose,tmargin=3cm,bmargin=3cm,lmargin=2.5cm,rmargin=2.5cm}
100 103
101 104 % Define a few colors for use in code, links and cell shading
102 105 \usepackage{color}
103 106 \definecolor{orange}{cmyk}{0,0.4,0.8,0.2}
104 107 \definecolor{darkorange}{rgb}{.71,0.21,0.01}
105 108 \definecolor{darkgreen}{rgb}{.12,.54,.11}
106 109 \definecolor{myteal}{rgb}{.26, .44, .56}
107 110 \definecolor{gray}{gray}{0.45}
108 111 \definecolor{lightgray}{gray}{.95}
109 112 \definecolor{mediumgray}{gray}{.8}
110 113 \definecolor{inputbackground}{rgb}{.95, .95, .85}
111 114 \definecolor{outputbackground}{rgb}{.95, .95, .95}
112 115 \definecolor{traceback}{rgb}{1, .95, .95}
113 116
114 117 % Framed environments for code cells (inputs, outputs, errors, ...). The
115 118 % various uses of \unskip (or not) at the end were fine-tuned by hand, so don't
116 119 % randomly change them unless you're sure of the effect it will have.
117 120 \usepackage{framed}
118 121
119 122 % remove extraneous vertical space in boxes
120 123 \setlength\fboxsep{0pt}
121 124
122 125 % codecell is the whole input+output set of blocks that a Code cell can
123 126 % generate.
124 127
125 128 % TODO: unfortunately, it seems that using a framed codecell environment breaks
126 129 % the ability of the frames inside of it to be broken across pages. This
127 130 % causes at least the problem of having lots of empty space at the bottom of
128 131 % pages as new frames are moved to the next page, and if a single frame is too
129 132 % long to fit on a page, will completely stop latex from compiling the
130 133 % document. So unless we figure out a solution to this, we'll have to instead
131 134 % leave the codecell env. as empty. I'm keeping the original codecell
132 135 % definition here (a thin vertical bar) for reference, in case we find a
133 136 % solution to the page break issue.
134 137
135 138 %% \newenvironment{codecell}{%
136 139 %% \def\FrameCommand{\color{mediumgray} \vrule width 1pt \hspace{5pt}}%
137 140 %% \MakeFramed{\vspace{-0.5em}}}
138 141 %% {\unskip\endMakeFramed}
139 142
140 143 % For now, make this a no-op...
141 144 \newenvironment{codecell}{}
142 145
143 146 \newenvironment{codeinput}{%
144 147 \def\FrameCommand{\colorbox{inputbackground}}%
145 148 \MakeFramed{\advance\hsize-\width \FrameRestore}}
146 149 {\unskip\endMakeFramed}
147 150
148 151 \newenvironment{codeoutput}{%
149 152 \def\FrameCommand{\colorbox{outputbackground}}%
150 153 \vspace{-1.4em}
151 154 \MakeFramed{\advance\hsize-\width \FrameRestore}}
152 155 {\unskip\medskip\endMakeFramed}
153 156
154 157 \newenvironment{traceback}{%
155 158 \def\FrameCommand{\colorbox{traceback}}%
156 159 \MakeFramed{\advance\hsize-\width \FrameRestore}}
157 160 {\endMakeFramed}
158 161
159 162 % Use and configure listings package for nicely formatted code
160 163 \usepackage{listingsutf8}
161 164 \lstset{
162 165 language=python,
163 166 inputencoding=utf8x,
164 167 extendedchars=\true,
165 168 aboveskip=\smallskipamount,
166 169 belowskip=\smallskipamount,
167 170 xleftmargin=2mm,
168 171 breaklines=true,
169 172 basicstyle=\small \ttfamily,
170 173 showstringspaces=false,
171 174 keywordstyle=\color{blue}\bfseries,
172 175 commentstyle=\color{myteal},
173 176 stringstyle=\color{darkgreen},
174 177 identifierstyle=\color{darkorange},
175 178 columns=fullflexible, % tighter character kerning, like verb
176 179 }
177 180
178 181 % The hyperref package gives us a pdf with properly built
179 182 % internal navigation ('pdf bookmarks' for the table of contents,
180 183 % internal cross-reference links, web links for URLs, etc.)
181 184 \usepackage{hyperref}
182 185 \hypersetup{
183 186 breaklinks=true, % so long urls are correctly broken across lines
184 187 colorlinks=true,
185 188 urlcolor=blue,
186 189 linkcolor=darkorange,
187 190 citecolor=darkgreen,
188 191 }
189 192
190 193 % hardcode size of all verbatim environments to be a bit smaller
191 194 \makeatletter
192 195 \g@addto@macro\@verbatim\small\topsep=0.5em\partopsep=0pt
193 196 \makeatother
194 197
195 198 % Prevent overflowing lines due to urls and other hard-to-break entities.
196 199 \sloppy
197 200
198 201 ((* endblock *))
General Comments 0
You need to be logged in to leave comments. Login now