From: Blair Conrad Date: Thu, 21 May 2020 12:46:57 +0000 (-0400) Subject: m.code: revamp ANSI color code handling completely. X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~cjwatson/git?a=commitdiff_plain;h=f3a166100128107527a0335c6912c4bc9754831e;p=blog.git m.code: revamp ANSI color code handling completely. Co-authored-by: Sergei Izmailov --- diff --git a/css/m-dark+documentation.compiled.css b/css/m-dark+documentation.compiled.css index a10afe7b..f3a4bf57 100644 --- a/css/m-dark+documentation.compiled.css +++ b/css/m-dark+documentation.compiled.css @@ -2548,6 +2548,23 @@ article:last-child, article section:last-child { margin-bottom: 0; } .m-code .il { color: #c7cf2f } .m-console .hll { background-color: #ffffcc } +.m-console .g-AnsiBackgroundBlack { background-color: #232627 } +.m-console .g-AnsiBackgroundBlue { background-color: #1d99f3 } +.m-console .g-AnsiBackgroundBrightBlack { background-color: #7f8c8d } +.m-console .g-AnsiBackgroundBrightBlue { background-color: #3daee9 } +.m-console .g-AnsiBackgroundBrightCyan { background-color: #16a085 } +.m-console .g-AnsiBackgroundBrightGreen { background-color: #1cdc9a } +.m-console .g-AnsiBackgroundBrightMagenta { background-color: #8e44ad } +.m-console .g-AnsiBackgroundBrightRed { background-color: #c0392b } +.m-console .g-AnsiBackgroundBrightWhite { background-color: #ffffff } +.m-console .g-AnsiBackgroundBrightYellow { background-color: #fdbc4b } +.m-console .g-AnsiBackgroundCyan { background-color: #1abc9c } +.m-console .g-AnsiBackgroundDefault { background-color: #fcfcfc } +.m-console .g-AnsiBackgroundGreen { background-color: #11d116 } +.m-console .g-AnsiBackgroundMagenta { background-color: #9b59b6 } +.m-console .g-AnsiBackgroundRed { background-color: #ed1515 } +.m-console .g-AnsiBackgroundWhite { background-color: #fcfcfc } +.m-console .g-AnsiBackgroundYellow { background-color: #f67400 } .m-console .g-AnsiBlack { color: #232627 } .m-console .g-AnsiBlue { color: #1d99f3 } .m-console .g-AnsiBrightBlack { color: #7f8c8d; font-weight: bold } diff --git a/css/m-dark.compiled.css b/css/m-dark.compiled.css index 0112d49a..5a9845f9 100644 --- a/css/m-dark.compiled.css +++ b/css/m-dark.compiled.css @@ -2548,6 +2548,23 @@ article:last-child, article section:last-child { margin-bottom: 0; } .m-code .il { color: #c7cf2f } .m-console .hll { background-color: #ffffcc } +.m-console .g-AnsiBackgroundBlack { background-color: #232627 } +.m-console .g-AnsiBackgroundBlue { background-color: #1d99f3 } +.m-console .g-AnsiBackgroundBrightBlack { background-color: #7f8c8d } +.m-console .g-AnsiBackgroundBrightBlue { background-color: #3daee9 } +.m-console .g-AnsiBackgroundBrightCyan { background-color: #16a085 } +.m-console .g-AnsiBackgroundBrightGreen { background-color: #1cdc9a } +.m-console .g-AnsiBackgroundBrightMagenta { background-color: #8e44ad } +.m-console .g-AnsiBackgroundBrightRed { background-color: #c0392b } +.m-console .g-AnsiBackgroundBrightWhite { background-color: #ffffff } +.m-console .g-AnsiBackgroundBrightYellow { background-color: #fdbc4b } +.m-console .g-AnsiBackgroundCyan { background-color: #1abc9c } +.m-console .g-AnsiBackgroundDefault { background-color: #fcfcfc } +.m-console .g-AnsiBackgroundGreen { background-color: #11d116 } +.m-console .g-AnsiBackgroundMagenta { background-color: #9b59b6 } +.m-console .g-AnsiBackgroundRed { background-color: #ed1515 } +.m-console .g-AnsiBackgroundWhite { background-color: #fcfcfc } +.m-console .g-AnsiBackgroundYellow { background-color: #f67400 } .m-console .g-AnsiBlack { color: #232627 } .m-console .g-AnsiBlue { color: #1d99f3 } .m-console .g-AnsiBrightBlack { color: #7f8c8d; font-weight: bold } diff --git a/css/m-light+documentation.compiled.css b/css/m-light+documentation.compiled.css index 48c77bbc..379eb02e 100644 --- a/css/m-light+documentation.compiled.css +++ b/css/m-light+documentation.compiled.css @@ -2481,6 +2481,23 @@ article:last-child, article section:last-child { margin-bottom: 0; } } .m-console .hll { background-color: #ffffcc } +.m-console .g-AnsiBackgroundBlack { background-color: #232627 } +.m-console .g-AnsiBackgroundBlue { background-color: #1d99f3 } +.m-console .g-AnsiBackgroundBrightBlack { background-color: #7f8c8d } +.m-console .g-AnsiBackgroundBrightBlue { background-color: #3daee9 } +.m-console .g-AnsiBackgroundBrightCyan { background-color: #16a085 } +.m-console .g-AnsiBackgroundBrightGreen { background-color: #1cdc9a } +.m-console .g-AnsiBackgroundBrightMagenta { background-color: #8e44ad } +.m-console .g-AnsiBackgroundBrightRed { background-color: #c0392b } +.m-console .g-AnsiBackgroundBrightWhite { background-color: #ffffff } +.m-console .g-AnsiBackgroundBrightYellow { background-color: #fdbc4b } +.m-console .g-AnsiBackgroundCyan { background-color: #1abc9c } +.m-console .g-AnsiBackgroundDefault { background-color: #fcfcfc } +.m-console .g-AnsiBackgroundGreen { background-color: #11d116 } +.m-console .g-AnsiBackgroundMagenta { background-color: #9b59b6 } +.m-console .g-AnsiBackgroundRed { background-color: #ed1515 } +.m-console .g-AnsiBackgroundWhite { background-color: #fcfcfc } +.m-console .g-AnsiBackgroundYellow { background-color: #f67400 } .m-console .g-AnsiBlack { color: #232627 } .m-console .g-AnsiBlue { color: #1d99f3 } .m-console .g-AnsiBrightBlack { color: #7f8c8d; font-weight: bold } diff --git a/css/m-light.compiled.css b/css/m-light.compiled.css index a4a4c100..0079fbcb 100644 --- a/css/m-light.compiled.css +++ b/css/m-light.compiled.css @@ -2481,6 +2481,23 @@ article:last-child, article section:last-child { margin-bottom: 0; } } .m-console .hll { background-color: #ffffcc } +.m-console .g-AnsiBackgroundBlack { background-color: #232627 } +.m-console .g-AnsiBackgroundBlue { background-color: #1d99f3 } +.m-console .g-AnsiBackgroundBrightBlack { background-color: #7f8c8d } +.m-console .g-AnsiBackgroundBrightBlue { background-color: #3daee9 } +.m-console .g-AnsiBackgroundBrightCyan { background-color: #16a085 } +.m-console .g-AnsiBackgroundBrightGreen { background-color: #1cdc9a } +.m-console .g-AnsiBackgroundBrightMagenta { background-color: #8e44ad } +.m-console .g-AnsiBackgroundBrightRed { background-color: #c0392b } +.m-console .g-AnsiBackgroundBrightWhite { background-color: #ffffff } +.m-console .g-AnsiBackgroundBrightYellow { background-color: #fdbc4b } +.m-console .g-AnsiBackgroundCyan { background-color: #1abc9c } +.m-console .g-AnsiBackgroundDefault { background-color: #fcfcfc } +.m-console .g-AnsiBackgroundGreen { background-color: #11d116 } +.m-console .g-AnsiBackgroundMagenta { background-color: #9b59b6 } +.m-console .g-AnsiBackgroundRed { background-color: #ed1515 } +.m-console .g-AnsiBackgroundWhite { background-color: #fcfcfc } +.m-console .g-AnsiBackgroundYellow { background-color: #f67400 } .m-console .g-AnsiBlack { color: #232627 } .m-console .g-AnsiBlue { color: #1d99f3 } .m-console .g-AnsiBrightBlack { color: #7f8c8d; font-weight: bold } diff --git a/css/pygments-console.css b/css/pygments-console.css index a726b019..13f03900 100644 --- a/css/pygments-console.css +++ b/css/pygments-console.css @@ -1,4 +1,21 @@ .m-console .hll { background-color: #ffffcc } +.m-console .g-AnsiBackgroundBlack { background-color: #232627 } /* Generic.AnsiBackgroundBlack */ +.m-console .g-AnsiBackgroundBlue { background-color: #1d99f3 } /* Generic.AnsiBackgroundBlue */ +.m-console .g-AnsiBackgroundBrightBlack { background-color: #7f8c8d } /* Generic.AnsiBackgroundBrightBlack */ +.m-console .g-AnsiBackgroundBrightBlue { background-color: #3daee9 } /* Generic.AnsiBackgroundBrightBlue */ +.m-console .g-AnsiBackgroundBrightCyan { background-color: #16a085 } /* Generic.AnsiBackgroundBrightCyan */ +.m-console .g-AnsiBackgroundBrightGreen { background-color: #1cdc9a } /* Generic.AnsiBackgroundBrightGreen */ +.m-console .g-AnsiBackgroundBrightMagenta { background-color: #8e44ad } /* Generic.AnsiBackgroundBrightMagenta */ +.m-console .g-AnsiBackgroundBrightRed { background-color: #c0392b } /* Generic.AnsiBackgroundBrightRed */ +.m-console .g-AnsiBackgroundBrightWhite { background-color: #ffffff } /* Generic.AnsiBackgroundBrightWhite */ +.m-console .g-AnsiBackgroundBrightYellow { background-color: #fdbc4b } /* Generic.AnsiBackgroundBrightYellow */ +.m-console .g-AnsiBackgroundCyan { background-color: #1abc9c } /* Generic.AnsiBackgroundCyan */ +.m-console .g-AnsiBackgroundDefault { background-color: #fcfcfc } /* Generic.AnsiBackgroundDefault */ +.m-console .g-AnsiBackgroundGreen { background-color: #11d116 } /* Generic.AnsiBackgroundGreen */ +.m-console .g-AnsiBackgroundMagenta { background-color: #9b59b6 } /* Generic.AnsiBackgroundMagenta */ +.m-console .g-AnsiBackgroundRed { background-color: #ed1515 } /* Generic.AnsiBackgroundRed */ +.m-console .g-AnsiBackgroundWhite { background-color: #fcfcfc } /* Generic.AnsiBackgroundWhite */ +.m-console .g-AnsiBackgroundYellow { background-color: #f67400 } /* Generic.AnsiBackgroundYellow */ .m-console .g-AnsiBlack { color: #232627 } /* Generic.AnsiBlack */ .m-console .g-AnsiBlue { color: #1d99f3 } /* Generic.AnsiBlue */ .m-console .g-AnsiBrightBlack { color: #7f8c8d; font-weight: bold } /* Generic.AnsiBrightBlack */ diff --git a/doc/plugins/math-and-code.rst b/doc/plugins/math-and-code.rst index 89bbded2..6de8a130 100644 --- a/doc/plugins/math-and-code.rst +++ b/doc/plugins/math-and-code.rst @@ -446,11 +446,11 @@ terminal, it's best to have the listings in external files and use :code: ansi :class: m-nopad -Apart from the basic color set there's also a very rudimentary support for -24bit colors using the ``\033[{?};2;{r};{g};{b}m`` color sequence --- currently -either just the foreground (the ``\033[38;2;`` prefix) or foreground -immediately followed by background color specification (the -``\033[48;2;`` prefix): +There's support for the basic foreground and background color sets, 256 palette +colors using the ``\033[38;5;{p}m`` or ``\033[48;5;{p}m`` color sequences, +and 24bit colors using the ``\033[38;2;{r};{g};{b}m`` and +``\033[48;2;{r};{g};{b}m`` color sequences. The non-bright basic foreground +colors can be independently brightened using the ``\033[1m`` color sequence: .. include:: math-and-code-console-colors.ansi :code: ansi diff --git a/plugins/ansilexer.py b/plugins/ansilexer.py index 01dd9ce1..bd540639 100644 --- a/plugins/ansilexer.py +++ b/plugins/ansilexer.py @@ -2,6 +2,7 @@ # This file is part of m.css. # # Copyright © 2017, 2018, 2019, 2020 Vladimír Vondruš +# Copyright © 2020 Blair Conrad # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), @@ -28,78 +29,281 @@ from pygments.lexer import RegexLexer from pygments.formatters import HtmlFormatter from pygments.token import * +# Support ANSI SGR codes in input, styling the output. +# Code definitions are taken from +# http://man7.org/linux/man-pages/man4/console_codes.4.html, which +# appears in part below, in case it disappears: +# +# ECMA-48 Set Graphics Rendition +# +# The ECMA-48 SGR sequence ESC [ parameters m sets display attributes. +# Several attributes can be set in the same sequence, separated by +# semicolons. An empty parameter (between semicolons or string +# initiator or terminator) is interpreted as a zero. +# param result +# 0 reset all attributes to their defaults +# 1 set bold +# 2 set half-bright (simulated with color on a color display) +# 4 set underscore (simulated with color on a color display) +# (the colors used to simulate dim or underline are set +# using ESC ] ...) +# 5 set blink +# 7 set reverse video +# 10 reset selected mapping, display control flag, and toggle +# meta flag (ECMA-48 says "primary font"). +# 11 select null mapping, set display control flag, reset +# toggle meta flag (ECMA-48 says "first alternate font"). +# 12 select null mapping, set display control flag, set toggle +# meta flag (ECMA-48 says "second alternate font"). The +# toggle meta flag causes the high bit of a byte to be +# toggled before the mapping table translation is done. +# 21 set underline; before Linux 4.17, this value set normal +# intensity (as is done in many other terminals) +# 22 set normal intensity +# 24 underline off +# 25 blink off +# 27 reverse video off +# 30 set black foreground +# 31 set red foreground +# 32 set green foreground +# 33 set brown foreground +# 34 set blue foreground +# 35 set magenta foreground +# 36 set cyan foreground +# 37 set white foreground +# 38 256/24-bit foreground color follows, shoehorned into 16 +# basic colors (before Linux 3.16: set underscore on, set +# default foreground color) +# 39 set default foreground color (before Linux 3.16: set +# underscore off, set default foreground color) +# 40 set black background +# 41 set red background +# 42 set green background +# 43 set brown background +# 44 set blue background +# 45 set magenta background +# 46 set cyan background +# 47 set white background +# 48 256/24-bit background color follows, shoehorned into 8 +# basic colors +# 49 set default background color +# 90..97 set foreground to bright versions of 30..37 +# 100..107 set background, same as 40..47 (bright not supported) +# +# Commands 38 and 48 require further arguments: +# ;5;x 256 color: values 0..15 are IBGR (black, red, green, +# ... white), 16..231 a 6x6x6 color cube, 232..255 a +# grayscale ramp +# ;2;r;g;b 24-bit color, r/g/b components are in the range 0..255 +# +# For historical reasons, all "brown"s above are replaced with "yellow" +# by m.css. +# +# AnsiLexer supports commands 0, 1, 22, 30–39, 40–49, 90–97, and 100–107 +# (ranges inclusive). +# All other commands will be ignored completely. +# +# Foreground colors named Bright* are not affected by the "bright" SGR +# setting—they will always appear bright, even after command 22 resets the +# normal intensity. Likewise, they will not affect the "bright" setting—a +# directive to use Red after BrightGreen will result in Red being displayed, +# not BrightRed. +# +# Palette or RGB Foreground colors from command 38 likewise do not interact +# with the "bright" setting, nor do any background colors. class AnsiLexer(RegexLexer): name = 'Ansi escape lexer' - def callback(lexer, match): - bright = match.group(1) - color = match.group(2) - text = match.group(3) + _sgrs_and_text = '(?P(\x1b\\[(\\d*;)*\\d*m)+)(?P[^\x1b]*)' + _sgr_split = re.compile('m\x1b\\[|;|m|\x1b\\[') - if int(bright) == 0: - token = 'Generic.Ansi' - elif int(bright) == 1: - token = 'Generic.AnsiBright' + _named_colors = [ + 'Black', + 'Red', + 'Green', + 'Yellow', + 'Blue', + 'Magenta', + 'Cyan', + 'White', + ] + _palette_start_colors = [ + '000000', + '800000', + '008000', + '808000', + '000080', + '800080', + '008080', + 'c0c0c0', + '808080', + 'ff0000', + '00ff00', + 'ffff00', + '0000ff', + 'ff00ff', + '00ffff', + 'ffffff', + ] + _palette_cube_steps = ['00', '5f', '87', 'af', 'd7', 'ff'] + + def __init__(self, **options): + RegexLexer.__init__(self, **options) + + self._bright = False + self._foreground = 'Default' + self._background = 'Default' + + def _callback(self, match): + commands = match.group('commands') + text = match.group('text') + + # split the commands strings into their constituent parameter codes + parameters = self._sgr_split.split(commands)[1:-1] + parameters = [int(p) if p else 0 for p in parameters] + + # loop over the parameters, consuming them to create commands, some + # of which will have arguments + while parameters: + command = parameters.pop(0) + if command == 0: + self._bright = False + self._foreground = 'Default' + self._background = 'Default' + elif command == 1: + self._bright = True + elif command == 22: + self._bright = False + elif command >= 30 and command <= 37: + self._foreground = self._named_colors[command - 30] + elif command == 38: + mode = parameters.pop(0) + if mode == 2: + rgb = self._read_rgb(parameters) + else: + offset = parameters.pop(0) + rgb = self._make_color_from_palette(offset) + self._foreground = 'ForegroundColor' + rgb + elif command == 39: + self._foreground = 'Default' + elif command >= 40 and command <= 47: + self._background = self._named_colors[command - 40] + elif command == 48: + mode = parameters.pop(0) + if mode == 2: + rgb = self._read_rgb(parameters) + else: + offset = parameters.pop() + rgb = self._make_color_from_palette(offset) + self._background = rgb + elif command == 49: + self._background = 'Default' + elif command >= 90 and command <= 97: + self._foreground = ('Bright' + + self._named_colors[command - 90]) + elif command >= 100 and command <= 107: + self._background = ('Bright' + + self._named_colors[command - 100]) + + if (self._bright + and not self._foreground.startswith('Bright') + and not self._foreground.startswith('ForegroundColor')): + token = 'Generic.AnsiBright' + self._foreground else: + token = 'Generic.Ansi' + self._foreground + + if (self._background != 'Default'): + token += 'BackgroundColor' + self._background + + if token == 'Generic.AnsiDefault': yield (match.start(), Text, text) - return - - if color == '30': - token += 'Black' - elif color == '31': - token += 'Red' - elif color == '32': - token += 'Green' - elif color == '33': - token += 'Yellow' - elif color == '34': - token += 'Blue' - elif color == '35': - token += 'Magenta' - elif color == '36': - token += 'Cyan' - elif color == '37': - token += 'White' - elif color == '39': - token += 'Default' else: - yield (match.start(), Text, text) - return + yield (match.start(), string_to_tokentype(token), text) - yield (match.start(), string_to_tokentype(token), text) + def _read_rgb(self, parameters): + r = parameters.pop(0) + g = parameters.pop(0) + b = parameters.pop(0) + return self._to_hex(r,g,b) - def callback_fg_color(lexer, match): - token = 'Generic.AnsiForegroundColor{:02x}{:02x}{:02x}'.format( - int(match.group(1)), int(match.group(2)), int(match.group(3))) - yield (match.start, string_to_tokentype(token), match.group(4)) + def _make_color_from_palette(self, offset): + # the palette runs from 0–255 inclusive, consisting of + # - 16 specific colors intended to give a good range + # - 216 colors laid out on a color cube, with axes for + # each of red, green, and blue + # - 24 shades of grey, from grey3 to grey93 + if offset < 16: + return self._palette_start_colors[offset] + elif offset < 232: + offset = offset - 16 + offset, b = divmod (offset,6) + r, g = divmod(offset, 6) + r = self._palette_cube_steps[r] + g = self._palette_cube_steps[g] + b = self._palette_cube_steps[b] + return r + g + b + else: + shade = 8 + 10 * (offset - 232) + return self._to_hex(shade, shade, shade) - def callback_fg_bg_color(lexer, match): - token = 'Generic.AnsiForegroundBackgroundColor{:02x}{:02x}{:02x}'.format( - int(match.group(1)), int(match.group(2)), int(match.group(3))) - yield (match.start, string_to_tokentype(token), match.group(4)) + def _to_hex(self, r, g, b): + return '{:02x}{:02x}{:02x}'.format(r, g, b) tokens = { 'root': [ ('[^\x1b]+', Text), - ('\x1b\\[38;2;(\\d+);(\\d+);(\\d+)m\x1b\\[48;2;\\d+;\\d+;\\d+m([^\x1b]+)\x1b\\[0m', callback_fg_bg_color), - ('\x1b\\[38;2;(\\d+);(\\d+);(\\d+)m([^\x1b]+)\x1b\\[0m', callback_fg_color), - # Brightness and color separately (used by ASan reports) - ('\x1b\\[([01])m\x1b\\[(\\d+)m([^\x1b]*)', callback), - ('\x1b\\[(\\d+)(?:;(\\d+))?m([^\x1b]*)', callback) + (_sgrs_and_text, _callback), ] } -_ansi_fg_color_re = re.compile('class="g g-AnsiForegroundColor([0-9a-f]{6})"') -_ansi_fg_bg_color_re = re.compile('class="g g-AnsiForegroundBackgroundColor([0-9a-f]{6})"') - class HtmlAnsiFormatter(HtmlFormatter): + _ansi_color_re = re.compile( + r'(?Pclass="g )(?Pg-Ansi\S+)(?P")' + ) + _rgb_code_re = re.compile(r'[0-9a-f]{6}$') + def wrap(self, source, outfile): return self._wrap_code(source) def _wrap_code(self, source): for i, t in source: if i == 1: # it's a line of formatted code - t = _ansi_fg_bg_color_re.sub('style="color: #\\1; background-color: #\\1"', t) - t = _ansi_fg_color_re.sub('style="color: #\\1"', t) - #t += 'H' + t = self._ansi_color_re.sub(self._replace_ansi_class, t) yield i, t + + def _replace_ansi_class(self, match): + html_classes = ['g'] + html_styles = [] + foreground_color = None + background_color = None + ansi_class = match.group('AnsiClass') + + i = ansi_class.find('BackgroundColor') + if i >= 0: + background_color = ansi_class[i + 15:] + ansi_class = ansi_class[:i] + + if self._rgb_code_re.match(background_color): + html_styles.append('background-color: #' + background_color) + else: + html_classes.append('g-AnsiBackground' + background_color) + + i = ansi_class.find('ForegroundColor') + if i >= 0: + foreground_color = ansi_class[i + 15:] + ansi_class = ansi_class[:i] + html_styles.insert(0, 'color: #' + foreground_color) + + if ansi_class != 'g-Ansi': + html_classes.insert(1, ansi_class) + + result = '' + if len(html_classes) > 1: # we don't want to emit just g + result = 'class="' + ' '.join(html_classes) + '"' + + if html_styles: + if result: + result += ' ' + result += 'style="' + '; '.join(html_styles) + '"' + + return result diff --git a/plugins/m/test/code/console-colors.ansi b/plugins/m/test/code/console-colors.ansi index ccd327f6..c17093c7 100644 --- a/plugins/m/test/code/console-colors.ansi +++ b/plugins/m/test/code/console-colors.ansi @@ -1,5 +1,99 @@ -██ ██ ██ ██ ██ ▓▓ ▒▒ +Named foreground colors: + Black Red Green Yellow Blue Magenta Cyan White Default + BrightBlack BrightRed BrightGreen BrightYellow + BrightBlue BrightMagenta BrightCyan BrightWhite -Leading zeros: ▒▒ ▒▒ +RGB foreground colors: + 91,157,217 157,217,91 217,91,157 -    ░░ ▒▒ ▓▓ ██ +Palette-based foreground colors: +  0  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15 +  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31 +  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47 +  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63 +  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79 +  80  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95 +  96  97  98  99 100 101 102 103 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 + +Reset undoes foreground color + Green Reset + Red Reset, with implicit '0' + +Reset or normal intensity undo brightness + Bright Reset + Bright Normal intensity + +Non-bright named foreground colors and brightness stack  + Bright and Yellow foreground in one Sequence + Yellow foreground and Bright in one Sequence + Bright Sequence and Yellow foreground Sequence + Yellow foreground Sequence and Bright Sequence + +Bright named foreground colors do not heed or change brightness flag, +nor do RGB or palette-based colors + Bright BrightGreen (still bright) Green + Default BrightGreen Green + Bright palette 9 (still bright) Blue palette 9 + Blue palette 9 Blue palette 9 + Bright rgb(255,255,0) (still bright) Blue rgb(255,255,0) + Blue rgb(255,255,0) Blue rgb(255,255,0) + +Named background colors: + Black Red Green Yellow Blue Magenta Cyan White Default + BrightBlack BrightRed BrightGreen BrightYellow + BrightBlue BrightMagenta BrightCyan BrightWhite + +RGB background colors: + 91,157,217 157,217,91 217,91,157 + +Palette-based background colors: +  0  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15 +  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31 +  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47 +  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63 +  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79 +  80  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95 +  96  97  98  99 100 101 102 103 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 + +Background colors do not heed or change brightness flag + Bright BrightGreen Green + BrightGreen Black + +Foreground and background colors stack: + Blue on Yellow + Palette 12 on BrightYellow + White on Palette 88 + BrightWhite on RGB 128,0,128 + RGB 0,128,128 on RGB 0,128,128 + RGB 192,192,0 on RGB 0,128,128 + +Other commands are ignored + half-bright + set underscore + set blink + set reverse video + reset selected mapping, display control flag, and toggle + select null mapping, set display control flag, reset + select null mapping, set display control flag, set toggle + set underline + underline off + blink off + reverse video off diff --git a/plugins/m/test/code/page.html b/plugins/m/test/code/page.html index a9f95582..910e75c3 100644 --- a/plugins/m/test/code/page.html +++ b/plugins/m/test/code/page.html @@ -39,11 +39,105 @@ ASan reports: =>0x0c287fff8030: 00[fc]fc fc fc fc fc fc fc fc fc fa fa fa fa fa

Console colors:

-
██ ██ ██ ██ ██ ▓▓ ▒▒
+
Named foreground colors:
+  Black Red Green Yellow Blue Magenta Cyan White Default
+  BrightBlack BrightRed BrightGreen BrightYellow
+  BrightBlue BrightMagenta BrightCyan BrightWhite
 
-Leading zeros: ▒▒ ▒▒
+RGB foreground colors:
+  91,157,217 157,217,91 217,91,157
 
-      ░░ ▒▒ ▓▓ ██
+Palette-based foreground colors: + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 + +Reset undoes foreground color + Green Reset + Red Reset, with implicit '0' + +Reset or normal intensity undo brightness + Bright Reset + Bright Normal intensity + +Non-bright named foreground colors and brightness stack + Bright and Yellow foreground in one Sequence + Yellow foreground and Bright in one Sequence + Bright Sequence and Yellow foreground Sequence + Yellow foreground Sequence and Bright Sequence + +Bright named foreground colors do not heed or change brightness flag, +nor do RGB or palette-based colors + Bright BrightGreen (still bright) Green + Default BrightGreen Green + Bright palette 9 (still bright) Blue palette 9 + Blue palette 9 Blue palette 9 + Bright rgb(255,255,0) (still bright) Blue rgb(255,255,0) + Blue rgb(255,255,0) Blue rgb(255,255,0) + +Named background colors: + Black Red Green Yellow Blue Magenta Cyan White Default + BrightBlack BrightRed BrightGreen BrightYellow + BrightBlue BrightMagenta BrightCyan BrightWhite + +RGB background colors: + 91,157,217 157,217,91 217,91,157 + +Palette-based background colors: + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 + +Background colors do not heed or change brightness flag + Bright BrightGreen Green + BrightGreen Black + +Foreground and background colors stack: + Blue on Yellow + Palette 12 on BrightYellow + White on Palette 88 + BrightWhite on RGB 128,0,128 + RGB 0,128,128 on RGB 0,128,128 + RGB 192,192,0 on RGB 0,128,128 + +Other commands are ignored + half-bright + set underscore + set blink + set reverse video + reset selected mapping, display control flag, and toggle + select null mapping, set display control flag, reset + select null mapping, set display control flag, set toggle + set underline + underline off + blink off + reverse video off
// this language is not highlighted

Properly preserve backslashes: \frac{a}{b} ... and backticks: :ref:`a function <os.path.join()>`