4848 'generated in subdirectories that match the package structure of the '
4949 'input .bzl files. The prefix to strip must be common to all .bzl files; '
5050 'otherwise, skydoc will raise an error.' )
51+ gflags .DEFINE_bool ('overview' , False , 'Whether to generate an overview page' )
52+ gflags .DEFINE_string ('overview_filename' , 'index' ,
53+ 'The file name to use for the overview page.' )
54+ gflags .DEFINE_string ('link_ext' , 'html' ,
55+ 'The file extension used for links in the generated documentation' )
5156
5257FLAGS = gflags .FLAGS
5358
6065
6166CSS_FILE = 'main.css'
6267
63- def _create_jinja_environment ():
68+ def _create_jinja_environment (link_ext ):
6469 env = jinja2 .Environment (
6570 loader = jinja2 .FileSystemLoader (_runfile_path (TEMPLATE_PATH )),
6671 keep_trailing_newline = True ,
6772 line_statement_prefix = '%' )
6873 env .filters ['markdown' ] = lambda text : jinja2 .Markup (mistune .markdown (text ))
74+ env .filters ['link' ] = lambda fname : '/' + fname + '.' + link_ext
6975 return env
7076
7177
@@ -112,14 +118,21 @@ def merge_languages(macro_language, rule_language):
112118 new_rule .CopyFrom (rule )
113119 return macro_language
114120
121+ class WriterOptions (object ):
122+ def __init__ (self , output_dir , output_file , output_zip , overview ,
123+ overview_filename , link_ext ):
124+ self .output_dir = output_dir
125+ self .output_file = output_file
126+ self .output_zip = output_zip
127+ self .overview = overview
128+ self .overview_filename = overview_filename
129+ self .link_ext = link_ext
130+
115131class MarkdownWriter (object ):
116132 """Writer for generating documentation in Markdown."""
117133
118- def __init__ (self , output_dir , output_file , output_zip , strip_prefix ):
119- self .__output_dir = output_dir
120- self .__output_file = output_file
121- self .__output_zip = output_zip
122- self .__strip_prefix = strip_prefix
134+ def __init__ (self , writer_options ):
135+ self .__options = writer_options
123136
124137 def write (self , rulesets ):
125138 """Write the documentation for the rules contained in rulesets."""
@@ -129,19 +142,21 @@ def write(self, rulesets):
129142 for ruleset in rulesets :
130143 if len (ruleset .rules ) > 0 :
131144 output_files .append (self ._write_ruleset (temp_dir , ruleset ))
145+ if self .__options .overview :
146+ output_files .append (self ._write_overview (temp_dir , rulesets ))
132147
133- if self .__output_zip :
148+ if self .__options . output_zip :
134149 # We are generating a zip archive containing all the documentation.
135150 # Write each documentation file generated in the temp directory to the
136151 # zip file.
137- with zipfile .ZipFile (self .__output_file , 'w' ) as zf :
152+ with zipfile .ZipFile (self .__options . output_file , 'w' ) as zf :
138153 for output_file , output_path in output_files :
139154 zf .write (output_file , output_path )
140155 else :
141156 # We are generating documentation in the output_dir directory. Copy each
142157 # documentation file to output_dir.
143158 for output_file , output_path in output_files :
144- dest_file = os .path .join (self .__output_dir , output_path )
159+ dest_file = os .path .join (self .__options . output_dir , output_path )
145160 dest_dir = os .path .dirname (dest_file )
146161 if not os .path .exists (dest_dir ):
147162 os .makedirs (dest_dir )
@@ -153,13 +168,13 @@ def write(self, rulesets):
153168
154169 def _write_ruleset (self , output_dir , ruleset ):
155170 # Load template and render Markdown.
156- env = _create_jinja_environment ()
171+ env = _create_jinja_environment (self . __options . link_ext )
157172 template = env .get_template ('markdown.jinja' )
158173 out = template .render (ruleset = ruleset )
159174
160175 # Write output to file. Output files are created in a directory structure
161176 # that matches that of the input file.
162- output_path = ruleset .output_filename ( self . __strip_prefix , ' md')
177+ output_path = ruleset .output_file + '. md'
163178 output_file = "%s/%s" % (output_dir , output_path )
164179 file_dirname = os .path .dirname (output_file )
165180 if not os .path .exists (file_dirname ):
@@ -168,57 +183,68 @@ def _write_ruleset(self, output_dir, ruleset):
168183 f .write (out )
169184 return (output_file , output_path )
170185
186+ def _write_overview (self , output_dir , rulesets ):
187+ template = self .__env .get_template ('markdown_overview.jinja' )
188+ out = template .render (rulesets = rulesets )
189+
190+ output_file = "%s/%s.md" % (output_dir , self .options .overview_filename )
191+ with open (output_file , "w" ) as f :
192+ f .write (out )
193+ return (output_file , "%s.md" % self .options .overview_filename )
194+
171195class HtmlWriter (object ):
172196 """Writer for generating documentation in HTML."""
173197
174- def __init__ (self , output_dir , output_file , output_zip , strip_prefix ):
175- self .__output_dir = output_dir
176- self .__output_file = output_file
177- self .__output_zip = output_zip
178- self .__strip_prefix = strip_prefix
179- self .__env = _create_jinja_environment ()
198+ def __init__ (self , options ):
199+ self .__options = options
200+ self .__env = _create_jinja_environment (self .__options .link_ext )
180201
181202 def write (self , rulesets ):
182203 # Generate navigation used for all rules.
183204 nav_template = self .__env .get_template ('nav.jinja' )
184- nav = nav_template .render (rulesets = rulesets )
205+ nav = nav_template .render (
206+ rulesets = rulesets ,
207+ overview = self .__options .overview ,
208+ overview_filename = self .__options .overview_filename )
185209
186210 try :
187211 temp_dir = tempfile .mkdtemp ()
188212 output_files = []
189213 for ruleset in rulesets :
190214 if len (ruleset .rules ) > 0 :
191215 output_files .append (self ._write_ruleset (temp_dir , ruleset , nav ))
216+ if self .__options .overview :
217+ output_files .append (self ._write_overview (temp_dir , rulesets , nav ))
192218
193- if self .__output_zip :
194- with zipfile .ZipFile (self .__output_file , 'w' ) as zf :
219+ if self .__options . output_zip :
220+ with zipfile .ZipFile (self .__options . output_file , 'w' ) as zf :
195221 for output_file , output_path in output_files :
196222 zf .write (output_file , output_path )
197223 zf .write (os .path .join (_runfile_path (CSS_PATH ), CSS_FILE ),
198224 '%s' % CSS_FILE )
199225 else :
200226 for output_file , output_path in output_files :
201- dest_file = os .path .join (self .__output_dir , output_path )
227+ dest_file = os .path .join (self .__options . output_dir , output_path )
202228 dest_dir = os .path .dirname (dest_file )
203229 if not os .path .exists (dest_dir ):
204230 os .makedirs (dest_dir )
205231 shutil .copyfile (output_file , dest_file )
206232
207233 # Copy CSS file.
208234 shutil .copyfile (os .path .join (_runfile_path (CSS_PATH ), CSS_FILE ),
209- os .path .join (self .__output_dir , CSS_FILE ))
235+ os .path .join (self .__options . output_dir , CSS_FILE ))
210236 finally :
211237 # Delete temporary directory.
212238 shutil .rmtree (temp_dir )
213239
214240 def _write_ruleset (self , output_dir , ruleset , nav ):
215241 # Load template and render markdown.
216242 template = self .__env .get_template ('html.jinja' )
217- out = template .render (ruleset = ruleset , nav = nav )
243+ out = template .render (title = ruleset . title , ruleset = ruleset , nav = nav )
218244
219245 # Write output to file. Output files are created in a directory structure
220246 # that matches that of the input file.
221- output_path = ruleset .output_filename ( self . __strip_prefix , ' html')
247+ output_path = ruleset .output_file + '. html'
222248 output_file = "%s/%s" % (output_dir , output_path )
223249 file_dirname = os .path .dirname (output_file )
224250 if not os .path .exists (file_dirname ):
@@ -227,6 +253,15 @@ def _write_ruleset(self, output_dir, ruleset, nav):
227253 f .write (out )
228254 return (output_file , output_path )
229255
256+ def _write_overview (self , output_dir , rulesets , nav ):
257+ template = self .__env .get_template ('html_overview.jinja' )
258+ out = template .render (title = 'Overview' , rulesets = rulesets , nav = nav )
259+
260+ output_file = "%s/%s.html" % (output_dir , self .__options .overview_filename )
261+ with open (output_file , "w" ) as f :
262+ f .write (out )
263+ return (output_file , "%s.html" % self .__options .overview_filename )
264+
230265def main (argv ):
231266 if FLAGS .output_dir and FLAGS .output_file :
232267 sys .stderr .write ('Only one of --output_dir or --output_file can be set.' )
@@ -252,17 +287,19 @@ def main(argv):
252287 rule_doc_extractor .parse_bzl (bzl_file )
253288 merged_language = merge_languages (macro_doc_extractor .proto (),
254289 rule_doc_extractor .proto ())
255- rulesets .append (rule .RuleSet (bzl_file , merged_language ,
256- macro_doc_extractor .title ,
257- macro_doc_extractor .description ))
258-
290+ rulesets .append (
291+ rule .RuleSet (bzl_file , merged_language , macro_doc_extractor .title ,
292+ macro_doc_extractor .description , strip_prefix ,
293+ FLAGS .format ))
294+
295+ writer_options = WriterOptions (
296+ FLAGS .output_dir , FLAGS .output_file , FLAGS .zip , FLAGS .overview ,
297+ FLAGS .overview_filename , FLAGS .link_ext )
259298 if FLAGS .format == "markdown" :
260- markdown_writer = MarkdownWriter (FLAGS .output_dir , FLAGS .output_file ,
261- FLAGS .zip , strip_prefix )
299+ markdown_writer = MarkdownWriter (writer_options )
262300 markdown_writer .write (rulesets )
263301 elif FLAGS .format == "html" :
264- html_writer = HtmlWriter (FLAGS .output_dir , FLAGS .output_file , FLAGS .zip ,
265- strip_prefix )
302+ html_writer = HtmlWriter (writer_options )
266303 html_writer .write (rulesets )
267304 else :
268305 sys .stderr .write (
0 commit comments