#!/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())
