3 pygments.formatters.html |
3 pygments.formatters.html |
4 ~~~~~~~~~~~~~~~~~~~~~~~~ |
4 ~~~~~~~~~~~~~~~~~~~~~~~~ |
5 |
5 |
6 Formatter for HTML output. |
6 Formatter for HTML output. |
7 |
7 |
8 :copyright: Copyright 2006-2013 by the Pygments team, see AUTHORS. |
8 :copyright: Copyright 2006-2014 by the Pygments team, see AUTHORS. |
9 :license: BSD, see LICENSE for details. |
9 :license: BSD, see LICENSE for details. |
10 """ |
10 """ |
11 |
11 |
12 try: |
12 from __future__ import print_function |
13 basestring # __IGNORE_WARNING__ |
|
14 except NameError: |
|
15 basestring = str |
|
16 |
13 |
17 import os |
14 import os |
18 import sys |
15 import sys |
19 import os.path |
16 import os.path |
20 import io |
|
21 |
17 |
22 from pygments.formatter import Formatter |
18 from pygments.formatter import Formatter |
23 from pygments.token import Token, Text, STANDARD_TYPES |
19 from pygments.token import Token, Text, STANDARD_TYPES |
24 from pygments.util import get_bool_opt, get_int_opt, get_list_opt, bytes |
20 from pygments.util import get_bool_opt, get_int_opt, get_list_opt, \ |
|
21 StringIO, string_types, iteritems |
25 |
22 |
26 try: |
23 try: |
27 import ctags |
24 import ctags |
28 except ImportError: |
25 except ImportError: |
29 ctags = None |
26 ctags = None |
30 |
27 |
31 __all__ = ['HtmlFormatter'] |
28 __all__ = ['HtmlFormatter'] |
32 |
29 |
33 |
30 |
34 _escape_html_table = { |
31 _escape_html_table = { |
35 ord('&'): '&', |
32 ord('&'): u'&', |
36 ord('<'): '<', |
33 ord('<'): u'<', |
37 ord('>'): '>', |
34 ord('>'): u'>', |
38 ord('"'): '"', |
35 ord('"'): u'"', |
39 ord("'"): ''', |
36 ord("'"): u''', |
40 } |
37 } |
41 |
38 |
42 def escape_html(text, table=_escape_html_table): |
39 def escape_html(text, table=_escape_html_table): |
43 """Escape &, <, > as well as single and double quotes for HTML.""" |
40 """Escape &, <, > as well as single and double quotes for HTML.""" |
44 return text.translate(table) |
41 return text.translate(table) |
221 `cssclass` |
218 `cssclass` |
222 CSS class for the wrapping ``<div>`` tag (default: ``'highlight'``). |
219 CSS class for the wrapping ``<div>`` tag (default: ``'highlight'``). |
223 If you set this option, the default selector for `get_style_defs()` |
220 If you set this option, the default selector for `get_style_defs()` |
224 will be this class. |
221 will be this class. |
225 |
222 |
226 *New in Pygments 0.9:* If you select the ``'table'`` line numbers, the |
223 .. versionadded:: 0.9 |
227 wrapping table will have a CSS class of this string plus ``'table'``, |
224 If you select the ``'table'`` line numbers, the wrapping table will |
228 the default is accordingly ``'highlighttable'``. |
225 have a CSS class of this string plus ``'table'``, the default is |
|
226 accordingly ``'highlighttable'``. |
229 |
227 |
230 `cssstyles` |
228 `cssstyles` |
231 Inline CSS styles for the wrapping ``<div>`` tag (default: ``''``). |
229 Inline CSS styles for the wrapping ``<div>`` tag (default: ``''``). |
232 |
230 |
233 `prestyles` |
231 `prestyles` |
234 Inline CSS styles for the ``<pre>`` tag (default: ``''``). *New in |
232 Inline CSS styles for the ``<pre>`` tag (default: ``''``). |
235 Pygments 0.11.* |
233 |
|
234 .. versionadded:: 0.11 |
236 |
235 |
237 `cssfile` |
236 `cssfile` |
238 If the `full` option is true and this option is given, it must be the |
237 If the `full` option is true and this option is given, it must be the |
239 name of an external file. If the filename does not include an absolute |
238 name of an external file. If the filename does not include an absolute |
240 path, the file's path will be assumed to be relative to the main output |
239 path, the file's path will be assumed to be relative to the main output |
241 file's path, if the latter can be found. The stylesheet is then written |
240 file's path, if the latter can be found. The stylesheet is then written |
242 to this file instead of the HTML file. *New in Pygments 0.6.* |
241 to this file instead of the HTML file. |
|
242 |
|
243 .. versionadded:: 0.6 |
243 |
244 |
244 `noclobber_cssfile` |
245 `noclobber_cssfile` |
245 If `cssfile` is given and the specified file exists, the css file will |
246 If `cssfile` is given and the specified file exists, the css file will |
246 not be overwritten. This allows the use of the `full` option in |
247 not be overwritten. This allows the use of the `full` option in |
247 combination with a user specified css file. Default is ``False``. |
248 combination with a user specified css file. Default is ``False``. |
248 *New in Pygments 1.1.* |
249 |
|
250 .. versionadded:: 1.1 |
249 |
251 |
250 `linenos` |
252 `linenos` |
251 If set to ``'table'``, output line numbers as a table with two cells, |
253 If set to ``'table'``, output line numbers as a table with two cells, |
252 one containing the line numbers, the other the whole code. This is |
254 one containing the line numbers, the other the whole code. This is |
253 copy-and-paste-friendly, but may cause alignment problems with some |
255 copy-and-paste-friendly, but may cause alignment problems with some |
282 |
286 |
283 `nobackground` |
287 `nobackground` |
284 If set to ``True``, the formatter won't output the background color |
288 If set to ``True``, the formatter won't output the background color |
285 for the wrapping element (this automatically defaults to ``False`` |
289 for the wrapping element (this automatically defaults to ``False`` |
286 when there is no wrapping element [eg: no argument for the |
290 when there is no wrapping element [eg: no argument for the |
287 `get_syntax_defs` method given]) (default: ``False``). *New in |
291 `get_syntax_defs` method given]) (default: ``False``). |
288 Pygments 0.6.* |
292 |
|
293 .. versionadded:: 0.6 |
289 |
294 |
290 `lineseparator` |
295 `lineseparator` |
291 This string is output between lines of code. It defaults to ``"\n"``, |
296 This string is output between lines of code. It defaults to ``"\n"``, |
292 which is enough to break a line inside ``<pre>`` tags, but you can |
297 which is enough to break a line inside ``<pre>`` tags, but you can |
293 e.g. set it to ``"<br>"`` to get HTML line breaks. *New in Pygments |
298 e.g. set it to ``"<br>"`` to get HTML line breaks. |
294 0.7.* |
299 |
|
300 .. versionadded:: 0.7 |
295 |
301 |
296 `lineanchors` |
302 `lineanchors` |
297 If set to a nonempty string, e.g. ``foo``, the formatter will wrap each |
303 If set to a nonempty string, e.g. ``foo``, the formatter will wrap each |
298 output line in an anchor tag with a ``name`` of ``foo-linenumber``. |
304 output line in an anchor tag with a ``name`` of ``foo-linenumber``. |
299 This allows easy linking to certain lines. *New in Pygments 0.9.* |
305 This allows easy linking to certain lines. |
|
306 |
|
307 .. versionadded:: 0.9 |
300 |
308 |
301 `linespans` |
309 `linespans` |
302 If set to a nonempty string, e.g. ``foo``, the formatter will wrap each |
310 If set to a nonempty string, e.g. ``foo``, the formatter will wrap each |
303 output line in a span tag with an ``id`` of ``foo-linenumber``. |
311 output line in a span tag with an ``id`` of ``foo-linenumber``. |
304 This allows easy access to lines via javascript. *New in Pygments 1.6.* |
312 This allows easy access to lines via javascript. |
|
313 |
|
314 .. versionadded:: 1.6 |
305 |
315 |
306 `anchorlinenos` |
316 `anchorlinenos` |
307 If set to `True`, will wrap line numbers in <a> tags. Used in |
317 If set to `True`, will wrap line numbers in <a> tags. Used in |
308 combination with `linenos` and `lineanchors`. |
318 combination with `linenos` and `lineanchors`. |
309 |
319 |
310 `tagsfile` |
320 `tagsfile` |
311 If set to the path of a ctags file, wrap names in anchor tags that |
321 If set to the path of a ctags file, wrap names in anchor tags that |
312 link to their definitions. `lineanchors` should be used, and the |
322 link to their definitions. `lineanchors` should be used, and the |
313 tags file should specify line numbers (see the `-n` option to ctags). |
323 tags file should specify line numbers (see the `-n` option to ctags). |
314 *New in Pygments 1.6.* |
324 |
|
325 .. versionadded:: 1.6 |
315 |
326 |
316 `tagurlformat` |
327 `tagurlformat` |
317 A string formatting pattern used to generate links to ctags definitions. |
328 A string formatting pattern used to generate links to ctags definitions. |
318 Available variables are `%(path)s`, `%(fname)s` and `%(fext)s`. |
329 Available variables are `%(path)s`, `%(fname)s` and `%(fext)s`. |
319 Defaults to an empty string, resulting in just `#prefix-number` links. |
330 Defaults to an empty string, resulting in just `#prefix-number` links. |
320 *New in Pygments 1.6.* |
331 |
|
332 .. versionadded:: 1.6 |
321 |
333 |
322 |
334 |
323 **Subclassing the HTML formatter** |
335 **Subclassing the HTML formatter** |
324 |
336 |
325 *New in Pygments 0.7.* |
337 .. versionadded:: 0.7 |
326 |
338 |
327 The HTML formatter is now built in a way that allows easy subclassing, thus |
339 The HTML formatter is now built in a way that allows easy subclassing, thus |
328 customizing the output HTML code. The `format()` method calls |
340 customizing the output HTML code. The `format()` method calls |
329 `self._format_lines()` which returns a generator that yields tuples of ``(1, |
341 `self._format_lines()` which returns a generator that yields tuples of ``(1, |
330 line)``, where the ``1`` indicates that the ``line`` is a line of the |
342 line)``, where the ``1`` indicates that the ``line`` is a line of the |
470 for arg in args: |
482 for arg in args: |
471 tmp.append((arg and arg + ' ' or '') + cls) |
483 tmp.append((arg and arg + ' ' or '') + cls) |
472 return ', '.join(tmp) |
484 return ', '.join(tmp) |
473 |
485 |
474 styles = [(level, ttype, cls, style) |
486 styles = [(level, ttype, cls, style) |
475 for cls, (style, ttype, level) in self.class2style.items() |
487 for cls, (style, ttype, level) in iteritems(self.class2style) |
476 if cls and style] |
488 if cls and style] |
477 styles.sort() |
489 styles.sort() |
478 lines = ['%s { %s } /* %s */' % (prefix(cls), style, repr(ttype)[6:]) |
490 lines = ['%s { %s } /* %s */' % (prefix(cls), style, repr(ttype)[6:]) |
479 for (level, ttype, cls, style) in styles] |
491 for (level, ttype, cls, style) in styles] |
480 if arg and not self.nobackground and \ |
492 if arg and not self.nobackground and \ |
508 # pseudo files, e.g. name == '<fdopen>' |
520 # pseudo files, e.g. name == '<fdopen>' |
509 raise AttributeError |
521 raise AttributeError |
510 cssfilename = os.path.join(os.path.dirname(filename), |
522 cssfilename = os.path.join(os.path.dirname(filename), |
511 self.cssfile) |
523 self.cssfile) |
512 except AttributeError: |
524 except AttributeError: |
513 sys.stderr.write('Note: Cannot determine output file name, ' \ |
525 print('Note: Cannot determine output file name, ' \ |
514 'using current directory as base for the CSS file name') |
526 'using current directory as base for the CSS file name', |
|
527 file=sys.stderr) |
515 cssfilename = self.cssfile |
528 cssfilename = self.cssfile |
516 # write CSS file only if noclobber_cssfile isn't given as an option. |
529 # write CSS file only if noclobber_cssfile isn't given as an option. |
517 try: |
530 try: |
518 if not os.path.exists(cssfilename) or not self.noclobber_cssfile: |
531 if not os.path.exists(cssfilename) or not self.noclobber_cssfile: |
519 cf = open(cssfilename, "w") |
532 cf = open(cssfilename, "w") |
613 for t, line in lines: |
626 for t, line in lines: |
614 if num%sp == 0: |
627 if num%sp == 0: |
615 style = 'background-color: #ffffc0; padding: 0 5px 0 5px' |
628 style = 'background-color: #ffffc0; padding: 0 5px 0 5px' |
616 else: |
629 else: |
617 style = 'background-color: #f0f0f0; padding: 0 5px 0 5px' |
630 style = 'background-color: #f0f0f0; padding: 0 5px 0 5px' |
618 yield 1, '<span style="%s">%*s</span> ' % ( |
631 yield 1, '<span style="%s">%*s </span>' % ( |
619 style, mw, (num%st and ' ' or num)) + line |
632 style, mw, (num%st and ' ' or num)) + line |
620 num += 1 |
633 num += 1 |
621 else: |
634 else: |
622 for t, line in lines: |
635 for t, line in lines: |
623 yield 1, ('<span style="background-color: #f0f0f0; ' |
636 yield 1, ('<span style="background-color: #f0f0f0; ' |
624 'padding: 0 5px 0 5px">%*s</span> ' % ( |
637 'padding: 0 5px 0 5px">%*s </span>' % ( |
625 mw, (num%st and ' ' or num)) + line) |
638 mw, (num%st and ' ' or num)) + line) |
626 num += 1 |
639 num += 1 |
627 elif sp: |
640 elif sp: |
628 for t, line in lines: |
641 for t, line in lines: |
629 yield 1, '<span class="lineno%s">%*s</span> ' % ( |
642 yield 1, '<span class="lineno%s">%*s </span>' % ( |
630 num%sp == 0 and ' special' or '', mw, |
643 num%sp == 0 and ' special' or '', mw, |
631 (num%st and ' ' or num)) + line |
644 (num%st and ' ' or num)) + line |
632 num += 1 |
645 num += 1 |
633 else: |
646 else: |
634 for t, line in lines: |
647 for t, line in lines: |
635 yield 1, '<span class="lineno">%*s</span> ' % ( |
648 yield 1, '<span class="lineno">%*s </span>' % ( |
636 mw, (num%st and ' ' or num)) + line |
649 mw, (num%st and ' ' or num)) + line |
637 num += 1 |
650 num += 1 |
638 |
651 |
639 def _wrap_lineanchors(self, inner): |
652 def _wrap_lineanchors(self, inner): |
640 s = self.lineanchors |
653 s = self.lineanchors |