##// 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 import os
8 import os
9 import sys
9 import sys
10 import textwrap
10 import textwrap
11 import argparse
11
12
12 try:
13 try:
13 import msvcrt
14 import msvcrt
@@ -115,7 +116,7 b' def get_cmd(cmd, cmdtable):'
115 return d
116 return d
116
117
117
118
118 def showdoc(ui):
119 def showdoc(ui, debugcmds=False):
119 # print options
120 # print options
120 ui.write(minirst.section(_(b"Options")))
121 ui.write(minirst.section(_(b"Options")))
121 multioccur = False
122 multioccur = False
@@ -129,11 +130,18 b' def showdoc(ui):'
129
130
130 # print cmds
131 # print cmds
131 ui.write(minirst.section(_(b"Commands")))
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 # print help topics
141 # print help topics
135 # The config help topic is included in the hgrc.5 man page.
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 ui.write(minirst.section(_(b"Extensions")))
146 ui.write(minirst.section(_(b"Extensions")))
139 ui.write(
147 ui.write(
@@ -166,10 +174,11 b' def showdoc(ui):'
166 cmdtable,
174 cmdtable,
167 minirst.subsubsubsection,
175 minirst.subsubsubsection,
168 minirst.subsubsubsubsection,
176 minirst.subsubsubsubsection,
177 debugcmds=debugcmds,
169 )
178 )
170
179
171
180
172 def showtopic(ui, topic):
181 def gettopicstable():
173 extrahelptable = [
182 extrahelptable = [
174 ([b"common"], b'', loaddoc(b'common'), help.TOPIC_CATEGORY_MISC),
183 ([b"common"], b'', loaddoc(b'common'), help.TOPIC_CATEGORY_MISC),
175 ([b"hg.1"], b'', loaddoc(b'hg.1'), help.TOPIC_CATEGORY_CONFIG),
184 ([b"hg.1"], b'', loaddoc(b'hg.1'), help.TOPIC_CATEGORY_CONFIG),
@@ -181,6 +190,7 b' def showtopic(ui, topic):'
181 help.TOPIC_CATEGORY_CONFIG,
190 help.TOPIC_CATEGORY_CONFIG,
182 ),
191 ),
183 ([b"hgrc.5"], b'', loaddoc(b'hgrc.5'), help.TOPIC_CATEGORY_CONFIG),
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 [b"hgignore.5.gendoc"],
195 [b"hgignore.5.gendoc"],
186 b'',
196 b'',
@@ -194,16 +204,59 b' def showtopic(ui, topic):'
194 help.TOPIC_CATEGORY_CONFIG,
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 for h in helptable:
216 for h in helptable:
202 names, sec, doc = h[0:3]
217 names, sec, doc = h[0:3]
203 if exclude and names[0] in exclude:
218 if exclude and names[0] in exclude:
204 continue
219 continue
205 if include and names[0] not in include:
220 if include and names[0] not in include:
206 continue
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 for name in names:
260 for name in names:
208 ui.write(b".. _%s:\n" % name)
261 ui.write(b".. _%s:\n" % name)
209 ui.write(b"\n")
262 ui.write(b"\n")
@@ -215,7 +268,7 b' def helpprinter(ui, helptable, sectionfu'
215 ui.write(b"\n")
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 """Render restructuredtext describing a list of commands and their
272 """Render restructuredtext describing a list of commands and their
220 documentations, grouped by command category.
273 documentations, grouped by command category.
221
274
@@ -236,11 +289,7 b' def commandprinter(ui, cmdtable, section'
236 sectionfunc: minirst function to format command category headers
289 sectionfunc: minirst function to format command category headers
237 subsectionfunc: minirst function to format command headers
290 subsectionfunc: minirst function to format command headers
238 """
291 """
239 h = {}
292 h = allcommandnames(cmdtable, debugcmds=debugcmds)
240 for c, attr in cmdtable.items():
241 f = c.split(b"|")[0]
242 f = f.lstrip(b"^")
243 h[f] = c
244 cmds = h.keys()
293 cmds = h.keys()
245
294
246 def helpcategory(cmd):
295 def helpcategory(cmd):
@@ -277,8 +326,6 b' def commandprinter(ui, cmdtable, section'
277 ui.write(sectionfunc(help.CATEGORY_NAMES[category]))
326 ui.write(sectionfunc(help.CATEGORY_NAMES[category]))
278 # Print each command in the category
327 # Print each command in the category
279 for f in sorted(categorycmds):
328 for f in sorted(categorycmds):
280 if f.startswith(b"debug"):
281 continue
282 d = get_cmd(h[f], cmdtable)
329 d = get_cmd(h[f], cmdtable)
283 ui.write(subsectionfunc(d[b'cmd']))
330 ui.write(subsectionfunc(d[b'cmd']))
284 # short description
331 # short description
@@ -293,28 +340,12 b' def commandprinter(ui, cmdtable, section'
293 ui.write(b'\n')
340 ui.write(b'\n')
294 # description
341 # description
295 ui.write(b"%s\n\n" % d[b'desc'][1])
342 ui.write(b"%s\n\n" % d[b'desc'][1])
343
296 # options
344 # options
297 opt_output = list(d[b'opts'])
345 def _optsection(s):
298 if opt_output:
346 return b"%s:\n\n" % s
299 opts_len = max([len(line[0]) for line in opt_output])
347
300 ui.write(_(b"Options:\n\n"))
348 _optionsprinter(ui, d, _optsection)
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")
318 # aliases
349 # aliases
319 if d[b'aliases']:
350 if d[b'aliases']:
320 # Note the empty comment, this is required to separate this
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 def allextensionnames():
400 def allextensionnames():
401 """Get a set of all known extension names"""
329 return set(extensions.enabled().keys()) | set(extensions.disabled().keys())
402 return set(extensions.enabled().keys()) | set(extensions.disabled().keys())
330
403
331
404
332 if __name__ == "__main__":
405 if __name__ == "__main__":
333 doc = b'hg.1.gendoc'
406 parser = argparse.ArgumentParser(
334 if len(sys.argv) > 1:
407 prog='gendoc', description="Generate mercurial documentation files"
335 doc = encoding.strtolocal(sys.argv[1])
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 ui = uimod.ui.load()
421 ui = uimod.ui.load()
338 # Trigger extensions to load. This is disabled by default because it uses
422 # Trigger extensions to load. This is disabled by default because it uses
@@ -340,7 +424,10 b' if __name__ == "__main__":'
340 if encoding.environ.get(b'GENDOC_LOAD_CONFIGURED_EXTENSIONS', b'0') != b'0':
424 if encoding.environ.get(b'GENDOC_LOAD_CONFIGURED_EXTENSIONS', b'0') != b'0':
341 extensions.loadall(ui)
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 if doc == b'hg.1.gendoc':
430 if doc == b'hg.1.gendoc':
344 showdoc(ui)
431 showdoc(ui)
345 else:
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