ThirdParty/Pygments/pygments/formatters/html.py

changeset 4172
4f20dba37ab6
parent 3079
0233bbe9a9c4
child 4697
c2e9bf425554
equal deleted inserted replaced
4170:8bc578136279 4172:4f20dba37ab6
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('<'): '&lt;', 33 ord('<'): u'&lt;',
37 ord('>'): '&gt;', 34 ord('>'): u'&gt;',
38 ord('"'): '&quot;', 35 ord('"'): u'&quot;',
39 ord("'"): '&#39;', 36 ord("'"): u'&#39;',
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
266 unless you give the enclosing ``<pre>`` tags an explicit ``line-height`` 268 unless you give the enclosing ``<pre>`` tags an explicit ``line-height``
267 CSS property (you get the default line spacing with ``line-height: 269 CSS property (you get the default line spacing with ``line-height:
268 125%``). 270 125%``).
269 271
270 `hl_lines` 272 `hl_lines`
271 Specify a list of lines to be highlighted. *New in Pygments 0.11.* 273 Specify a list of lines to be highlighted.
274
275 .. versionadded:: 0.11
272 276
273 `linenostart` 277 `linenostart`
274 The line number for the first line (default: ``1``). 278 The line number for the first line (default: ``1``).
275 279
276 `linenostep` 280 `linenostep`
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
456 highlighting style. ``arg`` can be a string or list of selectors to 468 highlighting style. ``arg`` can be a string or list of selectors to
457 insert before the token type classes. 469 insert before the token type classes.
458 """ 470 """
459 if arg is None: 471 if arg is None:
460 arg = ('cssclass' in self.options and '.'+self.cssclass or '') 472 arg = ('cssclass' in self.options and '.'+self.cssclass or '')
461 if isinstance(arg, basestring): 473 if isinstance(arg, string_types):
462 args = [arg] 474 args = [arg]
463 else: 475 else:
464 args = list(arg) 476 args = list(arg)
465 477
466 def prefix(cls): 478 def prefix(cls):
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")
537 for t, line in inner: 550 for t, line in inner:
538 yield t, line 551 yield t, line
539 yield 0, DOC_FOOTER 552 yield 0, DOC_FOOTER
540 553
541 def _wrap_tablelinenos(self, inner): 554 def _wrap_tablelinenos(self, inner):
542 dummyoutfile = io.StringIO() 555 dummyoutfile = StringIO()
543 lncount = 0 556 lncount = 0
544 for t, line in inner: 557 for t, line in inner:
545 if t: 558 if t:
546 lncount += 1 559 lncount += 1
547 dummyoutfile.write(line) 560 dummyoutfile.write(line)
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

eric ide

mercurial