16d528ed9Sopenharmony_ci#!/usr/bin/env python3 26d528ed9Sopenharmony_ci# Copyright 2014 The Chromium Authors. All rights reserved. 36d528ed9Sopenharmony_ci# Use of this source code is governed by a BSD-style license that can be 46d528ed9Sopenharmony_ci# found in the LICENSE file. 56d528ed9Sopenharmony_ci 66d528ed9Sopenharmony_ci# Runs 'gn help' and various subhelps, and spits out html. 76d528ed9Sopenharmony_ci# TODO: 86d528ed9Sopenharmony_ci# - Handle numbered and dashed lists -> <ol> <ul>. (See "os" and "toolchain"). 96d528ed9Sopenharmony_ci# - Handle "Arguments:" blocks a bit better (the argument names could be 106d528ed9Sopenharmony_ci# distinguished). 116d528ed9Sopenharmony_ci# - Convert "|blahblah|" to <code>. 126d528ed9Sopenharmony_ci# - Spit out other similar formats like wiki, markdown, whatever. 136d528ed9Sopenharmony_ci 146d528ed9Sopenharmony_ciimport cgi 156d528ed9Sopenharmony_ciimport subprocess 166d528ed9Sopenharmony_ciimport sys 176d528ed9Sopenharmony_ci 186d528ed9Sopenharmony_ci 196d528ed9Sopenharmony_cidef GetOutput(*args): 206d528ed9Sopenharmony_ci try: 216d528ed9Sopenharmony_ci return subprocess.check_output([sys.argv[1]] + list(args)) 226d528ed9Sopenharmony_ci except subprocess.CalledProcessError: 236d528ed9Sopenharmony_ci return '' 246d528ed9Sopenharmony_ci 256d528ed9Sopenharmony_ci 266d528ed9Sopenharmony_cidef ParseTopLevel(out): 276d528ed9Sopenharmony_ci commands = [] 286d528ed9Sopenharmony_ci output = [] 296d528ed9Sopenharmony_ci for line in out.splitlines(): 306d528ed9Sopenharmony_ci if line.startswith(' '): 316d528ed9Sopenharmony_ci command, sep, rest = line.partition(':') 326d528ed9Sopenharmony_ci command = command.strip() 336d528ed9Sopenharmony_ci is_option = command.startswith('-') 346d528ed9Sopenharmony_ci output_line = ['<li>'] 356d528ed9Sopenharmony_ci if not is_option: 366d528ed9Sopenharmony_ci commands.append(command) 376d528ed9Sopenharmony_ci output_line.append('<a href="#' + cgi.escape(command) + '">') 386d528ed9Sopenharmony_ci output_line.append(cgi.escape(command)) 396d528ed9Sopenharmony_ci if not is_option: 406d528ed9Sopenharmony_ci output_line.append('</a>') 416d528ed9Sopenharmony_ci output_line.extend([sep + cgi.escape(rest) + '</li>']) 426d528ed9Sopenharmony_ci output.append(''.join(output_line)) 436d528ed9Sopenharmony_ci else: 446d528ed9Sopenharmony_ci output.append('<h2>' + cgi.escape(line) + '</h2>') 456d528ed9Sopenharmony_ci return commands, output 466d528ed9Sopenharmony_ci 476d528ed9Sopenharmony_ci 486d528ed9Sopenharmony_cidef ParseCommand(command, out): 496d528ed9Sopenharmony_ci first_line = True 506d528ed9Sopenharmony_ci got_example = False 516d528ed9Sopenharmony_ci output = [] 526d528ed9Sopenharmony_ci for line in out.splitlines(): 536d528ed9Sopenharmony_ci if first_line: 546d528ed9Sopenharmony_ci name, sep, rest = line.partition(':') 556d528ed9Sopenharmony_ci name = name.strip() 566d528ed9Sopenharmony_ci output.append('<h3><a name="' + cgi.escape(command) + '">' + 576d528ed9Sopenharmony_ci cgi.escape(name + sep + rest) + '</a></h3>') 586d528ed9Sopenharmony_ci first_line = False 596d528ed9Sopenharmony_ci else: 606d528ed9Sopenharmony_ci if line.startswith('Example'): 616d528ed9Sopenharmony_ci # Special subsection that's pre-formatted. 626d528ed9Sopenharmony_ci if got_example: 636d528ed9Sopenharmony_ci output.append('</pre>') 646d528ed9Sopenharmony_ci got_example = True 656d528ed9Sopenharmony_ci output.append('<h4>Example</h4>') 666d528ed9Sopenharmony_ci output.append('<pre>') 676d528ed9Sopenharmony_ci elif not line.strip(): 686d528ed9Sopenharmony_ci output.append('<p>') 696d528ed9Sopenharmony_ci elif not line.startswith(' ') and line.endswith(':'): 706d528ed9Sopenharmony_ci # Subsection. 716d528ed9Sopenharmony_ci output.append('<h4>' + cgi.escape(line[:-1]) + '</h4>') 726d528ed9Sopenharmony_ci else: 736d528ed9Sopenharmony_ci output.append(cgi.escape(line)) 746d528ed9Sopenharmony_ci if got_example: 756d528ed9Sopenharmony_ci output.append('</pre>') 766d528ed9Sopenharmony_ci return output 776d528ed9Sopenharmony_ci 786d528ed9Sopenharmony_ci 796d528ed9Sopenharmony_cidef main(): 806d528ed9Sopenharmony_ci if len(sys.argv) < 2: 816d528ed9Sopenharmony_ci print('usage: help_as_html.py <gn_binary>') 826d528ed9Sopenharmony_ci return 1 836d528ed9Sopenharmony_ci header = '''<!DOCTYPE html> 846d528ed9Sopenharmony_ci<html> 856d528ed9Sopenharmony_ci <head> 866d528ed9Sopenharmony_ci <meta name="viewport" content="width=device-width, initial-scale=1"> 876d528ed9Sopenharmony_ci <style> 886d528ed9Sopenharmony_ci body { font-family: Arial, sans-serif; font-size: small; } 896d528ed9Sopenharmony_ci pre { font-family: Consolas, monospace; font-size: small; } 906d528ed9Sopenharmony_ci #container { margin: 0 auto; max-width: 48rem; width: 90%; } 916d528ed9Sopenharmony_ci </style> 926d528ed9Sopenharmony_ci </head> 936d528ed9Sopenharmony_ci <body> 946d528ed9Sopenharmony_ci <div id="container"><h1>GN</h1> 956d528ed9Sopenharmony_ci''' 966d528ed9Sopenharmony_ci footer = '</div></body></html>' 976d528ed9Sopenharmony_ci commands, output = ParseTopLevel(GetOutput('help')) 986d528ed9Sopenharmony_ci for command in commands: 996d528ed9Sopenharmony_ci output += ParseCommand(command, GetOutput('help', command)) 1006d528ed9Sopenharmony_ci print(header + '\n'.join(output) + footer) 1016d528ed9Sopenharmony_ci return 0 1026d528ed9Sopenharmony_ci 1036d528ed9Sopenharmony_ci 1046d528ed9Sopenharmony_ciif __name__ == '__main__': 1056d528ed9Sopenharmony_ci sys.exit(main()) 106