60 |
60 |
61 |
61 |
62 CSSFILE_TEMPLATE = '''\ |
62 CSSFILE_TEMPLATE = '''\ |
63 /* |
63 /* |
64 generated by Pygments <https://pygments.org/> |
64 generated by Pygments <https://pygments.org/> |
65 Copyright 2006-2019 by the Pygments team. |
65 Copyright 2006-2020 by the Pygments team. |
66 Licensed under the BSD license, see LICENSE for details. |
66 Licensed under the BSD license, see LICENSE for details. |
67 */ |
67 */ |
68 td.linenos { background-color: #f0f0f0; padding-right: 10px; } |
|
69 span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; } |
|
70 pre { line-height: 125%%; } |
|
71 %(styledefs)s |
68 %(styledefs)s |
72 ''' |
69 ''' |
73 |
70 |
74 DOC_HEADER = '''\ |
71 DOC_HEADER = '''\ |
75 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" |
72 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" |
76 "http://www.w3.org/TR/html4/strict.dtd"> |
73 "http://www.w3.org/TR/html4/strict.dtd"> |
77 <!-- |
74 <!-- |
78 generated by Pygments <https://pygments.org/> |
75 generated by Pygments <https://pygments.org/> |
79 Copyright 2006-2019 by the Pygments team. |
76 Copyright 2006-2020 by the Pygments team. |
80 Licensed under the BSD license, see LICENSE for details. |
77 Licensed under the BSD license, see LICENSE for details. |
81 --> |
78 --> |
82 <html> |
79 <html> |
83 <head> |
80 <head> |
84 <title>%(title)s</title> |
81 <title>%(title)s</title> |
433 self.linenos = 0 |
431 self.linenos = 0 |
434 self.linenostart = abs(get_int_opt(options, 'linenostart', 1)) |
432 self.linenostart = abs(get_int_opt(options, 'linenostart', 1)) |
435 self.linenostep = abs(get_int_opt(options, 'linenostep', 1)) |
433 self.linenostep = abs(get_int_opt(options, 'linenostep', 1)) |
436 self.linenospecial = abs(get_int_opt(options, 'linenospecial', 0)) |
434 self.linenospecial = abs(get_int_opt(options, 'linenospecial', 0)) |
437 self.nobackground = get_bool_opt(options, 'nobackground', False) |
435 self.nobackground = get_bool_opt(options, 'nobackground', False) |
438 self.lineseparator = options.get('lineseparator', u'\n') |
436 self.lineseparator = options.get('lineseparator', '\n') |
439 self.lineanchors = options.get('lineanchors', '') |
437 self.lineanchors = options.get('lineanchors', '') |
440 self.linespans = options.get('linespans', '') |
438 self.linespans = options.get('linespans', '') |
441 self.anchorlinenos = options.get('anchorlinenos', False) |
439 self.anchorlinenos = get_bool_opt(options, 'anchorlinenos', False) |
442 self.hl_lines = set() |
440 self.hl_lines = set() |
443 for lineno in get_list_opt(options, 'hl_lines', []): |
441 for lineno in get_list_opt(options, 'hl_lines', []): |
444 try: |
442 try: |
445 self.hl_lines.add(int(lineno)) |
443 self.hl_lines.add(int(lineno)) |
446 except ValueError: |
444 except ValueError: |
493 """ |
491 """ |
494 Return CSS style definitions for the classes produced by the current |
492 Return CSS style definitions for the classes produced by the current |
495 highlighting style. ``arg`` can be a string or list of selectors to |
493 highlighting style. ``arg`` can be a string or list of selectors to |
496 insert before the token type classes. |
494 insert before the token type classes. |
497 """ |
495 """ |
|
496 style_lines = [] |
|
497 |
|
498 style_lines.extend(self.get_linenos_style_defs()) |
|
499 style_lines.extend(self.get_background_style_defs(arg)) |
|
500 style_lines.extend(self.get_token_style_defs(arg)) |
|
501 |
|
502 return '\n'.join(style_lines) |
|
503 |
|
504 def get_token_style_defs(self, arg=None): |
|
505 prefix = self.get_css_prefix(arg) |
|
506 |
|
507 styles = [ |
|
508 (level, ttype, cls, style) |
|
509 for cls, (style, ttype, level) in self.class2style.items() |
|
510 if cls and style |
|
511 ] |
|
512 styles.sort() |
|
513 |
|
514 lines = [ |
|
515 '%s { %s } /* %s */' % (prefix(cls), style, repr(ttype)[6:]) |
|
516 for (level, ttype, cls, style) in styles |
|
517 ] |
|
518 |
|
519 return lines |
|
520 |
|
521 def get_background_style_defs(self, arg=None): |
|
522 prefix = self.get_css_prefix(arg) |
|
523 bg_color = self.style.background_color |
|
524 hl_color = self.style.highlight_color |
|
525 |
|
526 lines = [] |
|
527 |
|
528 if arg and not self.nobackground and bg_color is not None: |
|
529 text_style = '' |
|
530 if Text in self.ttype2class: |
|
531 text_style = ' ' + self.class2style[self.ttype2class[Text]][0] |
|
532 lines.insert( |
|
533 0, '%s{ background: %s;%s }' % ( |
|
534 prefix(''), bg_color, text_style |
|
535 ) |
|
536 ) |
|
537 if hl_color is not None: |
|
538 lines.insert( |
|
539 0, '%s { background-color: %s }' % (prefix('hll'), hl_color) |
|
540 ) |
|
541 |
|
542 return lines |
|
543 |
|
544 def get_linenos_style_defs(self): |
|
545 lines = [ |
|
546 'pre { %s }' % self._pre_style, |
|
547 'td.linenos pre { %s }' % self._linenos_style, |
|
548 'span.linenos { %s }' % self._linenos_style, |
|
549 'td.linenos pre.special { %s }' % self._linenos_special_style, |
|
550 'span.linenos.special { %s }' % self._linenos_special_style, |
|
551 ] |
|
552 |
|
553 return lines |
|
554 |
|
555 def get_css_prefix(self, arg): |
498 if arg is None: |
556 if arg is None: |
499 arg = ('cssclass' in self.options and '.'+self.cssclass or '') |
557 arg = ('cssclass' in self.options and '.'+self.cssclass or '') |
500 if isinstance(arg, str): |
558 if isinstance(arg, str): |
501 args = [arg] |
559 args = [arg] |
502 else: |
560 else: |
508 tmp = [] |
566 tmp = [] |
509 for arg in args: |
567 for arg in args: |
510 tmp.append((arg and arg + ' ' or '') + cls) |
568 tmp.append((arg and arg + ' ' or '') + cls) |
511 return ', '.join(tmp) |
569 return ', '.join(tmp) |
512 |
570 |
513 styles = [(level, ttype, cls, style) |
571 return prefix |
514 for cls, (style, ttype, level) in self.class2style.items() |
572 |
515 if cls and style] |
573 @property |
516 styles.sort() |
574 def _pre_style(self): |
517 lines = ['%s { %s } /* %s */' % (prefix(cls), style, repr(ttype)[6:]) |
575 return 'line-height: 125%; margin: 0;' |
518 for (level, ttype, cls, style) in styles] |
576 |
519 if arg and not self.nobackground and \ |
577 @property |
520 self.style.background_color is not None: |
578 def _linenos_style(self): |
521 text_style = '' |
579 return 'color: %s; background-color: %s; padding: 0 5px 0 5px;' % ( |
522 if Text in self.ttype2class: |
580 self.style.line_number_color, |
523 text_style = ' ' + self.class2style[self.ttype2class[Text]][0] |
581 self.style.line_number_background_color |
524 lines.insert(0, '%s { background: %s;%s }' % |
582 ) |
525 (prefix(''), self.style.background_color, text_style)) |
583 |
526 if self.style.highlight_color is not None: |
584 @property |
527 lines.insert(0, '%s.hll { background-color: %s }' % |
585 def _linenos_special_style(self): |
528 (prefix(''), self.style.highlight_color)) |
586 return 'color: %s; background-color: %s; padding: 0 5px 0 5px;' % ( |
529 return '\n'.join(lines) |
587 self.style.line_number_special_color, |
|
588 self.style.line_number_special_background_color |
|
589 ) |
530 |
590 |
531 def _decodeifneeded(self, value): |
591 def _decodeifneeded(self, value): |
532 if isinstance(value, bytes): |
592 if isinstance(value, bytes): |
533 if self.encoding: |
593 if self.encoding: |
534 return value.decode(self.encoding) |
594 return value.decode(self.encoding) |
590 sp = self.linenospecial |
649 sp = self.linenospecial |
591 st = self.linenostep |
650 st = self.linenostep |
592 la = self.lineanchors |
651 la = self.lineanchors |
593 aln = self.anchorlinenos |
652 aln = self.anchorlinenos |
594 nocls = self.noclasses |
653 nocls = self.noclasses |
595 if sp: |
654 |
596 lines = [] |
655 lines = [] |
597 |
656 |
598 for i in range(fl, fl+lncount): |
657 for i in range(fl, fl+lncount): |
599 if i % st == 0: |
658 print_line = i % st == 0 |
600 if i % sp == 0: |
659 special_line = sp and i % sp == 0 |
601 if aln: |
660 |
602 lines.append('<a href="#%s-%d" class="special">%*d</a>' % |
661 if print_line: |
603 (la, i, mw, i)) |
662 line = '%*d' % (mw, i) |
604 else: |
663 if aln: |
605 lines.append('<span class="special">%*d</span>' % (mw, i)) |
664 line = '<a href="#%s-%d">%s</a>' % (la, i, line) |
606 else: |
665 else: |
607 if aln: |
666 line = ' ' * mw |
608 lines.append('<a href="#%s-%d">%*d</a>' % (la, i, mw, i)) |
667 |
609 else: |
668 if nocls: |
610 lines.append('%*d' % (mw, i)) |
669 if special_line: |
|
670 style = ' style="%s"' % self._linenos_special_style |
611 else: |
671 else: |
612 lines.append('') |
672 style = ' style="%s"' % self._linenos_style |
613 ls = '\n'.join(lines) |
673 else: |
614 else: |
674 if special_line: |
615 lines = [] |
675 style = ' class="special"' |
616 for i in range(fl, fl+lncount): |
|
617 if i % st == 0: |
|
618 if aln: |
|
619 lines.append('<a href="#%s-%d">%*d</a>' % (la, i, mw, i)) |
|
620 else: |
|
621 lines.append('%*d' % (mw, i)) |
|
622 else: |
676 else: |
623 lines.append('') |
677 style = '' |
624 ls = '\n'.join(lines) |
678 |
|
679 if style: |
|
680 line = '<span%s>%s</span>' % (style, line) |
|
681 |
|
682 lines.append(line) |
|
683 |
|
684 ls = '\n'.join(lines) |
625 |
685 |
626 # in case you wonder about the seemingly redundant <div> here: since the |
686 # in case you wonder about the seemingly redundant <div> here: since the |
627 # content in the other cell also is wrapped in a div, some browsers in |
687 # content in the other cell also is wrapped in a div, some browsers in |
628 # some configurations seem to mess up the formatting... |
688 # some configurations seem to mess up the formatting... |
629 if nocls: |
689 yield 0, ( |
630 yield 0, ('<table class="%stable">' % self.cssclass + |
690 '<table class="%stable">' % self.cssclass + |
631 '<tr><td><div class="linenodiv" ' |
691 '<tr><td class="linenos"><div class="linenodiv"><pre>' + |
632 'style="background-color: #f0f0f0; padding-right: 10px">' |
692 ls + '</pre></div></td><td class="code">' |
633 '<pre style="line-height: 125%">' + |
693 ) |
634 ls + '</pre></div></td><td class="code">') |
|
635 else: |
|
636 yield 0, ('<table class="%stable">' % self.cssclass + |
|
637 '<tr><td class="linenos"><div class="linenodiv"><pre>' + |
|
638 ls + '</pre></div></td><td class="code">') |
|
639 yield 0, dummyoutfile.getvalue() |
694 yield 0, dummyoutfile.getvalue() |
640 yield 0, '</td></tr></table>' |
695 yield 0, '</td></tr></table>' |
641 |
696 |
642 def _wrap_inlinelinenos(self, inner): |
697 def _wrap_inlinelinenos(self, inner): |
643 # need a list of lines since we need the width of a single number :( |
698 # need a list of lines since we need the width of a single number :( |
644 lines = list(inner) |
699 inner_lines = list(inner) |
645 sp = self.linenospecial |
700 sp = self.linenospecial |
646 st = self.linenostep |
701 st = self.linenostep |
647 num = self.linenostart |
702 num = self.linenostart |
648 mw = len(str(len(lines) + num - 1)) |
703 mw = len(str(len(inner_lines) + num - 1)) |
649 |
704 nocls = self.noclasses |
650 if self.noclasses: |
705 |
651 if sp: |
706 for _, inner_line in inner_lines: |
652 for t, line in lines: |
707 print_line = num % st == 0 |
653 if num % sp == 0: |
708 special_line = sp and num % sp == 0 |
654 style = 'background-color: #ffffc0; padding: 0 5px 0 5px' |
709 |
655 else: |
710 if print_line: |
656 style = 'background-color: #f0f0f0; padding: 0 5px 0 5px' |
711 line = '%*d' % (mw, num) |
657 yield 1, '<span style="%s">%*s </span>' % ( |
|
658 style, mw, (num % st and ' ' or num)) + line |
|
659 num += 1 |
|
660 else: |
712 else: |
661 for t, line in lines: |
713 line = ' ' * mw |
662 yield 1, ('<span style="background-color: #f0f0f0; ' |
714 |
663 'padding: 0 5px 0 5px">%*s </span>' % ( |
715 if nocls: |
664 mw, (num % st and ' ' or num)) + line) |
716 if special_line: |
665 num += 1 |
717 style = ' style="%s"' % self._linenos_special_style |
666 elif sp: |
718 else: |
667 for t, line in lines: |
719 style = ' style="%s"' % self._linenos_style |
668 yield 1, '<span class="lineno%s">%*s </span>' % ( |
720 else: |
669 num % sp == 0 and ' special' or '', mw, |
721 if special_line: |
670 (num % st and ' ' or num)) + line |
722 style = ' class="linenos special"' |
671 num += 1 |
723 else: |
672 else: |
724 style = ' class="linenos"' |
673 for t, line in lines: |
725 |
674 yield 1, '<span class="lineno">%*s </span>' % ( |
726 if style: |
675 mw, (num % st and ' ' or num)) + line |
727 yield 1, '<span%s>%s</span>' % (style, line) + inner_line |
676 num += 1 |
728 else: |
|
729 yield 1, line + inner_line |
|
730 num += 1 |
677 |
731 |
678 def _wrap_lineanchors(self, inner): |
732 def _wrap_lineanchors(self, inner): |
679 s = self.lineanchors |
733 s = self.lineanchors |
680 # subtract 1 since we have to increment i *before* yielding |
734 # subtract 1 since we have to increment i *before* yielding |
681 i = self.linenostart - 1 |
735 i = self.linenostart - 1 |
705 style.append(self.cssstyles) |
759 style.append(self.cssstyles) |
706 style = '; '.join(style) |
760 style = '; '.join(style) |
707 |
761 |
708 yield 0, ('<div' + (self.cssclass and ' class="%s"' % self.cssclass) + |
762 yield 0, ('<div' + (self.cssclass and ' class="%s"' % self.cssclass) + |
709 (style and (' style="%s"' % style)) + '>') |
763 (style and (' style="%s"' % style)) + '>') |
710 for tup in inner: |
764 yield from inner |
711 yield tup |
|
712 yield 0, '</div>\n' |
765 yield 0, '</div>\n' |
713 |
766 |
714 def _wrap_pre(self, inner): |
767 def _wrap_pre(self, inner): |
715 style = [] |
768 style = [] |
716 if self.prestyles: |
769 if self.prestyles: |
717 style.append(self.prestyles) |
770 style.append(self.prestyles) |
718 if self.noclasses: |
771 if self.noclasses: |
719 style.append('line-height: 125%') |
772 style.append(self._pre_style) |
720 style = '; '.join(style) |
773 style = '; '.join(style) |
721 |
774 |
722 if self.filename: |
775 if self.filename: |
723 yield 0, ('<span class="filename">' + self.filename + '</span>') |
776 yield 0, ('<span class="filename">' + self.filename + '</span>') |
724 |
777 |
725 # the empty span here is to keep leading empty lines from being |
778 # the empty span here is to keep leading empty lines from being |
726 # ignored by HTML parsers |
779 # ignored by HTML parsers |
727 yield 0, ('<pre' + (style and ' style="%s"' % style) + '><span></span>') |
780 yield 0, ('<pre' + (style and ' style="%s"' % style) + '><span></span>') |
728 for tup in inner: |
781 yield from inner |
729 yield tup |
|
730 yield 0, '</pre>' |
782 yield 0, '</pre>' |
731 |
783 |
732 def _wrap_code(self, inner): |
784 def _wrap_code(self, inner): |
733 yield 0, '<code>' |
785 yield 0, '<code>' |
734 for tup in inner: |
786 yield from inner |
735 yield tup |
|
736 yield 0, '</code>' |
787 yield 0, '</code>' |
737 |
788 |
738 def _format_lines(self, tokensource): |
789 def _format_lines(self, tokensource): |
739 """ |
790 """ |
740 Just format the tokens, without any wrapping tags. |
791 Just format the tokens, without any wrapping tags. |