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 14import cgi 15import subprocess 16import sys 17 18 19def GetOutput(*args): 20 try: 21 return subprocess.check_output([sys.argv[1]] + list(args)) 22 except subprocess.CalledProcessError: 23 return '' 24 25 26def 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 48def 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 79def 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 104if __name__ == '__main__': 105 sys.exit(main()) 106