##// END OF EJS Templates
doc: refactor gendoc for better reusability...
Ludovic Chabant -
r52913:1f5974f8 default
parent child Browse files
Show More
@@ -8,6 +8,7 b' where DOC is the name of a document'
8 8 import os
9 9 import sys
10 10 import textwrap
11 import argparse
11 12
12 13 try:
13 14 import msvcrt
@@ -115,7 +116,7 b' def get_cmd(cmd, cmdtable):'
115 116 return d
116 117
117 118
118 def showdoc(ui):
119 def showdoc(ui, debugcmds=False):
119 120 # print options
120 121 ui.write(minirst.section(_(b"Options")))
121 122 multioccur = False
@@ -129,11 +130,18 b' def showdoc(ui):'
129 130
130 131 # print cmds
131 132 ui.write(minirst.section(_(b"Commands")))
132 commandprinter(ui, table, minirst.subsection, minirst.subsubsection)
133 commandprinter(
134 ui,
135 table,
136 minirst.subsection,
137 minirst.subsubsection,
138 debugcmds=debugcmds,
139 )
133 140
134 141 # print help topics
135 142 # The config help topic is included in the hgrc.5 man page.
136 helpprinter(ui, helptable, minirst.section, exclude=[b'config'])
143 topics = findtopics(helptable, exclude=[b'config'])
144 helpprinter(ui, topics, minirst.section)
137 145
138 146 ui.write(minirst.section(_(b"Extensions")))
139 147 ui.write(
@@ -166,10 +174,11 b' def showdoc(ui):'
166 174 cmdtable,
167 175 minirst.subsubsubsection,
168 176 minirst.subsubsubsubsection,
177 debugcmds=debugcmds,
169 178 )
170 179
171 180
172 def showtopic(ui, topic):
181 def gettopicstable():
173 182 extrahelptable = [
174 183 ([b"common"], b'', loaddoc(b'common'), help.TOPIC_CATEGORY_MISC),
175 184 ([b"hg.1"], b'', loaddoc(b'hg.1'), help.TOPIC_CATEGORY_CONFIG),
@@ -181,6 +190,7 b' def showtopic(ui, topic):'
181 190 help.TOPIC_CATEGORY_CONFIG,
182 191 ),
183 192 ([b"hgrc.5"], b'', loaddoc(b'hgrc.5'), help.TOPIC_CATEGORY_CONFIG),
193 ([b"hg-ssh.8.gendoc"], b'', b'', help.TOPIC_CATEGORY_CONFIG),
184 194 (
185 195 [b"hgignore.5.gendoc"],
186 196 b'',
@@ -194,16 +204,59 b' def showtopic(ui, topic):'
194 204 help.TOPIC_CATEGORY_CONFIG,
195 205 ),
196 206 ]
197 helpprinter(ui, helptable + extrahelptable, None, include=[topic])
207 return helptable + extrahelptable
198 208
199 209
200 def helpprinter(ui, helptable, sectionfunc, include=[], exclude=[]):
210 def findtopics(helptable, include=[], exclude=[]):
211 """Find topics whose names match the given include/exclude rules
212
213 Note that exclude rules take precedence over include rules.
214 """
215 found = []
201 216 for h in helptable:
202 217 names, sec, doc = h[0:3]
203 218 if exclude and names[0] in exclude:
204 219 continue
205 220 if include and names[0] not in include:
206 221 continue
222 found.append((names, sec, doc))
223 return found
224
225
226 def showtopic(ui, topic, wraptpl=False):
227 """Render a help topic
228
229 Args:
230 ui: the UI object to output to
231 topic: the topic name to output
232 wraptpl: whether to wrap the output in the individual help topic
233 pages' header/footer
234 """
235 found = findtopics(gettopicstable(), include=[topic])
236 if not found:
237 ui.write_err(_(b"ERROR: no such topic: %s\n") % topic)
238 sys.exit(1)
239
240 if wraptpl:
241 header = _rendertpl(
242 'topicheader.txt',
243 {'topicname': topic, 'topictitle': minirst.section(found[0][1])},
244 )
245 ui.write(header.encode())
246 helpprinter(ui, found, None)
247 return True
248
249
250 def helpprinter(ui, topics, sectionfunc):
251 """Print a help topic
252
253 Args:
254 ui: the UI object to output to
255 topics: a list of help topics to output
256 sectionfunc: a callback to write the section title
257 """
258 for h in topics:
259 names, sec, doc = h[0:3]
207 260 for name in names:
208 261 ui.write(b".. _%s:\n" % name)
209 262 ui.write(b"\n")
@@ -215,7 +268,7 b' def helpprinter(ui, helptable, sectionfu'
215 268 ui.write(b"\n")
216 269
217 270
218 def commandprinter(ui, cmdtable, sectionfunc, subsectionfunc):
271 def commandprinter(ui, cmdtable, sectionfunc, subsectionfunc, debugcmds=False):
219 272 """Render restructuredtext describing a list of commands and their
220 273 documentations, grouped by command category.
221 274
@@ -236,11 +289,7 b' def commandprinter(ui, cmdtable, section'
236 289 sectionfunc: minirst function to format command category headers
237 290 subsectionfunc: minirst function to format command headers
238 291 """
239 h = {}
240 for c, attr in cmdtable.items():
241 f = c.split(b"|")[0]
242 f = f.lstrip(b"^")
243 h[f] = c
292 h = allcommandnames(cmdtable, debugcmds=debugcmds)
244 293 cmds = h.keys()
245 294
246 295 def helpcategory(cmd):
@@ -277,8 +326,6 b' def commandprinter(ui, cmdtable, section'
277 326 ui.write(sectionfunc(help.CATEGORY_NAMES[category]))
278 327 # Print each command in the category
279 328 for f in sorted(categorycmds):
280 if f.startswith(b"debug"):
281 continue
282 329 d = get_cmd(h[f], cmdtable)
283 330 ui.write(subsectionfunc(d[b'cmd']))
284 331 # short description
@@ -293,28 +340,12 b' def commandprinter(ui, cmdtable, section'
293 340 ui.write(b'\n')
294 341 # description
295 342 ui.write(b"%s\n\n" % d[b'desc'][1])
343
296 344 # options
297 opt_output = list(d[b'opts'])
298 if opt_output:
299 opts_len = max([len(line[0]) for line in opt_output])
300 ui.write(_(b"Options:\n\n"))
301 multioccur = False
302 for optstr, desc in opt_output:
303 if desc:
304 s = b"%-*s %s" % (opts_len, optstr, desc)
305 else:
306 s = optstr
307 ui.write(b"%s\n" % s)
308 if optstr.endswith(b"[+]>"):
309 multioccur = True
310 if multioccur:
311 ui.write(
312 _(
313 b"\n[+] marked option can be specified"
314 b" multiple times\n"
315 )
316 )
317 ui.write(b"\n")
345 def _optsection(s):
346 return b"%s:\n\n" % s
347
348 _optionsprinter(ui, d, _optsection)
318 349 # aliases
319 350 if d[b'aliases']:
320 351 # Note the empty comment, this is required to separate this
@@ -325,14 +356,67 b' def commandprinter(ui, cmdtable, section'
325 356 )
326 357
327 358
359 def _optionsprinter(ui, cmd, sectionfunc):
360 """Outputs the list of options for a given command object"""
361 opt_output = list(cmd[b'opts'])
362 if opt_output:
363 opts_len = max([len(line[0]) for line in opt_output])
364 ui.write(sectionfunc(_(b"Options")))
365 multioccur = False
366 for optstr, desc in opt_output:
367 if desc:
368 s = b"%-*s %s" % (opts_len, optstr, desc)
369 else:
370 s = optstr
371 ui.write(b"%s\n" % s)
372 if optstr.endswith(b"[+]>"):
373 multioccur = True
374 if multioccur:
375 ui.write(
376 _(b"\n[+] marked option can be specified multiple times\n")
377 )
378 ui.write(b"\n")
379
380
381 def allcommandnames(cmdtable, debugcmds=False):
382 """Get a collection of all command names in the given command table
383
384 Args:
385 cmdtable: the command table to get the names from
386 debugcmds: whether to include debug commands
387
388 Returns a dictionary where the keys are the main command names, and the
389 values are the "raw" names (in the form of `name|alias1|alias2`).
390 """
391 allcmdnames = {}
392 for rawnames, attr in cmdtable.items():
393 mainname = rawnames.split(b"|")[0].lstrip(b"^")
394 if not debugcmds and mainname.startswith(b"debug"):
395 continue
396 allcmdnames[mainname] = rawnames
397 return allcmdnames
398
399
328 400 def allextensionnames():
401 """Get a set of all known extension names"""
329 402 return set(extensions.enabled().keys()) | set(extensions.disabled().keys())
330 403
331 404
332 405 if __name__ == "__main__":
333 doc = b'hg.1.gendoc'
334 if len(sys.argv) > 1:
335 doc = encoding.strtolocal(sys.argv[1])
406 parser = argparse.ArgumentParser(
407 prog='gendoc', description="Generate mercurial documentation files"
408 )
409 parser.add_argument('doc', default='hg.1.gendoc', nargs='?')
410 parser.add_argument(
411 '-d',
412 '--debug-cmds',
413 action='store_true',
414 help="Show debug commands in help pages",
415 )
416 args = parser.parse_args()
417
418 doc = encoding.strtolocal(args.doc)
419 debugcmds = args.debug_cmds
336 420
337 421 ui = uimod.ui.load()
338 422 # Trigger extensions to load. This is disabled by default because it uses
@@ -340,7 +424,10 b' if __name__ == "__main__":'
340 424 if encoding.environ.get(b'GENDOC_LOAD_CONFIGURED_EXTENSIONS', b'0') != b'0':
341 425 extensions.loadall(ui)
342 426
427 # ui.debugflag determines if the help module returns debug commands to us.
428 ui.debugflag = debugcmds
429
343 430 if doc == b'hg.1.gendoc':
344 431 showdoc(ui)
345 432 else:
346 showtopic(ui, encoding.strtolocal(sys.argv[1]))
433 showtopic(ui, doc)
General Comments 0
You need to be logged in to leave comments. Login now