Home | History | Annotate | Download | only in bin
      1 #!/usr/bin/env python
      2 # Copyright 2014 The Chromium Authors. All rights reserved.
      3 # Use of this source code is governed by a BSD-style license that can be
      4 # found in the LICENSE file.
      5 
      6 # Runs 'gn help' and various subhelps, and spits out html.
      7 # TODO:
      8 # - Handle numbered and dashed lists -> <ol> <ul>. (See "os" and "toolchain").
      9 # - Handle "Arguments:" blocks a bit better (the argument names could be
     10 #   distinguished).
     11 # - Convert "|blahblah|" to <code>.
     12 # - Spit out other similar formats like wiki, markdown, whatever.
     13 
     14 import cgi
     15 import subprocess
     16 import sys
     17 
     18 
     19 def GetOutput(*args):
     20   try:
     21     return subprocess.check_output([sys.argv[1]] + list(args))
     22   except subprocess.CalledProcessError:
     23     return ''
     24 
     25 
     26 def ParseTopLevel(out):
     27   commands = []
     28   output = []
     29   for line in out.splitlines():
     30     if line.startswith('  '):
     31       command, sep, rest = line.partition(':')
     32       command = command.strip()
     33       is_option = command.startswith('-')
     34       output_line = ['<li>']
     35       if not is_option:
     36         commands.append(command)
     37         output_line.append('<a href="#' + cgi.escape(command) + '">')
     38       output_line.append(cgi.escape(command))
     39       if not is_option:
     40         output_line.append('</a>')
     41       output_line.extend([sep + cgi.escape(rest) + '</li>'])
     42       output.append(''.join(output_line))
     43     else:
     44       output.append('<h2>' + cgi.escape(line) + '</h2>')
     45   return commands, output
     46 
     47 
     48 def ParseCommand(command, out):
     49   first_line = True
     50   got_example = False
     51   output = []
     52   for line in out.splitlines():
     53     if first_line:
     54       name, sep, rest = line.partition(':')
     55       name = name.strip()
     56       output.append('<h3><a name="' + cgi.escape(command) + '">' +
     57                     cgi.escape(name + sep + rest) + '</a></h3>')
     58       first_line = False
     59     else:
     60       if line.startswith('Example'):
     61         # Special subsection that's pre-formatted.
     62         if got_example:
     63           output.append('</pre>')
     64         got_example = True
     65         output.append('<h4>Example</h4>')
     66         output.append('<pre>')
     67       elif not line.strip():
     68         output.append('<p>')
     69       elif not line.startswith('  ') and line.endswith(':'):
     70         # Subsection.
     71         output.append('<h4>' + cgi.escape(line[:-1]) + '</h4>')
     72       else:
     73         output.append(cgi.escape(line))
     74   if got_example:
     75     output.append('</pre>')
     76   return output
     77 
     78 
     79 def main():
     80   if len(sys.argv) < 2:
     81     print 'usage: help_as_html.py <gn_binary>'
     82     return 1
     83   header = '''<!DOCTYPE html>
     84 <html>
     85   <head>
     86     <meta name="viewport" content="width=device-width, initial-scale=1">
     87     <style>
     88       body { font-family: Arial, sans-serif; font-size: small; }
     89       pre { font-family: Consolas, monospace; font-size: small; }
     90       #container { margin: 0 auto; max-width: 48rem; width: 90%; }
     91     </style>
     92   </head>
     93   <body>
     94     <div id="container"><h1>GN</h1>
     95 '''
     96   footer = '</div></body></html>'
     97   commands, output = ParseTopLevel(GetOutput('help'))
     98   for command in commands:
     99     output += ParseCommand(command, GetOutput('help', command))
    100   print header + '\n'.join(output) + footer
    101   return 0
    102 
    103 
    104 if __name__ == '__main__':
    105   sys.exit(main())
    106