This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH 1/2] wwwdocs: Add bin/gcc-color-to-html.py
- From: David Malcolm <dmalcolm at redhat dot com>
- To: Gerald Pfeifer <gerald at pfeifer dot com>
- Cc: gcc-patches at gcc dot gnu dot org, David Malcolm <dmalcolm at redhat dot com>
- Date: Wed, 4 Apr 2018 14:04:46 -0400
- Subject: [PATCH 1/2] wwwdocs: Add bin/gcc-color-to-html.py
- References: <alpine.LSU.2.21.1803182357560.3430@anthias.pfeifer.com> <1522865087-39444-1-git-send-email-dmalcolm@redhat.com>
Here's the new script I've been using for converting from diagnostic-color.c
output to HTML spans that use gcc.css, via something like:
LANG=C gcc $@ -fdiagnostics-color=always 2>&1
| ./bin/gcc-color-to-html.py
The script converts SGR_SEQ(COLOR_BOLD) to a
<span class="bold">
rather than
<b>
so that it can use
</span>
for all SGR_RESET, without needing to track the nesting.
OK to commit to the website (for reference)?
---
bin/gcc-color-to-html.py | 98 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 98 insertions(+)
create mode 100755 bin/gcc-color-to-html.py
diff --git a/bin/gcc-color-to-html.py b/bin/gcc-color-to-html.py
new file mode 100755
index 0000000..160d345
--- /dev/null
+++ b/bin/gcc-color-to-html.py
@@ -0,0 +1,98 @@
+#!/usr/bin/python3
+import html
+import re
+import sys
+import unittest
+
+# Colors from gcc/color-macros.h:
+
+COLOR_SEPARATOR = ";"
+COLOR_NONE = "00"
+COLOR_BOLD = "01"
+COLOR_UNDERSCORE = "04"
+COLOR_BLINK = "05"
+COLOR_REVERSE = "07"
+COLOR_FG_BLACK = "30"
+COLOR_FG_RED = "31"
+COLOR_FG_GREEN = "32"
+COLOR_FG_YELLOW = "33"
+COLOR_FG_BLUE = "34"
+COLOR_FG_MAGENTA = "35"
+COLOR_FG_CYAN = "36"
+COLOR_FG_WHITE = "37"
+COLOR_BG_BLACK = "40"
+COLOR_BG_RED = "41"
+COLOR_BG_GREEN = "42"
+COLOR_BG_YELLOW = "43"
+COLOR_BG_BLUE = "44"
+COLOR_BG_MAGENTA = "45"
+COLOR_BG_CYAN = "46"
+COLOR_BG_WHITE = "47"
+
+SGR_START = "\33["
+SGR_END = "m\33[K"
+
+def SGR_SEQ(str):
+ return SGR_START + str + SGR_END
+
+SGR_RESET = SGR_SEQ("")
+
+def ansi_to_html(text):
+ text = html.escape(text)
+ pattern = ('(' + re.escape(SGR_START) + ')'
+ + '(.*?)'
+ + '(' + re.escape(SGR_END) + ')')
+ while True:
+ m = re.search(pattern, text)
+ if not m:
+ break
+ sgr_seq = m.group(2)
+ if sgr_seq == COLOR_BOLD:
+ replacement = '<span class="bold">'
+ elif sgr_seq == COLOR_FG_RED:
+ replacement = '<span class="red">'
+ elif sgr_seq == COLOR_FG_GREEN:
+ replacement = '<span class="green">'
+ elif sgr_seq == COLOR_FG_BLUE:
+ replacement = '<span class="blue">'
+ elif sgr_seq == '':
+ replacement = '</span>'
+ elif sgr_seq == COLOR_BOLD + COLOR_SEPARATOR + COLOR_FG_RED:
+ replacement = '<span class="boldred">'
+ elif sgr_seq == COLOR_BOLD + COLOR_SEPARATOR + COLOR_FG_GREEN:
+ replacement = '<span class="boldgreen">'
+ elif sgr_seq == COLOR_BOLD + COLOR_SEPARATOR + COLOR_FG_CYAN:
+ replacement = '<span class="boldcyan">'
+ elif sgr_seq == COLOR_BOLD + COLOR_SEPARATOR + COLOR_FG_MAGENTA:
+ replacement = '<span class="boldmagenta">'
+ else:
+ raise ValueError('unknown SGR_SEQ code: %r' % sgr_seq)
+ text = text[:m.start(1)] + replacement + text[m.end(3):]
+ return text
+
+class AnsiToHtmlTests(unittest.TestCase):
+ def assert_html(self, ansi_text, expected_html):
+ html = ansi_to_html(ansi_text)
+ self.assertMultiLineEqual(html, expected_html)
+
+ def test_simple(self):
+ self.assert_html('', '')
+ self.assert_html('plain text', 'plain text')
+
+ def test_filename(self):
+ self.assert_html("\x1b[01m\x1b[Kfilename.c:\x1b[m\x1b[K In function '\x1b[01m\x1b[Ktest\x1b[m\x1b[K':\n",
+ '<span class="bold">filename.c:</span> In function '<span class="bold">test</span>':\n')
+
+ def test_error(self):
+ self.assert_html("\x1b[01;31m\x1b[Kerror: \x1b[m\x1b[K'\x1b[01m\x1b[KNULL\x1b[m\x1b[K' undeclared",
+ '<span class="boldred">error: </span>'<span class="bold">NULL</span>' undeclared')
+
+ def test_escaping(self):
+ self.assert_html("#include <stdio.h>", "#include <stdio.h>")
+
+if len(sys.argv) > 1:
+ sys.exit(unittest.main())
+
+for line in sys.stdin:
+ line = ansi_to_html(line)
+ sys.stdout.write(line)
--
1.8.5.3