| #!/usr/bin/env python3 | |
| # Copyright 2014 The Chromium Authors. All rights reserved. | |
| # Use of this source code is governed by a BSD-style license that can be | |
| # found in the LICENSE file. | |
| # Runs 'gn help' and various subhelps, and spits out html. | |
| # TODO: | |
| # - Handle numbered and dashed lists -> <ol> <ul>. (See "os" and "toolchain"). | |
| # - Handle "Arguments:" blocks a bit better (the argument names could be | |
| # distinguished). | |
| # - Convert "|blahblah|" to <code>. | |
| # - Spit out other similar formats like wiki, markdown, whatever. | |
| import html | |
| import subprocess | |
| import sys | |
| def GetOutput(*args): | |
| try: | |
| return subprocess.check_output([sys.argv[1]] + list(args)) | |
| except subprocess.CalledProcessError: | |
| return '' | |
| def ParseTopLevel(out): | |
| commands = [] | |
| output = [] | |
| for line in out.splitlines(): | |
| if line.startswith(' '): | |
| command, sep, rest = line.partition(':') | |
| command = command.strip() | |
| is_option = command.startswith('-') | |
| output_line = ['<li>'] | |
| if not is_option: | |
| commands.append(command) | |
| output_line.append('<a href="#' + html.escape(command) + '">') | |
| output_line.append(html.escape(command)) | |
| if not is_option: | |
| output_line.append('</a>') | |
| output_line.extend([sep + html.escape(rest) + '</li>']) | |
| output.append(''.join(output_line)) | |
| else: | |
| output.append('<h2>' + html.escape(line) + '</h2>') | |
| return commands, output | |
| def ParseCommand(command, out): | |
| first_line = True | |
| got_example = False | |
| output = [] | |
| for line in out.splitlines(): | |
| if first_line: | |
| name, sep, rest = line.partition(':') | |
| name = name.strip() | |
| output.append('<h3><a name="' + html.escape(command) + '">' + | |
| html.escape(name + sep + rest) + '</a></h3>') | |
| first_line = False | |
| else: | |
| if line.startswith('Example'): | |
| # Special subsection that's pre-formatted. | |
| if got_example: | |
| output.append('</pre>') | |
| got_example = True | |
| output.append('<h4>Example</h4>') | |
| output.append('<pre>') | |
| elif not line.strip(): | |
| output.append('<p>') | |
| elif not line.startswith(' ') and line.endswith(':'): | |
| # Subsection. | |
| output.append('<h4>' + html.escape(line[:-1]) + '</h4>') | |
| else: | |
| output.append(html.escape(line)) | |
| if got_example: | |
| output.append('</pre>') | |
| return output | |
| def main(): | |
| if len(sys.argv) < 2: | |
| print('usage: help_as_html.py <gn_binary>') | |
| return 1 | |
| header = '''<!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |
| <style> | |
| body { font-family: Arial, sans-serif; font-size: small; } | |
| pre { font-family: Consolas, monospace; font-size: small; } | |
| #container { margin: 0 auto; max-width: 48rem; width: 90%; } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="container"><h1>GN</h1> | |
| ''' | |
| footer = '</div></body></html>' | |
| commands, output = ParseTopLevel(GetOutput('help')) | |
| for command in commands: | |
| output += ParseCommand(command, GetOutput('help', command)) | |
| print(header + '\n'.join(output) + footer) | |
| return 0 | |
| if __name__ == '__main__': | |
| sys.exit(main()) |