eric6/ThirdParty/Pygments/pygments/formatters/html.py

changeset 7983
54c5cfbb1e29
parent 7701
25f42e208e08
equal deleted inserted replaced
7982:48d210e41c65 7983:54c5cfbb1e29
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-2020 by the Pygments team, see AUTHORS. 8 :copyright: Copyright 2006-2021 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 import functools
12 import os 13 import os
13 import sys 14 import sys
14 import os.path 15 import os.path
15 from io import StringIO 16 from io import StringIO
16 17
60 61
61 62
62 CSSFILE_TEMPLATE = '''\ 63 CSSFILE_TEMPLATE = '''\
63 /* 64 /*
64 generated by Pygments <https://pygments.org/> 65 generated by Pygments <https://pygments.org/>
65 Copyright 2006-2020 by the Pygments team. 66 Copyright 2006-2021 by the Pygments team.
66 Licensed under the BSD license, see LICENSE for details. 67 Licensed under the BSD license, see LICENSE for details.
67 */ 68 */
68 %(styledefs)s 69 %(styledefs)s
69 ''' 70 '''
70 71
71 DOC_HEADER = '''\ 72 DOC_HEADER = '''\
72 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" 73 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
73 "http://www.w3.org/TR/html4/strict.dtd"> 74 "http://www.w3.org/TR/html4/strict.dtd">
74 <!-- 75 <!--
75 generated by Pygments <https://pygments.org/> 76 generated by Pygments <https://pygments.org/>
76 Copyright 2006-2020 by the Pygments team. 77 Copyright 2006-2021 by the Pygments team.
77 Licensed under the BSD license, see LICENSE for details. 78 Licensed under the BSD license, see LICENSE for details.
78 --> 79 -->
79 <html> 80 <html>
80 <head> 81 <head>
81 <title>%(title)s</title> 82 <title>%(title)s</title>
412 self.noclobber_cssfile = get_bool_opt(options, 'noclobber_cssfile', False) 413 self.noclobber_cssfile = get_bool_opt(options, 'noclobber_cssfile', False)
413 self.tagsfile = self._decodeifneeded(options.get('tagsfile', '')) 414 self.tagsfile = self._decodeifneeded(options.get('tagsfile', ''))
414 self.tagurlformat = self._decodeifneeded(options.get('tagurlformat', '')) 415 self.tagurlformat = self._decodeifneeded(options.get('tagurlformat', ''))
415 self.filename = self._decodeifneeded(options.get('filename', '')) 416 self.filename = self._decodeifneeded(options.get('filename', ''))
416 self.wrapcode = get_bool_opt(options, 'wrapcode', False) 417 self.wrapcode = get_bool_opt(options, 'wrapcode', False)
418 self.span_element_openers = {}
417 419
418 if self.tagsfile: 420 if self.tagsfile:
419 if not ctags: 421 if not ctags:
420 raise RuntimeError('The "ctags" package must to be installed ' 422 raise RuntimeError('The "ctags" package must to be installed '
421 'to be able to use the "tagsfile" feature.') 423 'to be able to use the "tagsfile" feature.')
453 if ttypeclass: 455 if ttypeclass:
454 return self.classprefix + ttypeclass 456 return self.classprefix + ttypeclass
455 return '' 457 return ''
456 458
457 def _get_css_classes(self, ttype): 459 def _get_css_classes(self, ttype):
458 """Return the css classes of this token type prefixed with 460 """Return the CSS classes of this token type prefixed with the classprefix option."""
459 the classprefix option."""
460 cls = self._get_css_class(ttype) 461 cls = self._get_css_class(ttype)
461 while ttype not in STANDARD_TYPES: 462 while ttype not in STANDARD_TYPES:
462 ttype = ttype.parent 463 ttype = ttype.parent
463 cls = self._get_css_class(ttype) + ' ' + cls 464 cls = self._get_css_class(ttype) + ' ' + cls
464 return cls 465 return cls or ''
466
467 def _get_css_inline_styles(self, ttype):
468 """Return the inline CSS styles for this token type."""
469 cclass = self.ttype2class.get(ttype)
470 while cclass is None:
471 ttype = ttype.parent
472 cclass = self.ttype2class.get(ttype)
473 return cclass or ''
465 474
466 def _create_stylesheet(self): 475 def _create_stylesheet(self):
467 t2c = self.ttype2class = {Token: ''} 476 t2c = self.ttype2class = {Token: ''}
468 c2s = self.class2style = {} 477 c2s = self.class2style = {}
469 for ttype, ndef in self.style: 478 for ttype, ndef in self.style:
570 579
571 return prefix 580 return prefix
572 581
573 @property 582 @property
574 def _pre_style(self): 583 def _pre_style(self):
575 return 'line-height: 125%; margin: 0;' 584 return 'line-height: 125%;'
576 585
577 @property 586 @property
578 def _linenos_style(self): 587 def _linenos_style(self):
579 return 'color: %s; background-color: %s; padding: 0 5px 0 5px;' % ( 588 return 'color: %s; background-color: %s; padding-left: 5px; padding-right: 5px;' % (
580 self.style.line_number_color, 589 self.style.line_number_color,
581 self.style.line_number_background_color 590 self.style.line_number_background_color
582 ) 591 )
583 592
584 @property 593 @property
585 def _linenos_special_style(self): 594 def _linenos_special_style(self):
586 return 'color: %s; background-color: %s; padding: 0 5px 0 5px;' % ( 595 return 'color: %s; background-color: %s; padding-left: 5px; padding-right: 5px;' % (
587 self.style.line_number_special_color, 596 self.style.line_number_special_color,
588 self.style.line_number_special_background_color 597 self.style.line_number_special_background_color
589 ) 598 )
590 599
591 def _decodeifneeded(self, value): 600 def _decodeifneeded(self, value):
784 def _wrap_code(self, inner): 793 def _wrap_code(self, inner):
785 yield 0, '<code>' 794 yield 0, '<code>'
786 yield from inner 795 yield from inner
787 yield 0, '</code>' 796 yield 0, '</code>'
788 797
798 @functools.lru_cache(maxsize=100)
799 def _translate_parts(self, value):
800 """HTML-escape a value and split it by newlines."""
801 return value.translate(_escape_html_table).split('\n')
802
789 def _format_lines(self, tokensource): 803 def _format_lines(self, tokensource):
790 """ 804 """
791 Just format the tokens, without any wrapping tags. 805 Just format the tokens, without any wrapping tags.
792 Yield individual lines. 806 Yield individual lines.
793 """ 807 """
794 nocls = self.noclasses 808 nocls = self.noclasses
795 lsep = self.lineseparator 809 lsep = self.lineseparator
796 # for <span style=""> lookup only
797 getcls = self.ttype2class.get
798 c2s = self.class2style
799 escape_table = _escape_html_table
800 tagsfile = self.tagsfile 810 tagsfile = self.tagsfile
801 811
802 lspan = '' 812 lspan = ''
803 line = [] 813 line = []
804 for ttype, value in tokensource: 814 for ttype, value in tokensource:
805 if nocls: 815 try:
806 cclass = getcls(ttype) 816 cspan = self.span_element_openers[ttype]
807 while cclass is None: 817 except KeyError:
808 ttype = ttype.parent 818 if nocls:
809 cclass = getcls(ttype) 819 css_style = self._get_css_inline_styles(ttype)
810 cspan = cclass and '<span style="%s">' % c2s[cclass][0] or '' 820 cspan = css_style and '<span style="%s">' % self.class2style[css_style][0] or ''
811 else: 821 else:
812 cls = self._get_css_classes(ttype) 822 css_class = self._get_css_classes(ttype)
813 cspan = cls and '<span class="%s">' % cls or '' 823 cspan = css_class and '<span class="%s">' % css_class or ''
814 824 self.span_element_openers[ttype] = cspan
815 parts = value.translate(escape_table).split('\n') 825
826 parts = self._translate_parts(value)
816 827
817 if tagsfile and ttype in Token.Name: 828 if tagsfile and ttype in Token.Name:
818 filename, linenumber = self._lookup_ctag(value) 829 filename, linenumber = self._lookup_ctag(value)
819 if linenumber: 830 if linenumber:
820 base, filename = os.path.split(filename) 831 base, filename = os.path.split(filename)

eric ide

mercurial