2 # Copyright 2015 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.
7 """Reads, parses, and (optionally) writes as HTML the contents of Markdown
8 files passed as arguments. Intended for rendering network stack documentation
9 stored as Markdown in the source tree to a human-readable format."""
17 def nth_parent_directory(path
, n
):
19 path
= os
.path
.dirname(path
)
23 # Go up the directory tree from this script and add src/third_party to sys.path
24 # so "import markdown" can find it in src/third_party/markdown.
25 SCRIPT_PATH
= os
.path
.abspath(__file__
)
26 SRC_PATH
= nth_parent_directory(SCRIPT_PATH
, 4)
27 THIRD_PARTY_PATH
= os
.path
.join(SRC_PATH
, 'third_party')
28 sys
.path
.insert(0, THIRD_PARTY_PATH
)
32 def ReadFile(filename
):
33 with
open(filename
, 'r') as file:
37 def WriteFile(filename
, contents
):
38 dir = os
.path
.dirname(filename
)
39 if not os
.path
.isdir(dir):
41 with
open(filename
, 'w') as file:
48 <title>{title}</title>
56 def FormatPage(markdown_html
, title
):
57 # TODO(ttuttle): Add a navigation list / table of contents of available
58 # Markdown files, perhaps?
59 return TEMPLATE
.format(title
=title
, body
=markdown_html
)
62 def ProcessDocs(input_filenames
, input_pathname
, output_pathname
):
63 """Processes a list of Markdown documentation files.
65 If input_pathname and output_pathname are specified, outputs HTML files
66 into the corresponding subdirectories of output_pathname. If one or both is
67 not specified, simply ensures the files exist and contain valid Markdown.
70 input_filenames: A list of filenames (absolute, or relative to $PWD) of
71 Markdown files to parse and possibly render.
72 input_pathname: The base directory of the input files. (Needed so they
73 can be placed in the same relative path in the output path.)
74 output_pathname: The output directory into which rendered Markdown files
75 go, using that relative path.
81 IOError: if any of the file operations fail (e.g. input_filenames
82 contains a non-existent file).
85 outputting
= (input_pathname
is not None) and (output_pathname
is not None)
87 markdown_parser
= markdown
.Markdown()
89 for input_filename
in input_filenames
:
90 markdown_text
= ReadFile(input_filename
)
91 markdown_html
= markdown_parser
.reset().convert(markdown_text
)
95 full_html
= FormatPage(markdown_html
, title
=input_filename
)
96 rel_filename
= os
.path
.relpath(input_filename
, start
=input_pathname
)
97 output_filename
= os
.path
.join(output_pathname
, rel_filename
) + '.html'
98 WriteFile(output_filename
, full_html
)
102 parser
= argparse
.ArgumentParser(
103 description
='Parse and render Markdown documentation')
104 parser
.add_argument('--input_path', default
=None,
105 help="Input path for Markdown; required only if output_path set")
106 parser
.add_argument('--output_path', default
=None,
107 help="Output path for rendered HTML; if unspecified, won't output")
108 parser
.add_argument('filenames', nargs
=argparse
.REMAINDER
)
109 args
= parser
.parse_args()
111 ProcessDocs(args
.filenames
, args
.input_path
, args
.output_path
)
116 if __name__
== '__main__':