123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- #!/usr/bin/env python
- # Copyright 2015 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.
- """Reads, parses, and (optionally) writes as HTML the contents of Markdown
- files passed as arguments. Intended for rendering network stack documentation
- stored as Markdown in the source tree to a human-readable format."""
- import argparse
- import os.path
- import sys
- def nth_parent_directory(path, n):
- for i in range(n):
- path = os.path.dirname(path)
- return path
- # Go up the directory tree from this script and add src/third_party to sys.path
- # so "import markdown" can find it in src/third_party/markdown.
- SCRIPT_PATH = os.path.abspath(__file__)
- SRC_PATH = nth_parent_directory(SCRIPT_PATH, 4)
- THIRD_PARTY_PATH = os.path.join(SRC_PATH, 'third_party')
- sys.path.insert(0, THIRD_PARTY_PATH)
- import markdown
- def ReadFile(filename):
- with open(filename, 'r') as file:
- return file.read()
- def WriteFile(filename, contents):
- dir = os.path.dirname(filename)
- if not os.path.isdir(dir):
- os.mkdir(dir)
- with open(filename, 'w') as file:
- file.write(contents)
- TEMPLATE = """
- <html>
- <head>
- <title>{title}</title>
- </head>
- <body>
- {body}
- </body>
- </html>"""
- def FormatPage(markdown_html, title):
- # TODO(juliatuttle): Add a navigation list / table of contents of available
- # Markdown files, perhaps?
- return TEMPLATE.format(title=title, body=markdown_html)
- def ProcessDocs(input_filenames, input_pathname, output_pathname,
- extensions=None):
- """Processes a list of Markdown documentation files.
- If input_pathname and output_pathname are specified, outputs HTML files
- into the corresponding subdirectories of output_pathname. If one or both is
- not specified, simply ensures the files exist and contain valid Markdown.
- Args:
- input_filenames: A list of filenames (absolute, or relative to $PWD) of
- Markdown files to parse and possibly render.
- input_pathname: The base directory of the input files. (Needed so they
- can be placed in the same relative path in the output path.)
- output_pathname: The output directory into which rendered Markdown files
- go, using that relative path.
- extensions: a list of Markdown.extensions to apply if any.
- Returns:
- nothing
- Raises:
- IOError: if any of the file operations fail (e.g. input_filenames
- contains a non-existent file).
- """
- outputting = (input_pathname is not None) and (output_pathname is not None)
- if extensions:
- markdown_parser = markdown.Markdown(extensions)
- else:
- markdown_parser = markdown.Markdown()
- for input_filename in input_filenames:
- markdown_text = ReadFile(input_filename)
- markdown_html = markdown_parser.reset().convert(markdown_text)
- if not outputting:
- continue
- full_html = FormatPage(markdown_html, title=input_filename)
- rel_filename = os.path.relpath(input_filename, start=input_pathname)
- output_filename = os.path.join(output_pathname, rel_filename) + '.html'
- WriteFile(output_filename, full_html)
- def main():
- parser = argparse.ArgumentParser(
- description='Parse and render Markdown documentation')
- parser.add_argument('--input_path', default=None,
- help="Input path for Markdown; required only if output_path set")
- parser.add_argument('--output_path', default=None,
- help="Output path for rendered HTML; if unspecified, won't output")
- parser.add_argument('filenames', nargs=argparse.REMAINDER)
- args = parser.parse_args()
- extensions = ['markdown.extensions.def_list']
- ProcessDocs(args.filenames, args.input_path, args.output_path, extensions)
- return 0
- if __name__ == '__main__':
- sys.exit(main())
|