wwwdocs: port from MetaHTML to a Python 3 script

Message ID 1528146493-29692-1-git-send-email-dmalcolm@redhat.com
State New
Headers show
Series
  • wwwdocs: port from MetaHTML to a Python 3 script
Related show

Commit Message

David Malcolm June 4, 2018, 9:08 p.m.
On Sat, 2018-06-02 at 13:27 +0200, Gerald Pfeifer wrote:
> On Mon, 14 May 2018, Martin Sebor wrote:

> > > Martin, what do you think?  Would that have avoided the

> > > challenges

> > > your ran into?  Anything to better clarify or otherwise improve?

> >

> > Thanks for the improvement!  I think it will help going forward

>

> Great, I (finally) committed this now, business travel not exactly

> having been helpful with my GCC engagements...

>

> > assuming one knows about the page and remembers to check it.

> > I have to confess I forgot about it so I didn't check it before

> > running the validator the last time.  Would it be possible to add

> > the snippet to each page permanently?

>

> You mean, avoiding preprocessing and making the change permanent,

> directly as part of every .html file?

>

> I've been hesitant doing that to keep things simple and easier to

> change (and not bother folks), but think this makes sense and plan

> on doing that as we migrate our pages to HTML 5 which will

> drastically

> reduce the size of that snippet also.  I expect to find time to do

> so in the coming few months, and things should indeed be simpler

> than.

>

>

> One improvement I just made is to add a reference to

>   https://gcc.gnu.org/about.html

> to the automated checker that runs after each commit.  That provides

> more background then.

>

> > Alternatively, what do you think of the idea to have a script (or

> > makefile) to post-process changes to these pages on the client

> > side,

> > before checking them in?  I.e., adding the example annotation David

> > Malcolm prefers (black background) and also validating the HTML).

>

> That's a great idea.  Sadly our post-processing relies on MetaHTML,

> a GNU projects that was handled in, umm, a less than optimal manner,

> and has been in coma for years and thus does not build with current

> compilers on current operating system versions.

>

> At least GCC Summit in Praha David and me chatted about it, and he

> was thinking to (re)implement the key functionality we use in Python,

> so let me include him here.

>

> (In any case, with the move to CSS and the forthcoming move to HTML 5

> that dependency has been and will be reducing over time.)

>

> Gerald


Caveat/confession: I've never managed to successfully build MetaHTML,
so I've never run it.  All of my editing of the GCC website has involved
looking at the input HTML locally, hacking up the header so that the W3C
validator can run on it, then committing (and crossing my fingers).

Here's an attempt at porting the website from MetaHTML to a Python 3
script.  I've tested it lightly so far by comparing it to reference
pages from the built site (index.html, c99status.html, and install/test.html
so far).

It's not particularly elegant Python 3 (though it does have unit tests!),
and the parsing is a kludge (but seems good enough).  The goal is purely
to drop our dependency on MetaHTML so that all of the logic is expressed
in a well-supported, living programming language.  It has no dependencies
besides Python 3 (tested with 3.3.2).  It might even work with Python 2.

Does this look like the right idea?  (it's not quite perfect yet, but
is pretty close for the pages I tested on).

Are there any other pages which have their own uses of MetaHTML that I
didn't spot yet?

For now, I've attempted to faithfully reproduce the strange whitespace that
MetaHTML introduces, to make it easier to compare diffs.  A followup would
be to remove that, to give more natural whitespace (thus keeping the
whitespace changes separated from non-whitespace changes, as it were).

Dave
---
 bin/preprocess           |  24 ++--
 bin/process-html-file.py | 321 +++++++++++++++++++++++++++++++++++++++++++++++
 htdocs/style.mhtml       | 223 --------------------------------
 3 files changed, 329 insertions(+), 239 deletions(-)
 create mode 100755 bin/process-html-file.py
 delete mode 100644 htdocs/style.mhtml

-- 
1.8.5.3

Comments

Gerald Pfeifer June 11, 2018, 5:49 a.m. | #1
Hi David,

On Mon, 4 Jun 2018, David Malcolm wrote:
> Caveat/confession: I've never managed to successfully build MetaHTML,

> so I've never run it.


yes, it's become increasingly difficult to build given how it's
been abandoned unfortunately (which is something I had brought up
with RMS even twice or so).  Hence increasingly a bit of a burning
platform to move away from.

> Here's an attempt at porting the website from MetaHTML to a Python 3

> script.


This is great!  Thank you for doing this.

> I've tested it lightly so far by comparing it to reference pages from 

> the built site (index.html, c99status.html, and install/test.html so 

> far).


Can you also give something like gcc-8/*.html a try?  In between those
you pointed out and these I feel pretty comfortable about us having good
coverage.

> Does this look like the right idea?  (it's not quite perfect yet, but

> is pretty close for the pages I tested on).


It's more procedural, when in principle declarative is nicer, *but*
clearly something that works for everyone (who has Python) and is
maintainable is a big step forward.  And, heck, I may get to learn
a bit of Python on the way. ;-)

> Are there any other pages which have their own uses of MetaHTML that 

> I didn't spot yet?


I cannot think of any; not with some of my recent (and not so recent)
changes to push things to CSS and otherwise.

> For now, I've attempted to faithfully reproduce the strange whitespace that

> MetaHTML introduces, to make it easier to compare diffs.  A followup would

> be to remove that, to give more natural whitespace (thus keeping the

> whitespace changes separated from non-whitespace changes, as it were).


What do you think of simplifying this such that `diff -w -B` aka
`diff --ignore-all-space --ignore-blank-lines` doesn't flag anything?

That would be a way towards more natural whitespace as you refer to,
and from my parsing of the Python code would make things a bit easier?


Two small questions: given the main script is bin/preprocess, would 
it be okay to call the new one bin/preprocess-html-file instead of 
bin/process-html-file.py ?  And possibly omit the .py to "hide" this 
implementation detail?


Last weekend I started to think how to move nearly everything to HTML 5 
(and as you may have seen started to patch in that direction) and devise
a way to handle that in the framework with minimal effort.  

However, now that you have gone to the effort of creating this script,
I am wondering whether we should simply do a flag day and switch to your
script as quickly as possible, even before that transition is complete.

What do you think?

Gerald (on business travel last week and most of the next two, 
	but trying to keep up by e-mail).

Patch

diff --git a/bin/preprocess b/bin/preprocess
index 2d09d54..f894af4 100755
--- a/bin/preprocess
+++ b/bin/preprocess
@@ -33,11 +33,11 @@ 
 #
 # By Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> 1999-12-29.
 
-MHC=${MHC-/usr/local/bin/mhc}
-
 SOURCETREE=${SOURCETREE-/www/gcc/htdocs-preformatted}
 DESTTREE=${DESTTREE-/www/gcc/htdocs}
 
+BINDIR=${SOURCETREE}/../bin
+
 STYLE=$SOURCETREE/style.mhtml
 IGNORE_DIFF_MARKER="IGNORE DIFF"
 
@@ -102,29 +102,26 @@  process_html_file()
     fdest=$2
 
     # Set environment variable PREPROCESS_FILE, which will then be
-    # accessible by MetaHTML.
+    # accessible by bin/process-html-file.py.
 
     PREPROCESS_FILE=$f
     export PREPROCESS_FILE
 
-    # Prepend the MetaHTML style, set the MetaHTML include directory,
+    # Prepend the MetaHTML include directory,
     # and process the page.
-
-    cat $STYLE > $TMPDIR/input
     printf '<set-var MHTML::INCLUDE-PREFIX="%s">\n' `pwd` >> $TMPDIR/input
     cat $f >> $TMPDIR/input
 
-    if ! ${MHC} $TMPDIR/input > $TMPDIR/output.raw; then
-        echo "${MHC} failed; aborting."
+    # Process the page.
+    if ! $BINDIR/process-html-file.py $TMPDIR/input > $TMPDIR/output.raw; then
+        echo "$BINDIR/process-html-file.py failed; aborting."
         exit 1
     fi
 
     # Use sed to work around makeinfo 4.7 brokenness.
-    # Use sed to work around MetaHTML brokenness wrt. <DIV>.
     # Then remove leading blank lines and single line comments.
     cat $TMPDIR/output.raw \
         | sed -e 's/_002d/-/g' -e 's/_002a/*/g' \
-        | sed -e 's/<DIV/<div/g' \
         | awk -- \
           '/^( *)?$/      { if( ! body ) next } \
            /^<!--.*-->$/  { if( ! body ) next } \
@@ -132,7 +129,7 @@  process_html_file()
         > $TMPDIR/output
 
     # Copy the page only if it's new or there has been a change, and,
-    # first of all, if there was no problem when running MetaHTML.
+    # first of all, if there was no problem when running process-html-file.py
     if [ $? -ne 0 ]; then
         echo "  Problem processing $f; not updated!"
     elif [ ! -f $fdest ]; then
@@ -221,11 +218,6 @@  shift `expr ${OPTIND} - 1`
 
 ## Various safety checks.
 
-if ! ${MHC} --version >/dev/null; then
-    echo "Something does not look right with \"${MHC}\"; aborting."
-    exit 1
-fi
-
 if [ ! -d $SOURCETREE ]; then
     echo "Source tree \"$SOURCETREE\" does not exist."
     exit 1
diff --git a/bin/process-html-file.py b/bin/process-html-file.py
new file mode 100755
index 0000000..8296189
--- /dev/null
+++ b/bin/process-html-file.py
@@ -0,0 +1,321 @@ 
+#!/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 datetime
+import os
+import re
+import sys
+import unittest
+
+NAVIGATION_FOOTER = """
+  </td>                                            <!-- end of main frame -->
+
+  <td valign="top">                                        <!-- nav frame -->
+  <table class="nav" border="0" cellpadding="2" width="10em">
+
+  <tr><td><table class="navitem" width="100%">
+  <tr><td>About GCC</td></tr>
+  <tr><td>
+  <a href="<get-var BACKPATH>gccmission.html">Mission Statement</a><br />
+  <a href="<get-var BACKPATH>releases.html">Releases</a><br />
+  <a href="<get-var BACKPATH>snapshots.html">Snapshots</a><br />
+  <a href="<get-var BACKPATH>lists.html">Mailing lists</a><br />
+  <a href="https://gcc.gnu.org/onlinedocs/gcc/Contributors.html">Contributors</a><br />
+  <a href="<get-var BACKPATH>steering.html">Steering Committee</a><br />
+  <div align="center">
+  <a href="https://twitter.com/gnutools">
+    <img src="<get-var BACKPATH>twitter-bird-light-bgs.png"
+      height="42" width="42" align="middle" alt="@gnutools on Twitter"
+      />@gnutools</a>
+  </div>
+  <div align="center">
+  <a href="https://plus.google.com/108467477471815191158">
+    <img src="<get-var BACKPATH>gplus-32.png"
+      height="24" width="24" align="middle" alt="gnutools on Google+"
+      />  gnutools</a>
+  </div>
+  <div align="center">
+  <a href="https://my.fsf.org/civicrm/contribute/transact?reset=1&amp;id=57">
+    <img src="<get-var BACKPATH>donate-110-23.png"
+      height="23" width="100" align="middle" alt="Donate to GNU Toolchain Fund"
+      /></a>
+  </div>
+  </td></tr>
+  </table></td></tr>
+
+  <tr><td><table class="navitem" width="100%">
+  <tr><td>Documentation</td></tr>
+  <tr><td>
+  <a href="https://gcc.gnu.org/install/">Installation</a><br />
+  &middot;&nbsp;<a href="https://gcc.gnu.org/install/specific.html">Platforms</a><br />
+  <a href="<get-var BACKPATH>onlinedocs/">Manual</a><br />
+  <a href="<get-var BACKPATH>faq.html">FAQ</a><br />
+  <a href="https://gcc.gnu.org/wiki">Wiki</a><br />
+  <a href="<get-var BACKPATH>readings.html">Pointers</a>
+  </td></tr>
+  </table></td></tr>
+ 
+  <tr><td><table class="navitem" width="100%">
+  <tr><td>Download</td></tr>
+  <tr><td>
+  <a href="<get-var BACKPATH>mirrors.html">Mirrors</a><br />
+  <a href="https://gcc.gnu.org/install/binaries.html">Binaries</a>
+  </td></tr>
+  </table></td></tr>
+
+  <tr><td><table class="navitem" width="100%">
+  <tr><td>Sources</td></tr>
+  <tr><td>
+  <a href="<get-var BACKPATH>svn.html">SVN read access</a><br />
+  <a href="<get-var BACKPATH>svnwrite.html">SVN write access</a><br />
+  <a href="https://gcc.gnu.org/wiki/GitMirror">Git read access</a><br />
+  <a href="<get-var BACKPATH>rsync.html">Rsync</a><br />
+  </td></tr>
+  </table></td></tr>
+
+  <tr><td><table class="navitem" width="100%">
+  <tr><td>Development</td></tr>
+  <tr><td>
+  <a href="<get-var BACKPATH>develop.html">Development Plan</a><br />
+  &middot;&nbsp;<a href="<get-var BACKPATH>develop.html#timeline">Timeline</a><br />
+  <a href="<get-var BACKPATH>contribute.html">Contributing</a><br />
+  <a href="<get-var BACKPATH>contributewhy.html">Why&nbsp;contribute?</a><br />
+  <a href="<get-var BACKPATH>projects/">Open projects</a><br />
+  <a href="<get-var BACKPATH>frontends.html">Front ends</a><br />
+  <a href="<get-var BACKPATH>backends.html">Back ends</a><br />
+  <a href="<get-var BACKPATH>extensions.html">Extensions</a><br />
+  <a href="<get-var BACKPATH>benchmarks/">Benchmarks</a><br />
+  <a href="http://toolchain.lug-owl.de/buildbot/">Build Robot</a><br />
+  <a href="<get-var BACKPATH>translation.html">Translations</a><br />
+  </td></tr>
+  </table></td></tr>
+
+  <tr><td><table class="navitem" width="100%">
+  <tr><td>Bugs</td></tr>
+  <tr><td>
+  <a href="<get-var BACKPATH>bugs/#known">Known bugs</a><br />
+  <a href="<get-var BACKPATH>bugs/">How to report</a><br />
+  <a href="https://gcc.gnu.org/bugzilla/">Bug&nbsp;tracker</a><br />
+  &middot;&nbsp;<a href="<get-var BACKPATH>bugs/management.html">Management</a>
+  </td></tr>
+  </table></td></tr>
+
+  </table>
+  </td>                                             <!-- end of nav frame -->
+
+  </tr>
+  </table>
+ 
+"""
+
+FOOTER = """
+<!-- ==================================================================== -->
+
+<div class="copyright">
+
+<address>For questions related to the use of GCC,
+please consult these web pages and the
+<a href="https://gcc.gnu.org/onlinedocs/">GCC manuals</a>. If that fails,
+the <a href="mailto:gcc-help@gcc.gnu.org">gcc-help@gcc.gnu.org</a>
+mailing list might help.
+Comments on these web pages and the development of GCC are welcome on our
+developer list at <a href="mailto:gcc@gcc.gnu.org">gcc@gcc.gnu.org</a>.
+All of <a href="https://gcc.gnu.org/lists.html">our lists</a>
+have public archives.
+</address>
+
+<p>Copyright (C)
+<a href="https://www.fsf.org">Free Software Foundation, Inc.</a>
+Verbatim copying and distribution of this entire article is
+permitted in any medium, provided this notice is preserved.</p>
+
+<p>These pages are
+<a href="https://gcc.gnu.org/about.html">maintained by the GCC team</a>.
+Last modified <date::format-time "YYYY-MM-DD"><!-- IGNORE DIFF
+--><a href="http://validator.w3.org/check/referer">.</a></p>
+
+</div>
+
+<!-- ==================================================================== -->
+
+"""
+
+def process(src_content, src_filename):
+    """
+    Given SRC_CONTENT, the input HTML page, return a string containing
+    the final HTML to be written out to be served.
+    """
+    xhtml = True
+    backpath = ''
+
+    # The "install/" pages are HTML, not XHTML.
+    if src_filename.startswith('install/'):
+        xhtml = False
+
+    # Strip out MetaHTML directives
+    include_prefix = None
+
+    m = re.match('<set-var MHTML::INCLUDE-PREFIX="(.*)">', src_content)
+    if m:
+        include_prefix = m.group(1)
+        src_content = src_content[:m.start()] + src_content[m.end():]
+
+    if '<set-var navigation>' in src_content:
+        navigation = True
+        src_content = src_content.replace('<set-var navigation>', '')
+    else:
+        navigation = False
+
+    if '<include searchbox.ihtml>' in src_content:
+        with open(os.path.join(include_prefix, 'searchbox.ihtml')) as f:
+            included_content = f.read()
+        src_content = src_content.replace('<include searchbox.ihtml>', included_content)
+
+    if xhtml:
+        dst_content = ('<?xml version="1.0" encoding="utf-8"?>\n'
+                       '  <!DOCTYPE html\n'
+                       '            PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"\n'
+                       '            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n'
+                       ' \n\n\n \n' + ('\n' * 9))
+    else:
+        dst_content = ('  <?xml version="1.0" encoding="utf-8"?>\n'
+                       '  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\n'
+                       ' \n' + ('\n' * 13))
+
+    for line in src_content.splitlines():
+        if xhtml:
+            # Redefine the <html> tag so that we can put XHTML attributes inside.
+            if line == '<html>':
+                dst_content += '     <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n  \n'
+                continue
+            if line == '</html>':
+                dst_content += '     </html>\n  \n '
+                continue
+
+        # Redefine the <head> tag so that we can add default <meta /> headers.
+        if line == '<head>':
+            if navigation:
+                dst_content += '  '
+            else:
+                dst_content += '  \n'
+            if xhtml:
+                dst_content += \
+                    ('   <head>\n'
+                     ' \n'
+                     '    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />\n'
+                     '    <link rel="shortcut icon" href="https://gcc.gnu.org/favicon.ico" />\n'
+                     '  \n ')
+            else:
+                dst_content += \
+                    ('   <head>\n'
+                     ' \n'
+                     '    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">\n'
+                     '    <link rel="shortcut icon" href="https://gcc.gnu.org/favicon.ico">\n'
+                     '    <link rel="stylesheet" type="text/css" href="/gcc.css">\n')
+            continue
+        if line == '</head>':
+            dst_content += '   </head>\n \n'
+            continue
+
+        # Redefine the <title> tag to comply with the GNU style.
+        m = re.match('<title>(.*)</title>', line)
+        if m:
+            dst_content += ('<title>\n'
+                            + m.group(1) + '\n'
+                            + '- GNU Project - Free Software Foundation (FSF)</title>\n')
+            continue
+
+        # Stay faithful to what MetaHTML emitted:
+        if line == '<div>':
+            line = '<div >'
+
+        # Redefine the <body> tag, adding navigation and a standard footer.
+        if line == '<body>':
+            if navigation:
+                dst_content += \
+                    ('<body>\n'
+                     '\n'
+                     '  <table border="0" cellspacing="0" cellpadding="2">\n'
+                     '  <tr>\n'
+                     '\n'
+                     '  <td valign="top" width="99%">                           <!-- main frame -->\n \n\n')
+                continue
+            else:
+                dst_content += '<body>\n\n\n\n'
+                continue
+        if line == '</body>':
+            if navigation:
+                dst_content += NAVIGATION_FOOTER.replace('<get-var BACKPATH>', backpath)
+            else:
+                dst_content += '\n\n'
+            if '<date::format-time "YYYY-MM-DD">' in FOOTER:
+                dst_content += FOOTER.replace('<date::format-time "YYYY-MM-DD">',
+                                              datetime.date.today().isoformat())
+
+        dst_content += line + '\n'
+
+
+    return dst_content
+
+class Tests(unittest.TestCase):
+    def test_xhtml_head(self):
+        dst_content = process('<head>\n</head>\n', 'not-in-install.html')
+        self.assertTrue(dst_content.startswith('<?xml version="1.0" encoding="utf-8"?>'))
+
+    def test_html_head(self):
+        dst_content = process('<head>\n</head>\n', 'install/foo.html')
+        self.assertTrue(dst_content.startswith('  <?xml version="1.0" encoding="utf-8"?>'))
+
+    def test_title(self):
+        dst_content = process('<title>Foo</title>\n', 'not-in-install.html')
+        self.assertIn('<title>\n'
+                      'Foo\n'
+                      '- GNU Project - Free Software Foundation (FSF)</title>\n', dst_content)
+
+        self.assertTrue(dst_content.startswith('<?xml version="1.0" encoding="utf-8"?>'))
+
+    def test_footer(self):
+        dst_content = process('<body>\n</body>\n', 'not-in-install.html')
+        self.assertIn('<p>These pages are', dst_content)
+
+    def test_include(self):
+        dst_content = process('<set-var MHTML::INCLUDE-PREFIX="../htdocs">\n<include searchbox.ihtml>\n',
+                              'not-in-install.html')
+        self.assertNotIn('<include', dst_content)
+        self.assertIn('search.cgi', dst_content)
+
+    def test_navigation(self):
+        dst_content = process('<set-var navigation>\n<body>\n</body>\n', 'not-in-install.html')
+        self.assertIn('<!-- main frame -->', dst_content)
+        self.assertIn('<!-- end of nav frame -->', dst_content)
+
+def main():
+    # Expect either "--unittest", or an input filename
+    if sys.argv[1] == '--unittest':
+        sys.argv = [sys.argv[0]] + sys.argv[2:]
+        unittest.main()
+        return
+    src_filename = sys.argv[1]
+    with open(src_filename) as infile:
+        src_content = infile.read()
+        dst_content = process(src_content, src_filename)
+        print(dst_content)
+
+main()
diff --git a/htdocs/style.mhtml b/htdocs/style.mhtml
deleted file mode 100644
index 1bad660..0000000
--- a/htdocs/style.mhtml
+++ /dev/null
@@ -1,223 +0,0 @@ 
-;;; Set a couple of site-wide defaults, some of which we'll override in the
-;;; following.
-
-<set-var XHTML>
-<set-var BACKPATH>
-
-;;; The "install/" pages are HTML, not XHTML.
-
-<if <match <get-var env::PREPROCESS_FILE> "install/.*">
-  <unset-var XHTML>
->
-
-;;; Note that the <?xml...> line really needs to start in the first column.
-
-<if <var-exists XHTML>
- <group
-<?xml version="1.0" encoding="utf-8"?>
-  <!DOCTYPE html
-            PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- >
- <group
-  <?xml version="1.0" encoding="utf-8"?>
-  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- >
->
-
-;;; Redefine the <html> tag so that we can put XHTML attributes inside.
-
-<if <var-exists XHTML>
- <group <define-container html>
-  <verbatim>
-   <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-  </verbatim>
-  %body
-  <verbatim>
-   </html>
-  </verbatim>
- </define-container> >
->
-
-;;; Redefine the <head> tag so that we can add default <meta /> headers.
-
-<define-container head>
- <verbatim>
-  <head>
- </verbatim>
- <if <var-exists XHTML>
-  <group
-   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <link rel="shortcut icon" href="https://gcc.gnu.org/favicon.ico" />
-  >
-  <group
-   <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-    <link rel="shortcut icon" href="https://gcc.gnu.org/favicon.ico">
-    <link rel="stylesheet" type="text/css" href="/gcc.css">
-  >
- >
- %body
- <verbatim>
-  </head>
- </verbatim>
-</define-container>
-
-;;; Redefine the <title> tag to comply with the GNU style.
-
-<define-container title>
-<verbatim><title></verbatim>
-%body
-<verbatim>- GNU Project - Free Software Foundation (FSF)</title></verbatim>
-</define-container>
-
-;;; Redefine the <body> tag, adding navigation and a standard footer.
-
-<define-container body>
-<verbatim><body></verbatim>
-
-<if <var-exists navigation>
- <group
-  <table border="0" cellspacing="0" cellpadding="2">
-  <tr>
-
-  <td valign="top" width="99%">                           <!-- main frame -->
- >
->
-
-%body
-
-<if <var-exists navigation>
- <group
-  </td>                                            <!-- end of main frame -->
-
-  <td valign="top">                                        <!-- nav frame -->
-  <table class="nav" border="0" cellpadding="2" width="10em">
-
-  <tr><td><table class="navitem" width="100%">
-  <tr><td>About GCC</td></tr>
-  <tr><td>
-  <a href="<get-var BACKPATH>gccmission.html">Mission Statement</a><br />
-  <a href="<get-var BACKPATH>releases.html">Releases</a><br />
-  <a href="<get-var BACKPATH>snapshots.html">Snapshots</a><br />
-  <a href="<get-var BACKPATH>lists.html">Mailing lists</a><br />
-  <a href="https://gcc.gnu.org/onlinedocs/gcc/Contributors.html">Contributors</a><br />
-  <a href="<get-var BACKPATH>steering.html">Steering Committee</a><br />
-  <div align="center">
-  <a href="https://twitter.com/gnutools">
-    <img src="<get-var BACKPATH>twitter-bird-light-bgs.png"
-      height="42" width="42" align="middle" alt="@gnutools on Twitter"
-      />@gnutools</a>
-  </div>
-  <div align="center">
-  <a href="https://plus.google.com/108467477471815191158">
-    <img src="<get-var BACKPATH>gplus-32.png"
-      height="24" width="24" align="middle" alt="gnutools on Google+"
-      />  gnutools</a>
-  </div>
-  <div align="center">
-  <a href="https://my.fsf.org/civicrm/contribute/transact?reset=1&amp;id=57">
-    <img src="<get-var BACKPATH>donate-110-23.png"
-      height="23" width="100" align="middle" alt="Donate to GNU Toolchain Fund"
-      /></a>
-  </div>
-  </td></tr>
-  </table></td></tr>
-
-  <tr><td><table class="navitem" width="100%">
-  <tr><td>Documentation</td></tr>
-  <tr><td>
-  <a href="https://gcc.gnu.org/install/">Installation</a><br />
-  &middot;&nbsp;<a href="https://gcc.gnu.org/install/specific.html">Platforms</a><br />
-  <a href="<get-var BACKPATH>onlinedocs/">Manual</a><br />
-  <a href="<get-var BACKPATH>faq.html">FAQ</a><br />
-  <a href="https://gcc.gnu.org/wiki">Wiki</a><br />
-  <a href="<get-var BACKPATH>readings.html">Pointers</a>
-  </td></tr>
-  </table></td></tr>
- 
-  <tr><td><table class="navitem" width="100%">
-  <tr><td>Download</td></tr>
-  <tr><td>
-  <a href="<get-var BACKPATH>mirrors.html">Mirrors</a><br />
-  <a href="https://gcc.gnu.org/install/binaries.html">Binaries</a>
-  </td></tr>
-  </table></td></tr>
-
-  <tr><td><table class="navitem" width="100%">
-  <tr><td>Sources</td></tr>
-  <tr><td>
-  <a href="<get-var BACKPATH>svn.html">SVN read access</a><br />
-  <a href="<get-var BACKPATH>svnwrite.html">SVN write access</a><br />
-  <a href="https://gcc.gnu.org/wiki/GitMirror">Git read access</a><br />
-  <a href="<get-var BACKPATH>rsync.html">Rsync</a><br />
-  </td></tr>
-  </table></td></tr>
-
-  <tr><td><table class="navitem" width="100%">
-  <tr><td>Development</td></tr>
-  <tr><td>
-  <a href="<get-var BACKPATH>develop.html">Development Plan</a><br />
-  &middot;&nbsp;<a href="<get-var BACKPATH>develop.html#timeline">Timeline</a><br />
-  <a href="<get-var BACKPATH>contribute.html">Contributing</a><br />
-  <a href="<get-var BACKPATH>contributewhy.html">Why&nbsp;contribute?</a><br />
-  <a href="<get-var BACKPATH>projects/">Open projects</a><br />
-  <a href="<get-var BACKPATH>frontends.html">Front ends</a><br />
-  <a href="<get-var BACKPATH>backends.html">Back ends</a><br />
-  <a href="<get-var BACKPATH>extensions.html">Extensions</a><br />
-  <a href="<get-var BACKPATH>benchmarks/">Benchmarks</a><br />
-  <a href="http://toolchain.lug-owl.de/buildbot/">Build Robot</a><br />
-  <a href="<get-var BACKPATH>translation.html">Translations</a><br />
-  </td></tr>
-  </table></td></tr>
-
-  <tr><td><table class="navitem" width="100%">
-  <tr><td>Bugs</td></tr>
-  <tr><td>
-  <a href="<get-var BACKPATH>bugs/#known">Known bugs</a><br />
-  <a href="<get-var BACKPATH>bugs/">How to report</a><br />
-  <a href="https://gcc.gnu.org/bugzilla/">Bug&nbsp;tracker</a><br />
-  &middot;&nbsp;<a href="<get-var BACKPATH>bugs/management.html">Management</a>
-  </td></tr>
-  </table></td></tr>
-
-  </table>
-  </td>                                             <!-- end of nav frame -->
-
-  </tr>
-  </table>
- > 
->
-
-<!-- ==================================================================== -->
-
-<div class="copyright">
-
-<address>For questions related to the use of GCC,
-please consult these web pages and the
-<a href="https://gcc.gnu.org/onlinedocs/">GCC manuals</a>. If that fails,
-the <a href="mailto:gcc-help@gcc.gnu.org">gcc-help@gcc.gnu.org</a>
-mailing list might help.
-Comments on these web pages and the development of GCC are welcome on our
-developer list at <a href="mailto:gcc@gcc.gnu.org">gcc@gcc.gnu.org</a>.
-All of <a href="https://gcc.gnu.org/lists.html">our lists</a>
-have public archives.
-</address>
-
-<p>Copyright (C)
-<a href="https://www.fsf.org">Free Software Foundation, Inc.</a>
-Verbatim copying and distribution of this entire article is
-permitted in any medium, provided this notice is preserved.</p>
-
-<p>These pages are
-<a href="https://gcc.gnu.org/about.html">maintained by the GCC team</a>.
-Last modified <date::format-time "YYYY-MM-DD"><!-- IGNORE DIFF
---><a href="http://validator.w3.org/check/referer">.</a></p>
-
-</div>
-
-<!-- ==================================================================== -->
-
-<verbatim>
-</body>
-</verbatim>
-</define-container>