2 pygments.formatters.html
3 ~~~~~~~~~~~~~~~~~~~~~~~~
5 Formatter for HTML output.
7 :copyright: Copyright 2006-2023 by the Pygments team, see AUTHORS.
8 :license: BSD, see LICENSE for details.
15from io
import StringIO
26__all__ = [
'HtmlFormatter']
39 """Escape &, <, > as well as single and double quotes for HTML."""
56 aname =
'-' + ttype[-1] + aname
62CSSFILE_TEMPLATE =
'''\
64generated by Pygments <https://pygments.org/>
65Copyright 2006-2023 by the Pygments team.
66Licensed under the BSD license, see LICENSE for details.
72<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
73 "http://www.w3.org/TR/html4/strict.dtd">
75generated by Pygments <https://pygments.org/>
76Copyright 2006-2023 by the Pygments team.
77Licensed under the BSD license, see LICENSE for details.
81 <title>%(title)s</title>
82 <meta http-equiv="content-type" content="text/html; charset=%(encoding)s">
83 <style type="text/css">
84''' + CSSFILE_TEMPLATE +
'''
92DOC_HEADER_EXTERNALCSS =
'''\
93<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
94 "http://www.w3.org/TR/html4/strict.dtd">
98 <title>%(title)s</title>
99 <meta http-equiv="content-type" content="text/html; charset=%(encoding)s">
100 <link rel="stylesheet" href="%(cssfile)s" type="text/css">
115 Format tokens as HTML 4 ``<span>`` tags. By default, the content is enclosed
116 in a ``<pre>`` tag, itself wrapped in a ``<div>`` tag (but see the `nowrap` option).
117 The ``<div>``'s CSS class can be set by the `cssclass` option.
119 If the `linenos` option is set to ``"table"``, the ``<pre>`` is
120 additionally wrapped inside a ``<table>`` which has one row and two
121 cells: one containing the line numbers and one containing the code.
126 <div class="highlight" >
128 <td class="linenos" title="click to toggle"
129 onclick="with (this.firstChild.style)
130 { display = (display == '') ? 'none' : '' }">
135 <pre><span class="Ke">def </span><span class="NaFu">foo</span>(bar):
136 <span class="Ke">pass</span>
141 (whitespace added to improve clarity).
143 A list of lines can be specified using the `hl_lines` option to make these
144 lines highlighted (as of Pygments 0.11).
146 With the `full` option, a complete HTML 4 document is output, including
147 the style definitions inside a ``<style>`` tag, or in a separate file if
148 the `cssfile` option is given.
150 When `tagsfile` is set to the path of a ctags index file, it is used to
151 generate hyperlinks from names to their definition. You must enable
152 `lineanchors` and run ctags with the `-n` option for this to work. The
153 `python-ctags` module from PyPI must be installed to use this feature;
154 otherwise a `RuntimeError` will be raised.
156 The `get_style_defs(arg='')` method of a `HtmlFormatter` returns a string
157 containing CSS rules for the CSS classes used by the formatter. The
158 argument `arg` can be used to specify additional CSS selectors that
159 are prepended to the classes. A call `fmter.get_style_defs('td .code')`
160 would result in the following CSS classes:
164 td .code .kw { font-weight: bold; color: #00FF00 }
165 td .code .cm { color: #999999 }
168 If you have Pygments 0.6 or higher, you can also pass a list or tuple to the
169 `get_style_defs()` method to request multiple prefixes for the tokens:
171 .. sourcecode:: python
173 formatter.get_style_defs(['div.syntax pre', 'pre.syntax'])
175 The output would then look like this:
180 pre.syntax .kw { font-weight: bold; color: #00FF00 }
182 pre.syntax .cm { color: #999999 }
185 Additional options accepted:
188 If set to ``True``, don't add a ``<pre>`` and a ``<div>`` tag
189 around the tokens. This disables most other options (default: ``False``).
192 Tells the formatter to output a "full" document, i.e. a complete
193 self-contained document (default: ``False``).
196 If `full` is true, the title that should be used to caption the
197 document (default: ``''``).
200 The style to use, can be a string or a Style subclass (default:
201 ``'default'``). This option has no effect if the `cssfile`
202 and `noclobber_cssfile` option are given and the file specified in
206 If set to true, token ``<span>`` tags (as well as line number elements)
207 will not use CSS classes, but inline styles. This is not recommended
208 for larger pieces of code since it increases output size by quite a bit
209 (default: ``False``).
212 Since the token types use relatively short class names, they may clash
213 with some of your own class names. In this case you can use the
214 `classprefix` option to give a string to prepend to all Pygments-generated
215 CSS class names for token types.
216 Note that this option also affects the output of `get_style_defs()`.
219 CSS class for the wrapping ``<div>`` tag (default: ``'highlight'``).
220 If you set this option, the default selector for `get_style_defs()`
223 .. versionadded:: 0.9
224 If you select the ``'table'`` line numbers, the wrapping table will
225 have a CSS class of this string plus ``'table'``, the default is
226 accordingly ``'highlighttable'``.
229 Inline CSS styles for the wrapping ``<div>`` tag (default: ``''``).
232 Inline CSS styles for the ``<pre>`` tag (default: ``''``).
234 .. versionadded:: 0.11
237 If the `full` option is true and this option is given, it must be the
238 name of an external file. If the filename does not include an absolute
239 path, the file's path will be assumed to be relative to the main output
240 file's path, if the latter can be found. The stylesheet is then written
241 to this file instead of the HTML file.
243 .. versionadded:: 0.6
246 If `cssfile` is given and the specified file exists, the css file will
247 not be overwritten. This allows the use of the `full` option in
248 combination with a user specified css file. Default is ``False``.
250 .. versionadded:: 1.1
253 If set to ``'table'``, output line numbers as a table with two cells,
254 one containing the line numbers, the other the whole code. This is
255 copy-and-paste-friendly, but may cause alignment problems with some
256 browsers or fonts. If set to ``'inline'``, the line numbers will be
257 integrated in the ``<pre>`` tag that contains the code (that setting
258 is *new in Pygments 0.8*).
260 For compatibility with Pygments 0.7 and earlier, every true value
261 except ``'inline'`` means the same as ``'table'`` (in particular, that
262 means also ``True``).
264 The default value is ``False``, which means no line numbers at all.
266 **Note:** with the default ("table") line number mechanism, the line
267 numbers and code can have different line heights in Internet Explorer
268 unless you give the enclosing ``<pre>`` tags an explicit ``line-height``
269 CSS property (you get the default line spacing with ``line-height:
273 Specify a list of lines to be highlighted. The line numbers are always
274 relative to the input (i.e. the first line is line 1) and are
275 independent of `linenostart`.
277 .. versionadded:: 0.11
280 The line number for the first line (default: ``1``).
283 If set to a number n > 1, only every nth line number is printed.
286 If set to a number n > 0, every nth line number is given the CSS
287 class ``"special"`` (default: ``0``).
290 If set to ``True``, the formatter won't output the background color
291 for the wrapping element (this automatically defaults to ``False``
292 when there is no wrapping element [eg: no argument for the
293 `get_syntax_defs` method given]) (default: ``False``).
295 .. versionadded:: 0.6
298 This string is output between lines of code. It defaults to ``"\n"``,
299 which is enough to break a line inside ``<pre>`` tags, but you can
300 e.g. set it to ``"<br>"`` to get HTML line breaks.
302 .. versionadded:: 0.7
305 If set to a nonempty string, e.g. ``foo``, the formatter will wrap each
306 output line in an anchor tag with an ``id`` (and `name`) of ``foo-linenumber``.
307 This allows easy linking to certain lines.
309 .. versionadded:: 0.9
312 If set to a nonempty string, e.g. ``foo``, the formatter will wrap each
313 output line in a span tag with an ``id`` of ``foo-linenumber``.
314 This allows easy access to lines via javascript.
316 .. versionadded:: 1.6
319 If set to `True`, will wrap line numbers in <a> tags. Used in
320 combination with `linenos` and `lineanchors`.
323 If set to the path of a ctags file, wrap names in anchor tags that
324 link to their definitions. `lineanchors` should be used, and the
325 tags file should specify line numbers (see the `-n` option to ctags).
327 .. versionadded:: 1.6
330 A string formatting pattern used to generate links to ctags definitions.
331 Available variables are `%(path)s`, `%(fname)s` and `%(fext)s`.
332 Defaults to an empty string, resulting in just `#prefix-number` links.
334 .. versionadded:: 1.6
337 A string used to generate a filename when rendering ``<pre>`` blocks,
338 for example if displaying source code. If `linenos` is set to
339 ``'table'`` then the filename will be rendered in an initial row
340 containing a single `<th>` which spans both columns.
342 .. versionadded:: 2.1
345 Wrap the code inside ``<pre>`` blocks using ``<code>``, as recommended
346 by the HTML5 specification.
348 .. versionadded:: 2.4
351 Add ``title`` attributes to all token ``<span>`` tags that show the
354 .. versionadded:: 2.10
357 **Subclassing the HTML formatter**
359 .. versionadded:: 0.7
361 The HTML formatter is now built in a way that allows easy subclassing, thus
362 customizing the output HTML code. The `format()` method calls
363 `self._format_lines()` which returns a generator that yields tuples of ``(1,
364 line)``, where the ``1`` indicates that the ``line`` is a line of the
365 formatted source code.
367 If the `nowrap` option is set, the generator is the iterated over and the
368 resulting HTML is output.
370 Otherwise, `format()` calls `self.wrap()`, which wraps the generator with
371 other generators. These may add some HTML code to the one generated by
372 `_format_lines()`, either by modifying the lines generated by the latter,
373 then yielding them again with ``(1, line)``, and/or by yielding other HTML
374 code before or after the lines, with ``(0, html)``. The distinction between
375 source lines and other code makes it possible to wrap the generator multiple
378 The default `wrap()` implementation adds a ``<div>`` and a ``<pre>`` tag.
380 A custom `HtmlFormatter` subclass could look like this:
382 .. sourcecode:: python
384 class CodeHtmlFormatter(HtmlFormatter):
386 def wrap(self, source, *, include_div):
387 return self._wrap_code(source)
389 def _wrap_code(self, source):
393 # it's a line of formatted code
398 This results in wrapping the formatted lines with a ``<code>`` tag, where the
399 source lines are broken using ``<br>`` tags.
401 After calling `wrap()`, the `format()` method also adds the "line numbers"
402 and/or "full document" wrappers if the respective options are set. Then, all
403 HTML yielded by the wrapped generator is output.
408 filenames = [
'*.html',
'*.htm']
413 self.
nowrap = get_bool_opt(options,
'nowrap',
False)
414 self.
noclasses = get_bool_opt(options,
'noclasses',
False)
424 self.
wrapcode = get_bool_opt(options,
'wrapcode',
False)
430 raise RuntimeError(
'The "ctags" package must to be installed '
431 'to be able to use the "tagsfile" feature.')
435 if linenos ==
'inline':
451 for lineno
in get_list_opt(options,
'hl_lines', []):
460 """Return the css class of this token type prefixed with
461 the classprefix option."""
468 """Return the CSS classes of this token type prefixed with the classprefix option."""
470 while ttype
not in STANDARD_TYPES:
476 """Return the inline CSS styles for this token type."""
477 cclass = self.ttype2class.get(ttype)
478 while cclass
is None:
480 cclass = self.ttype2class.get(ttype)
484 t2c = self.ttype2class = {Token:
''}
485 c2s = self.class2style = {}
486 for ttype, ndef
in self.
style:
490 style +=
'color: %s; ' %
webify(ndef[
'color'])
492 style +=
'font-weight: bold; '
494 style +=
'font-style: italic; '
495 if ndef[
'underline']:
496 style +=
'text-decoration: underline; '
498 style +=
'background-color: %s; ' %
webify(ndef[
'bgcolor'])
500 style +=
'border: 1px solid %s; ' %
webify(ndef[
'border'])
505 c2s[name] = (style[:-2], ttype,
len(ttype))
509 Return CSS style definitions for the classes produced by the current
510 highlighting style. ``arg`` can be a string or list of selectors to
511 insert before the token type classes.
519 return '\n'.join(style_lines)
525 (level, ttype, cls, style)
526 for cls, (style, ttype, level)
in self.class2style.items()
532 '%s { %s } /* %s */' % (prefix(cls), style, repr(ttype)[6:])
533 for (level, ttype, cls, style)
in styles
540 bg_color = self.
style.background_color
541 hl_color = self.
style.highlight_color
545 if arg
and not self.
nobackground and bg_color
is not None:
547 if Text
in self.ttype2class:
548 text_style =
' ' + self.class2style[self.ttype2class[Text]][0]
550 0,
'%s{ background: %s;%s }' % (
551 prefix(
''), bg_color, text_style
554 if hl_color
is not None:
556 0,
'%s { background-color: %s }' % (prefix(
'hll'), hl_color)
586 return ', '.join(tmp)
592 return 'line-height: 125%;'
596 return 'color: %s; background-color: %s; padding-left: 5px; padding-right: 5px;' % (
597 self.
style.line_number_color,
598 self.
style.line_number_background_color
603 return 'color: %s; background-color: %s; padding-left: 5px; padding-right: 5px;' % (
604 self.
style.line_number_special_color,
605 self.
style.line_number_special_background_color
623 if not filename
or filename[0] ==
'<':
628 except AttributeError:
629 print(
'Note: Cannot determine output file name, '
630 'using current directory as base for the CSS file name',
636 with open(cssfilename,
"w", encoding=
"utf-8")
as cf:
639 except OSError
as err:
643 yield 0, (DOC_HEADER_EXTERNALCSS %
648 yield 0, (DOC_HEADER %
657 dummyoutfile = StringIO()
659 for t, line
in inner:
665 mw =
len(str(lncount + fl - 1))
674 for i
in range(fl, fl+lncount):
675 print_line = i % st == 0
676 special_line = sp
and i % sp == 0
679 line =
'%*d' % (mw, i)
681 line =
'<a href="#%s-%d">%s</a>' % (anchor_name, i, line)
692 style =
' class="special"'
694 style =
' class="normal"'
697 line =
'<span%s>%s</span>' % (style, line)
701 ls =
'\n'.join(lines)
708 '<tr><th colspan="2" class="filename">'
709 '<span class="filename">' + self.
filename +
'</span>'
715 yield 0, (f
'<table class="{self.cssclass}table">' + filename_tr +
716 '<tr><td class="linenos"><div class="linenodiv"><pre>' +
717 ls +
'</pre></div></td><td class="code">')
721 yield 0,
'</td></tr></table>'
726 inner_lines = list(inner)
730 mw =
len(str(
len(inner_lines) + num - 1))
735 for _, inner_line
in inner_lines:
736 print_line = num % st == 0
737 special_line = sp
and num % sp == 0
740 line =
'%*d' % (mw, num)
751 style =
' class="linenos special"'
753 style =
' class="linenos"'
756 linenos =
'<span%s>%s</span>' % (style, line)
761 yield 1, (
'<a href="#%s-%d">%s</a>' % (anchor_name, num, linenos) +
764 yield 1, linenos + inner_line
771 for t, line
in inner:
774 href =
"" if self.
linenos else ' href="#%s-%d"' % (s, i)
775 yield 1,
'<a id="%s-%d" name="%s-%d"%s></a>' % (s, i, s, i, href) + line
782 for t, line
in inner:
785 yield 1,
'<span id="%s-%d">%s</span>' % (s, i, line)
792 self.
style.background_color
is not None):
796 style =
'; '.join(style)
799 (style
and (
' style="%s"' % style)) +
'>')
809 style =
'; '.join(style)
812 yield 0, (
'<span class="filename">' + self.
filename +
'</span>')
816 yield 0, (
'<pre' + (style
and ' style="%s"' % style) +
'><span></span>')
825 @functools.lru_cache(maxsize=100)
827 """HTML-escape a value and split it by newlines."""
832 Just format the tokens, without any wrapping tags.
833 Yield individual lines.
841 for ttype, value
in tokensource:
849 css_style = self.class2style[css_style][0]
850 cspan =
'<span style="%s"%s>' % (css_style, title)
856 cspan =
'<span class="%s"%s>' % (css_class, title)
870 url = self.
tagurlformat % {
'path': base,
'fname': filename,
872 parts[0] =
"<a href=\"%s#%s-%d\">%s" % \
874 parts[-1] = parts[-1] +
"</a>"
877 for part
in parts[:-1]:
881 if lspan != cspan
and part:
883 (cspan
and '</span>'), lsep))
886 yield 1,
''.join(line)
889 yield 1,
''.join((cspan, part, (cspan
and '</span>'), lsep))
893 if line
and parts[-1]:
895 line.extend(((lspan
and '</span>'), cspan, parts[-1]))
900 line = [cspan, parts[-1]]
906 yield 1,
''.join(line)
911 return entry[
'file'], entry[
'lineNumber']
917 Highlighted the lines specified in the `hl_lines` option by
918 post-processing the token stream coming from `_format_lines`.
922 for i, (t, value)
in enumerate(tokensource):
928 if self.
style.highlight_color
is not None:
929 style = (
' style="background-color: %s"' %
930 (self.
style.highlight_color,))
931 yield 1,
'<span%s>%s</span>' % (style, value)
933 yield 1,
'<span class="hll">%s</span>' % value
939 Wrap the ``source``, which is a generator yielding
940 individual lines, in custom generators. See docstring
941 for `format`. Can be overridden.
954 The formatting process uses several nested generators; which of
955 them are used is determined by the user's options.
957 Each generator should take at least one argument, ``inner``,
958 and wrap the pieces of text generated by this.
960 Always yield 2-tuples: (code, text). If "code" is 1, the text
961 is part of the original tokensource being highlighted, if it's
962 0, the text is some piece of wrapping. This makes it possible to
963 use several different wrappers that process the original source
964 linewise, e.g. line number generators.
981 source = self.
wrap(source)
988 for t, piece
in source: