##// END OF EJS Templates
add html_text and add_anchor filters...
MinRK -
Show More
@@ -1,346 +1,348
1 """This module defines Exporter, a highly configurable converter
1 """This module defines Exporter, a highly configurable converter
2 that uses Jinja2 to export notebook files into different formats.
2 that uses Jinja2 to export notebook files into different formats.
3 """
3 """
4
4
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
6 # Copyright (c) 2013, the IPython Development Team.
7 #
7 #
8 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
9 #
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 from __future__ import print_function, absolute_import
17 from __future__ import print_function, absolute_import
18
18
19 # Stdlib imports
19 # Stdlib imports
20 import io
20 import io
21 import os
21 import os
22 import inspect
22 import inspect
23 from copy import deepcopy
23 from copy import deepcopy
24
24
25 # other libs/dependencies
25 # other libs/dependencies
26 from jinja2 import Environment, FileSystemLoader, ChoiceLoader
26 from jinja2 import Environment, FileSystemLoader, ChoiceLoader
27
27
28 # IPython imports
28 # IPython imports
29 from IPython.config.configurable import Configurable
29 from IPython.config.configurable import Configurable
30 from IPython.config import Config
30 from IPython.config import Config
31 from IPython.nbformat import current as nbformat
31 from IPython.nbformat import current as nbformat
32 from IPython.utils.traitlets import MetaHasTraits, Unicode
32 from IPython.utils.traitlets import MetaHasTraits, Unicode
33 from IPython.utils.text import indent
33 from IPython.utils.text import indent
34
34
35 from IPython.nbconvert import filters
35 from IPython.nbconvert import filters
36 from IPython.nbconvert import transformers
36 from IPython.nbconvert import transformers
37
37
38 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
39 # Globals and constants
39 # Globals and constants
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41
41
42 #Jinja2 extensions to load.
42 #Jinja2 extensions to load.
43 JINJA_EXTENSIONS = ['jinja2.ext.loopcontrols']
43 JINJA_EXTENSIONS = ['jinja2.ext.loopcontrols']
44
44
45 default_filters = {
45 default_filters = {
46 'indent': indent,
46 'indent': indent,
47 'markdown': filters.markdown2html,
47 'markdown': filters.markdown2html,
48 'ansi2html': filters.ansi2html,
48 'ansi2html': filters.ansi2html,
49 'filter_data_type': filters.DataTypeFilter,
49 'filter_data_type': filters.DataTypeFilter,
50 'get_lines': filters.get_lines,
50 'get_lines': filters.get_lines,
51 'highlight': filters.highlight,
51 'highlight': filters.highlight,
52 'highlight2html': filters.highlight,
52 'highlight2html': filters.highlight,
53 'highlight2latex': filters.highlight2latex,
53 'highlight2latex': filters.highlight2latex,
54 'markdown2latex': filters.markdown2latex,
54 'markdown2latex': filters.markdown2latex,
55 'markdown2rst': filters.markdown2rst,
55 'markdown2rst': filters.markdown2rst,
56 'pycomment': filters.python_comment,
56 'pycomment': filters.python_comment,
57 'rm_ansi': filters.remove_ansi,
57 'rm_ansi': filters.remove_ansi,
58 'rm_dollars': filters.strip_dollars,
58 'rm_dollars': filters.strip_dollars,
59 'rm_fake': filters.rm_fake,
59 'rm_fake': filters.rm_fake,
60 'html_text' : filters.html_text,
61 'add_anchor': filters.add_anchor,
60 'ansi2latex': filters.ansi2latex,
62 'ansi2latex': filters.ansi2latex,
61 'rm_math_space': filters.rm_math_space,
63 'rm_math_space': filters.rm_math_space,
62 'wrap': filters.wrap
64 'wrap': filters.wrap
63 }
65 }
64
66
65 #-----------------------------------------------------------------------------
67 #-----------------------------------------------------------------------------
66 # Class
68 # Class
67 #-----------------------------------------------------------------------------
69 #-----------------------------------------------------------------------------
68
70
69 class Exporter(Configurable):
71 class Exporter(Configurable):
70 """
72 """
71 Exports notebooks into other file formats. Uses Jinja 2 templating engine
73 Exports notebooks into other file formats. Uses Jinja 2 templating engine
72 to output new formats. Inherit from this class if you are creating a new
74 to output new formats. Inherit from this class if you are creating a new
73 template type along with new filters/transformers. If the filters/
75 template type along with new filters/transformers. If the filters/
74 transformers provided by default suffice, there is no need to inherit from
76 transformers provided by default suffice, there is no need to inherit from
75 this class. Instead, override the template_file and file_extension
77 this class. Instead, override the template_file and file_extension
76 traits via a config file.
78 traits via a config file.
77
79
78 {filters}
80 {filters}
79 """
81 """
80
82
81 # finish the docstring
83 # finish the docstring
82 __doc__ = __doc__.format(filters = '- '+'\n - '.join(default_filters.keys()))
84 __doc__ = __doc__.format(filters = '- '+'\n - '.join(default_filters.keys()))
83
85
84
86
85 template_file = Unicode(
87 template_file = Unicode(
86 '', config=True,
88 '', config=True,
87 help="Name of the template file to use")
89 help="Name of the template file to use")
88
90
89 file_extension = Unicode(
91 file_extension = Unicode(
90 'txt', config=True,
92 'txt', config=True,
91 help="Extension of the file that should be written to disk"
93 help="Extension of the file that should be written to disk"
92 )
94 )
93
95
94 template_path = Unicode(
96 template_path = Unicode(
95 os.path.join("..", "templates"), config=True,
97 os.path.join("..", "templates"), config=True,
96 help="Path where the template files are located.")
98 help="Path where the template files are located.")
97
99
98 template_skeleton_path = Unicode(
100 template_skeleton_path = Unicode(
99 os.path.join("..", "templates", "skeleton"), config=True,
101 os.path.join("..", "templates", "skeleton"), config=True,
100 help="Path where the template skeleton files are located.")
102 help="Path where the template skeleton files are located.")
101
103
102 #Jinja block definitions
104 #Jinja block definitions
103 jinja_comment_block_start = Unicode("", config=True)
105 jinja_comment_block_start = Unicode("", config=True)
104 jinja_comment_block_end = Unicode("", config=True)
106 jinja_comment_block_end = Unicode("", config=True)
105 jinja_variable_block_start = Unicode("", config=True)
107 jinja_variable_block_start = Unicode("", config=True)
106 jinja_variable_block_end = Unicode("", config=True)
108 jinja_variable_block_end = Unicode("", config=True)
107 jinja_logic_block_start = Unicode("", config=True)
109 jinja_logic_block_start = Unicode("", config=True)
108 jinja_logic_block_end = Unicode("", config=True)
110 jinja_logic_block_end = Unicode("", config=True)
109
111
110 #Extension that the template files use.
112 #Extension that the template files use.
111 template_extension = Unicode(".tpl", config=True)
113 template_extension = Unicode(".tpl", config=True)
112
114
113 #Processors that process the input data prior to the export, set in the
115 #Processors that process the input data prior to the export, set in the
114 #constructor for this class.
116 #constructor for this class.
115 transformers = None
117 transformers = None
116
118
117
119
118 def __init__(self, transformers=None, filters=None, config=None, extra_loaders=None, **kw):
120 def __init__(self, transformers=None, filters=None, config=None, extra_loaders=None, **kw):
119 """
121 """
120 Public constructor
122 Public constructor
121
123
122 Parameters
124 Parameters
123 ----------
125 ----------
124 transformers : list[of transformer]
126 transformers : list[of transformer]
125 Custom transformers to apply to the notebook prior to engaging
127 Custom transformers to apply to the notebook prior to engaging
126 the Jinja template engine. Any transformers specified here
128 the Jinja template engine. Any transformers specified here
127 will override existing transformers if a naming conflict
129 will override existing transformers if a naming conflict
128 occurs.
130 occurs.
129 filters : dict[of filter]
131 filters : dict[of filter]
130 filters specified here will override existing filters if a naming
132 filters specified here will override existing filters if a naming
131 conflict occurs. Filters are availlable in jinja template through
133 conflict occurs. Filters are availlable in jinja template through
132 the name of the corresponding key. Cf class docstring for
134 the name of the corresponding key. Cf class docstring for
133 availlable default filters.
135 availlable default filters.
134 config : config
136 config : config
135 User configuration instance.
137 User configuration instance.
136 extra_loaders : list[of Jinja Loaders]
138 extra_loaders : list[of Jinja Loaders]
137 ordered list of Jinja loder to find templates. Will be tried in order
139 ordered list of Jinja loder to find templates. Will be tried in order
138 before the default FileSysteme ones.
140 before the default FileSysteme ones.
139 """
141 """
140
142
141 #Call the base class constructor
143 #Call the base class constructor
142 c = self.default_config
144 c = self.default_config
143 if config:
145 if config:
144 c.merge(config)
146 c.merge(config)
145
147
146 super(Exporter, self).__init__(config=c, **kw)
148 super(Exporter, self).__init__(config=c, **kw)
147
149
148 #Standard environment
150 #Standard environment
149 self._init_environment(extra_loaders=extra_loaders)
151 self._init_environment(extra_loaders=extra_loaders)
150
152
151 #Add transformers
153 #Add transformers
152 self._register_transformers()
154 self._register_transformers()
153
155
154 #Add filters to the Jinja2 environment
156 #Add filters to the Jinja2 environment
155 self._register_filters()
157 self._register_filters()
156
158
157 #Load user transformers. Overwrite existing transformers if need be.
159 #Load user transformers. Overwrite existing transformers if need be.
158 if transformers :
160 if transformers :
159 for transformer in transformers:
161 for transformer in transformers:
160 self.register_transformer(transformer)
162 self.register_transformer(transformer)
161
163
162 #Load user filters. Overwrite existing filters if need be.
164 #Load user filters. Overwrite existing filters if need be.
163 if not filters is None:
165 if not filters is None:
164 for key, user_filter in filters.iteritems():
166 for key, user_filter in filters.iteritems():
165 self.register_filter(key, user_filter)
167 self.register_filter(key, user_filter)
166
168
167 @property
169 @property
168 def default_config(self):
170 def default_config(self):
169 return Config()
171 return Config()
170
172
171
173
172
174
173 def from_notebook_node(self, nb, resources=None):
175 def from_notebook_node(self, nb, resources=None):
174 """
176 """
175 Convert a notebook from a notebook node instance.
177 Convert a notebook from a notebook node instance.
176
178
177 Parameters
179 Parameters
178 ----------
180 ----------
179 nb : Notebook node
181 nb : Notebook node
180 resources : a dict of additional resources that
182 resources : a dict of additional resources that
181 can be accessed read/write by transformers
183 can be accessed read/write by transformers
182 and filters.
184 and filters.
183 """
185 """
184 if resources is None:
186 if resources is None:
185 resources = {}
187 resources = {}
186 nb, resources = self._preprocess(nb, resources)
188 nb, resources = self._preprocess(nb, resources)
187
189
188 #Load the template file.
190 #Load the template file.
189 self.template = self.environment.get_template(self.template_file+self.template_extension)
191 self.template = self.environment.get_template(self.template_file+self.template_extension)
190
192
191 return self.template.render(nb=nb, resources=resources), resources
193 return self.template.render(nb=nb, resources=resources), resources
192
194
193
195
194 def from_filename(self, filename):
196 def from_filename(self, filename):
195 """
197 """
196 Convert a notebook from a notebook file.
198 Convert a notebook from a notebook file.
197
199
198 Parameters
200 Parameters
199 ----------
201 ----------
200 filename : str
202 filename : str
201 Full filename of the notebook file to open and convert.
203 Full filename of the notebook file to open and convert.
202 """
204 """
203
205
204 with io.open(filename) as f:
206 with io.open(filename) as f:
205 return self.from_notebook_node(nbformat.read(f, 'json'))
207 return self.from_notebook_node(nbformat.read(f, 'json'))
206
208
207
209
208 def from_file(self, file_stream):
210 def from_file(self, file_stream):
209 """
211 """
210 Convert a notebook from a notebook file.
212 Convert a notebook from a notebook file.
211
213
212 Parameters
214 Parameters
213 ----------
215 ----------
214 file_stream : file-like object
216 file_stream : file-like object
215 Notebook file-like object to convert.
217 Notebook file-like object to convert.
216 """
218 """
217 return self.from_notebook_node(nbformat.read(file_stream, 'json'))
219 return self.from_notebook_node(nbformat.read(file_stream, 'json'))
218
220
219
221
220 def register_transformer(self, transformer):
222 def register_transformer(self, transformer):
221 """
223 """
222 Register a transformer.
224 Register a transformer.
223 Transformers are classes that act upon the notebook before it is
225 Transformers are classes that act upon the notebook before it is
224 passed into the Jinja templating engine. Transformers are also
226 passed into the Jinja templating engine. Transformers are also
225 capable of passing additional information to the Jinja
227 capable of passing additional information to the Jinja
226 templating engine.
228 templating engine.
227
229
228 Parameters
230 Parameters
229 ----------
231 ----------
230 transformer : transformer
232 transformer : transformer
231 """
233 """
232 if self.transformers is None:
234 if self.transformers is None:
233 self.transformers = []
235 self.transformers = []
234
236
235 if inspect.isfunction(transformer):
237 if inspect.isfunction(transformer):
236 self.transformers.append(transformer)
238 self.transformers.append(transformer)
237 return transformer
239 return transformer
238 elif isinstance(transformer, MetaHasTraits):
240 elif isinstance(transformer, MetaHasTraits):
239 transformer_instance = transformer(config=self.config)
241 transformer_instance = transformer(config=self.config)
240 self.transformers.append(transformer_instance)
242 self.transformers.append(transformer_instance)
241 return transformer_instance
243 return transformer_instance
242 else:
244 else:
243 transformer_instance = transformer()
245 transformer_instance = transformer()
244 self.transformers.append(transformer_instance)
246 self.transformers.append(transformer_instance)
245 return transformer_instance
247 return transformer_instance
246
248
247
249
248 def register_filter(self, name, filter):
250 def register_filter(self, name, filter):
249 """
251 """
250 Register a filter.
252 Register a filter.
251 A filter is a function that accepts and acts on one string.
253 A filter is a function that accepts and acts on one string.
252 The filters are accesible within the Jinja templating engine.
254 The filters are accesible within the Jinja templating engine.
253
255
254 Parameters
256 Parameters
255 ----------
257 ----------
256 name : str
258 name : str
257 name to give the filter in the Jinja engine
259 name to give the filter in the Jinja engine
258 filter : filter
260 filter : filter
259 """
261 """
260 if inspect.isfunction(filter):
262 if inspect.isfunction(filter):
261 self.environment.filters[name] = filter
263 self.environment.filters[name] = filter
262 elif isinstance(filter, MetaHasTraits):
264 elif isinstance(filter, MetaHasTraits):
263 self.environment.filters[name] = filter(config=self.config)
265 self.environment.filters[name] = filter(config=self.config)
264 else:
266 else:
265 self.environment.filters[name] = filter()
267 self.environment.filters[name] = filter()
266 return self.environment.filters[name]
268 return self.environment.filters[name]
267
269
268
270
269 def _register_transformers(self):
271 def _register_transformers(self):
270 """
272 """
271 Register all of the transformers needed for this exporter.
273 Register all of the transformers needed for this exporter.
272 """
274 """
273
275
274 self.register_transformer(transformers.coalesce_streams)
276 self.register_transformer(transformers.coalesce_streams)
275
277
276 #Remember the figure extraction transformer so it can be enabled and
278 #Remember the figure extraction transformer so it can be enabled and
277 #disabled easily later.
279 #disabled easily later.
278 self.extract_figure_transformer = self.register_transformer(transformers.ExtractFigureTransformer)
280 self.extract_figure_transformer = self.register_transformer(transformers.ExtractFigureTransformer)
279
281
280
282
281 def _register_filters(self):
283 def _register_filters(self):
282 """
284 """
283 Register all of the filters required for the exporter.
285 Register all of the filters required for the exporter.
284 """
286 """
285 for k, v in default_filters.iteritems():
287 for k, v in default_filters.iteritems():
286 self.register_filter(k, v)
288 self.register_filter(k, v)
287
289
288
290
289 def _init_environment(self, extra_loaders=None):
291 def _init_environment(self, extra_loaders=None):
290 """
292 """
291 Create the Jinja templating environment.
293 Create the Jinja templating environment.
292 """
294 """
293 here = os.path.dirname(os.path.realpath(__file__))
295 here = os.path.dirname(os.path.realpath(__file__))
294 loaders = []
296 loaders = []
295 if extra_loaders:
297 if extra_loaders:
296 loaders.extend(extra_loaders)
298 loaders.extend(extra_loaders)
297
299
298 loaders.append(FileSystemLoader([
300 loaders.append(FileSystemLoader([
299 os.path.join(here, self.template_path),
301 os.path.join(here, self.template_path),
300 os.path.join(here, self.template_skeleton_path),
302 os.path.join(here, self.template_skeleton_path),
301 ]))
303 ]))
302
304
303 self.environment = Environment(
305 self.environment = Environment(
304 loader= ChoiceLoader(loaders),
306 loader= ChoiceLoader(loaders),
305 extensions=JINJA_EXTENSIONS
307 extensions=JINJA_EXTENSIONS
306 )
308 )
307
309
308 #Set special Jinja2 syntax that will not conflict with latex.
310 #Set special Jinja2 syntax that will not conflict with latex.
309 if self.jinja_logic_block_start:
311 if self.jinja_logic_block_start:
310 self.environment.block_start_string = self.jinja_logic_block_start
312 self.environment.block_start_string = self.jinja_logic_block_start
311 if self.jinja_logic_block_end:
313 if self.jinja_logic_block_end:
312 self.environment.block_end_string = self.jinja_logic_block_end
314 self.environment.block_end_string = self.jinja_logic_block_end
313 if self.jinja_variable_block_start:
315 if self.jinja_variable_block_start:
314 self.environment.variable_start_string = self.jinja_variable_block_start
316 self.environment.variable_start_string = self.jinja_variable_block_start
315 if self.jinja_variable_block_end:
317 if self.jinja_variable_block_end:
316 self.environment.variable_end_string = self.jinja_variable_block_end
318 self.environment.variable_end_string = self.jinja_variable_block_end
317 if self.jinja_comment_block_start:
319 if self.jinja_comment_block_start:
318 self.environment.comment_start_string = self.jinja_comment_block_start
320 self.environment.comment_start_string = self.jinja_comment_block_start
319 if self.jinja_comment_block_end:
321 if self.jinja_comment_block_end:
320 self.environment.comment_end_string = self.jinja_comment_block_end
322 self.environment.comment_end_string = self.jinja_comment_block_end
321
323
322
324
323 def _preprocess(self, nb, resources):
325 def _preprocess(self, nb, resources):
324 """
326 """
325 Preprocess the notebook before passing it into the Jinja engine.
327 Preprocess the notebook before passing it into the Jinja engine.
326 To preprocess the notebook is to apply all of the
328 To preprocess the notebook is to apply all of the
327
329
328 Parameters
330 Parameters
329 ----------
331 ----------
330 nb : notebook node
332 nb : notebook node
331 notebook that is being exported.
333 notebook that is being exported.
332 resources : a dict of additional resources that
334 resources : a dict of additional resources that
333 can be accessed read/write by transformers
335 can be accessed read/write by transformers
334 and filters.
336 and filters.
335 """
337 """
336
338
337 # Do a deepcopy first,
339 # Do a deepcopy first,
338 # we are never safe enough with what the transformers could do.
340 # we are never safe enough with what the transformers could do.
339 nbc = deepcopy(nb)
341 nbc = deepcopy(nb)
340 resc = deepcopy(resources)
342 resc = deepcopy(resources)
341 #Run each transformer on the notebook. Carry the output along
343 #Run each transformer on the notebook. Carry the output along
342 #to each transformer
344 #to each transformer
343 for transformer in self.transformers:
345 for transformer in self.transformers:
344 nb, resources = transformer(nbc, resc)
346 nb, resources = transformer(nbc, resc)
345 return nb, resources
347 return nb, resources
346
348
@@ -1,123 +1,151
1 # coding: utf-8
1 """String filters.
2 """String filters.
2
3
3 Contains a collection of useful string manipulation filters for use in Jinja
4 Contains a collection of useful string manipulation filters for use in Jinja
4 templates.
5 templates.
5 """
6 """
6 #-----------------------------------------------------------------------------
7 #-----------------------------------------------------------------------------
7 # Copyright (c) 2013, the IPython Development Team.
8 # Copyright (c) 2013, the IPython Development Team.
8 #
9 #
9 # Distributed under the terms of the Modified BSD License.
10 # Distributed under the terms of the Modified BSD License.
10 #
11 #
11 # The full license is in the file COPYING.txt, distributed with this software.
12 # The full license is in the file COPYING.txt, distributed with this software.
12 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
13
14
14 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
15 # Imports
16 # Imports
16 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
17
18
18 import re
19 import re
19 import textwrap
20 import textwrap
21 from xml.etree import ElementTree
22
23 from IPython.utils import py3compat
20
24
21 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
22 # Functions
26 # Functions
23 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
24
28
25 __all__ = [
29 __all__ = [
26 'wrap',
30 'wrap',
31 'html_text',
32 'add_anchor',
27 'strip_dollars',
33 'strip_dollars',
28 'rm_fake',
34 'rm_fake',
29 'python_comment',
35 'python_comment',
30 'get_lines'
36 'get_lines'
31 ]
37 ]
32
38
33
39
34 def wrap(text, width=100):
40 def wrap(text, width=100):
35 """
41 """
36 Intelligently wrap text.
42 Intelligently wrap text.
37 Wrap text without breaking words if possible.
43 Wrap text without breaking words if possible.
38
44
39 Parameters
45 Parameters
40 ----------
46 ----------
41 text : str
47 text : str
42 Text to wrap.
48 Text to wrap.
43 width : int, optional
49 width : int, optional
44 Number of characters to wrap to, default 100.
50 Number of characters to wrap to, default 100.
45 """
51 """
46
52
47 split_text = text.split('\n')
53 split_text = text.split('\n')
48 wrp = map(lambda x:textwrap.wrap(x,width), split_text)
54 wrp = map(lambda x:textwrap.wrap(x,width), split_text)
49 wrpd = map('\n'.join, wrp)
55 wrpd = map('\n'.join, wrp)
50 return '\n'.join(wrpd)
56 return '\n'.join(wrpd)
51
57
52 def single_line(text):
58
53 """Wrap multi-line text into a single line
59 def html_text(element):
60 """extract inner text from html
61
62 Analog of jQuery's $(element).text()
63 """
64 if not isinstance(element, (ElementTree.ElementTree, ElementTree.Element)):
65 element = ElementTree.fromstring(element)
66
67 text = element.text or ""
68 for child in element:
69 text += html_text(child)
70 text += (element.tail or "")
71 return text
72
73
74 def add_anchor(html):
75 """Add an anchor-link to an html header tag
54
76
55 Used in markdown heading cells, which are not allowed to be multiline.
77 For use in heading cells
56 """
78 """
57 return ''.join(text.splitlines())
79 h = ElementTree.fromstring(py3compat.cast_bytes_py2(html))
80 link = html_text(h).replace(' ', '-')
81 h.set('id', link)
82 a = ElementTree.Element("a", {"class" : "anchor-link", "href" : "#" + link})
83 a.text = u'¶'
84 h.append(a)
85 return ElementTree.tostring(h)
58
86
59
87
60 def strip_dollars(text):
88 def strip_dollars(text):
61 """
89 """
62 Remove all dollar symbols from text
90 Remove all dollar symbols from text
63
91
64 Parameters
92 Parameters
65 ----------
93 ----------
66 text : str
94 text : str
67 Text to remove dollars from
95 Text to remove dollars from
68 """
96 """
69
97
70 return text.strip('$')
98 return text.strip('$')
71
99
72
100
73 files_url_pattern = re.compile(r'(src|href)\=([\'"]?)files/')
101 files_url_pattern = re.compile(r'(src|href)\=([\'"]?)files/')
74
102
75 def rm_fake(text):
103 def rm_fake(text):
76 """
104 """
77 Fix all fake URLs that start with `files/`,
105 Fix all fake URLs that start with `files/`,
78 stripping out the `files/` prefix.
106 stripping out the `files/` prefix.
79
107
80 Parameters
108 Parameters
81 ----------
109 ----------
82 text : str
110 text : str
83 Text in which to replace 'src="files/real...' with 'src="real...'
111 Text in which to replace 'src="files/real...' with 'src="real...'
84 """
112 """
85 return files_url_pattern.sub(r"\1=\2", text)
113 return files_url_pattern.sub(r"\1=\2", text)
86
114
87
115
88 def python_comment(text):
116 def python_comment(text):
89 """
117 """
90 Build a Python comment line from input text.
118 Build a Python comment line from input text.
91
119
92 Parameters
120 Parameters
93 ----------
121 ----------
94 text : str
122 text : str
95 Text to comment out.
123 Text to comment out.
96 """
124 """
97
125
98 #Replace line breaks with line breaks and comment symbols.
126 #Replace line breaks with line breaks and comment symbols.
99 #Also add a comment symbol at the beginning to comment out
127 #Also add a comment symbol at the beginning to comment out
100 #the first line.
128 #the first line.
101 return '# '+'\n# '.join(text.split('\n'))
129 return '# '+'\n# '.join(text.split('\n'))
102
130
103
131
104 def get_lines(text, start=None,end=None):
132 def get_lines(text, start=None,end=None):
105 """
133 """
106 Split the input text into separate lines and then return the
134 Split the input text into separate lines and then return the
107 lines that the caller is interested in.
135 lines that the caller is interested in.
108
136
109 Parameters
137 Parameters
110 ----------
138 ----------
111 text : str
139 text : str
112 Text to parse lines from.
140 Text to parse lines from.
113 start : int, optional
141 start : int, optional
114 First line to grab from.
142 First line to grab from.
115 end : int, optional
143 end : int, optional
116 Last line to grab from.
144 Last line to grab from.
117 """
145 """
118
146
119 # Split the input into lines.
147 # Split the input into lines.
120 lines = text.split("\n")
148 lines = text.split("\n")
121
149
122 # Return the right lines.
150 # Return the right lines.
123 return "\n".join(lines[start:end]) #re-join
151 return "\n".join(lines[start:end]) #re-join
General Comments 0
You need to be logged in to leave comments. Login now