diff mbox series

[1/2] wwwdocs: Add bin/gcc-color-to-html.py

Message ID 1522865087-39444-2-git-send-email-dmalcolm@redhat.com
State New
Headers show
Series wwwdocs: Updates for gcc 8 changes (v2) | expand

Commit Message

David Malcolm April 4, 2018, 6:04 p.m. UTC
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

Comments

Gerald Pfeifer April 4, 2018, 7:01 p.m. UTC | #1
On Wed, 4 Apr 2018, David Malcolm wrote:
> 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)?

Oh, yes!

Really nice.  

(You may want to identify yourself as the author, "Contributed by 
David Malcolm, and would you like to contribute as "Copyright (C) 
2018 Free Software Foundation, Inc."?  Full GPL may be a bit of
overkill, but of course also a good option.)

Gerald
Gerald Pfeifer April 4, 2018, 7:53 p.m. UTC | #2
On Wed, 4 Apr 2018, David Malcolm wrote:
> I've committed it to CVS, with the following changes:

Lovely, thank you!

Gerald
David Malcolm April 4, 2018, 7:58 p.m. UTC | #3
On Wed, 2018-04-04 at 21:01 +0200, Gerald Pfeifer wrote:
> On Wed, 4 Apr 2018, David Malcolm wrote:
> > 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)?
> 
> Oh, yes!
> 
> Really nice.  

Thanks.

> (You may want to identify yourself as the author, "Contributed by 
> David Malcolm, and would you like to contribute as "Copyright (C) 
> 2018 Free Software Foundation, Inc."?  Full GPL may be a bit of
> overkill, but of course also a good option.)

I've committed it to CVS, with the following changes:

 bin/gcc-color-to-html.py | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/bin/gcc-color-to-html.py b/bin/gcc-color-to-html.py
index 160d345..0d97ead 100755
--- a/bin/gcc-color-to-html.py
+++ b/bin/gcc-color-to-html.py
@@ -1,4 +1,23 @@
 #!/usr/bin/python3
+#
+# Copyright (C) 2018 Free Software Foundation, Inc.
+#
+# Contributed by David Malcolm
+#
+# GCC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
 import html
 import re
 import sys
diff mbox series

Patch

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 &#x27;<span class="bold">test</span>&#x27;:\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>&#x27;<span class="bold">NULL</span>&#x27; undeclared')
+
+    def test_escaping(self):
+        self.assert_html("#include <stdio.h>", "#include &lt;stdio.h&gt;")
+
+if len(sys.argv) > 1:
+    sys.exit(unittest.main())
+
+for line in sys.stdin:
+    line = ansi_to_html(line)
+    sys.stdout.write(line)