| 1 | #!/usr/bin/env python2
 | 
| 2 | """html_head.py: Emit <html><head> boilerplate.
 | 
| 3 | 
 | 
| 4 | And make sure it works on mobile!
 | 
| 5 | 
 | 
| 6 | Note: this file is also run with python3, by the Soil CI, because outside
 | 
| 7 | containers we don't have python2.
 | 
| 8 | """
 | 
| 9 | from __future__ import print_function
 | 
| 10 | 
 | 
| 11 | import sys
 | 
| 12 | try:
 | 
| 13 |     import html
 | 
| 14 | except ImportError:
 | 
| 15 |     import cgi as html  # only for cgi.escape -> html.escape
 | 
| 16 | try:
 | 
| 17 |     import cStringIO
 | 
| 18 | except ImportError:
 | 
| 19 |     cStringIO = None
 | 
| 20 |     import io
 | 
| 21 | import optparse
 | 
| 22 | 
 | 
| 23 | from doctools import doc_html
 | 
| 24 | 
 | 
| 25 | 
 | 
| 26 | # Python library.  Also see doctools/doc_html.py.
 | 
| 27 | def Write(f, title, css_urls=None, js_urls=None):
 | 
| 28 |     css_urls = css_urls or []
 | 
| 29 |     js_urls = js_urls or []
 | 
| 30 | 
 | 
| 31 |     # Note: do lang=en and charset=utf8 matter?  I guess if goes to a different
 | 
| 32 |     # web server?
 | 
| 33 |     f.write('''\
 | 
| 34 | <!DOCTYPE html>
 | 
| 35 | <html>
 | 
| 36 |   <head>
 | 
| 37 |     <meta name="viewport" content="width=device-width, initial-scale=1">
 | 
| 38 |     <title>%s</title>
 | 
| 39 | ''' % html.escape(title))
 | 
| 40 | 
 | 
| 41 |     # Write CSS files first I guess?
 | 
| 42 | 
 | 
| 43 |     for url in css_urls:
 | 
| 44 |         f.write(doc_html.CSS_FMT % html.escape(url))
 | 
| 45 | 
 | 
| 46 |     for url in js_urls:
 | 
| 47 |         f.write(doc_html.JS_FMT % html.escape(url))
 | 
| 48 | 
 | 
| 49 |     f.write('''\
 | 
| 50 |   </head>
 | 
| 51 | ''')
 | 
| 52 | 
 | 
| 53 | 
 | 
| 54 |     # Not used now
 | 
| 55 | def HtmlHead(title, css_urls=None, js_urls=None):
 | 
| 56 |     if cStringIO:
 | 
| 57 |         f = cStringIO.StringIO()
 | 
| 58 |     else:
 | 
| 59 |         f = io.BytesIO()
 | 
| 60 |     Write(f, title, css_urls=css_urls, js_urls=js_urls)
 | 
| 61 |     return f.getvalue()
 | 
| 62 | 
 | 
| 63 | 
 | 
| 64 | def main(argv):
 | 
| 65 |     p = optparse.OptionParser('html_head.py FLAGS? CSS_JS*')
 | 
| 66 |     p.add_option('-t',
 | 
| 67 |                  '--title',
 | 
| 68 |                  dest='title',
 | 
| 69 |                  default='',
 | 
| 70 |                  help='The title of the web page')
 | 
| 71 |     opts, argv = p.parse_args(argv[1:])
 | 
| 72 | 
 | 
| 73 |     # Make it easier to use from shell scripts
 | 
| 74 |     css_urls = []
 | 
| 75 |     js_urls = []
 | 
| 76 |     for arg in argv:
 | 
| 77 |         i = arg.rfind('?')  # account for query param
 | 
| 78 |         if i != -1:
 | 
| 79 |             url = arg[:i]
 | 
| 80 |         else:
 | 
| 81 |             url = arg
 | 
| 82 | 
 | 
| 83 |         if url.endswith('.js'):
 | 
| 84 |             js_urls.append(arg)
 | 
| 85 |         elif url.endswith('.css'):
 | 
| 86 |             css_urls.append(arg)
 | 
| 87 |         else:
 | 
| 88 |             raise RuntimeError("Expected URL with .js or .css, got %r" % arg)
 | 
| 89 | 
 | 
| 90 |     Write(sys.stdout, opts.title, css_urls=css_urls, js_urls=js_urls)
 | 
| 91 | 
 | 
| 92 | 
 | 
| 93 | if __name__ == '__main__':
 | 
| 94 |     try:
 | 
| 95 |         main(sys.argv)
 | 
| 96 |     except RuntimeError as e:
 | 
| 97 |         print('FATAL: %s' % e, file=sys.stderr)
 | 
| 98 |         sys.exit(1)
 |