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
,
64 """Processes a list of Markdown documentation files.
66 If input_pathname and output_pathname are specified, outputs HTML files
67 into the corresponding subdirectories of output_pathname. If one or both is
68 not specified, simply ensures the files exist and contain valid Markdown.
71 input_filenames: A list of filenames (absolute, or relative to $PWD) of
72 Markdown files to parse and possibly render.
73 input_pathname: The base directory of the input files. (Needed so they
74 can be placed in the same relative path in the output path.)
75 output_pathname: The output directory into which rendered Markdown files
76 go, using that relative path.
77 extensions: a list of Markdown.extensions to apply if any.
83 IOError: if any of the file operations fail (e.g. input_filenames
84 contains a non-existent file).
87 outputting
= (input_pathname
is not None) and (output_pathname
is not None)
90 markdown_parser
= markdown
.Markdown(extensions
)
92 markdown_parser
= markdown
.Markdown()
94 for input_filename
in input_filenames
:
95 markdown_text
= ReadFile(input_filename
)
96 markdown_html
= markdown_parser
.reset().convert(markdown_text
)
100 full_html
= FormatPage(markdown_html
, title
=input_filename
)
101 rel_filename
= os
.path
.relpath(input_filename
, start
=input_pathname
)
102 output_filename
= os
.path
.join(output_pathname
, rel_filename
) + '.html'
103 WriteFile(output_filename
, full_html
)
107 parser
= argparse
.ArgumentParser(
108 description
='Parse and render Markdown documentation')
109 parser
.add_argument('--input_path', default
=None,
110 help="Input path for Markdown; required only if output_path set")
111 parser
.add_argument('--output_path', default
=None,
112 help="Output path for rendered HTML; if unspecified, won't output")
113 parser
.add_argument('filenames', nargs
=argparse
.REMAINDER
)
114 args
= parser
.parse_args()
116 ProcessDocs(args
.filenames
, args
.input_path
, args
.output_path
)
121 if __name__
== '__main__':