gendoc.py
209 lines
| 6.4 KiB
| text/x-python
|
PythonLexer
/ doc / gendoc.py
|
r27496 | #!/usr/bin/env python | ||
|
r19425 | """usage: %s DOC ... | ||
where DOC is the name of a document | ||||
""" | ||||
|
r12780 | import os, sys, textwrap | ||
|
r27330 | |||
# This script is executed during installs and may not have C extensions | ||||
# available. Relax C module requirements. | ||||
os.environ['HGMODULEPOLICY'] = 'allow' | ||||
|
r1814 | # import from the live mercurial repo | ||
sys.path.insert(0, "..") | ||||
|
r5209 | from mercurial import demandimport; demandimport.enable() | ||
|
r18748 | from mercurial import minirst | ||
|
r1814 | from mercurial.commands import table, globalopts | ||
|
r19231 | from mercurial.i18n import gettext, _ | ||
|
r19424 | from mercurial.help import helptable, loaddoc | ||
|
r12781 | from mercurial import extensions | ||
|
r26412 | from mercurial import ui as uimod | ||
|
r1814 | |||
def get_desc(docstr): | ||||
if not docstr: | ||||
return "", "" | ||||
# sanitize | ||||
docstr = docstr.strip("\n") | ||||
docstr = docstr.rstrip() | ||||
shortdesc = docstr.splitlines()[0].strip() | ||||
i = docstr.find("\n") | ||||
if i != -1: | ||||
|
r10282 | desc = docstr[i + 2:] | ||
|
r1814 | else: | ||
|
r12780 | desc = shortdesc | ||
desc = textwrap.dedent(desc) | ||||
|
r1814 | return (shortdesc, desc) | ||
def get_opts(opts): | ||||
|
r11321 | for opt in opts: | ||
if len(opt) == 5: | ||||
shortopt, longopt, default, desc, optlabel = opt | ||||
else: | ||||
shortopt, longopt, default, desc = opt | ||||
|
r20081 | optlabel = _("VALUE") | ||
|
r1814 | allopts = [] | ||
if shortopt: | ||||
allopts.append("-%s" % shortopt) | ||||
if longopt: | ||||
allopts.append("--%s" % longopt) | ||||
|
r20081 | if isinstance(default, list): | ||
allopts[-1] += " <%s[+]>" % optlabel | ||||
elif (default is not None) and not isinstance(default, bool): | ||||
allopts[-1] += " <%s>" % optlabel | ||||
|
r20655 | if '\n' in desc: | ||
# only remove line breaks and indentation | ||||
desc = ' '.join(l.lstrip() for l in desc.split('\n')) | ||||
|
r1814 | desc += default and _(" (default: %s)") % default or "" | ||
|
r13077 | yield (", ".join(allopts), desc) | ||
|
r1814 | |||
|
r12756 | def get_cmd(cmd, cmdtable): | ||
|
r1814 | d = {} | ||
|
r12756 | attr = cmdtable[cmd] | ||
|
r1814 | cmds = cmd.lstrip("^").split("|") | ||
d['cmd'] = cmds[0] | ||||
d['aliases'] = cmd.split("|")[1:] | ||||
|
r19231 | d['desc'] = get_desc(gettext(attr[0].__doc__)) | ||
|
r1814 | d['opts'] = list(get_opts(attr[1])) | ||
|
r7376 | |||
s = 'hg ' + cmds[0] | ||||
if len(attr) > 2: | ||||
if not attr[2].startswith('hg'): | ||||
|
r8546 | s += ' ' + attr[2] | ||
|
r7376 | else: | ||
s = attr[2] | ||||
|
r9622 | d['synopsis'] = s.strip() | ||
|
r7376 | |||
|
r1814 | return d | ||
|
r19423 | def showdoc(ui): | ||
|
r1814 | # print options | ||
|
r18748 | ui.write(minirst.section(_("Options"))) | ||
|
r20081 | multioccur = False | ||
|
r1814 | for optstr, desc in get_opts(globalopts): | ||
|
r12812 | ui.write("%s\n %s\n\n" % (optstr, desc)) | ||
|
r20081 | if optstr.endswith("[+]>"): | ||
multioccur = True | ||||
if multioccur: | ||||
ui.write(_("\n[+] marked option can be specified multiple times\n")) | ||||
ui.write("\n") | ||||
|
r1814 | |||
# print cmds | ||||
|
r18748 | ui.write(minirst.section(_("Commands"))) | ||
commandprinter(ui, table, minirst.subsection) | ||||
|
r12756 | |||
|
r19233 | # print help topics | ||
# The config help topic is included in the hgrc.5 man page. | ||||
helpprinter(ui, helptable, minirst.section, exclude=['config']) | ||||
|
r12756 | |||
|
r18748 | ui.write(minirst.section(_("Extensions"))) | ||
|
r16683 | ui.write(_("This section contains help for extensions that are " | ||
"distributed together with Mercurial. Help for other " | ||||
"extensions is available in the help system.")) | ||||
|
r12781 | ui.write("\n\n" | ||
".. contents::\n" | ||||
" :class: htmlonly\n" | ||||
" :local:\n" | ||||
" :depth: 1\n\n") | ||||
for extensionname in sorted(allextensionnames()): | ||||
mod = extensions.load(None, extensionname, None) | ||||
|
r18748 | ui.write(minirst.subsection(extensionname)) | ||
|
r19231 | ui.write("%s\n\n" % gettext(mod.__doc__)) | ||
|
r12781 | cmdtable = getattr(mod, 'cmdtable', None) | ||
if cmdtable: | ||||
|
r18748 | ui.write(minirst.subsubsection(_('Commands'))) | ||
commandprinter(ui, cmdtable, minirst.subsubsubsection) | ||||
|
r12781 | |||
|
r19424 | def showtopic(ui, topic): | ||
extrahelptable = [ | ||||
(["common"], '', loaddoc('common')), | ||||
(["hg.1"], '', loaddoc('hg.1')), | ||||
(["hgignore.5"], '', loaddoc('hgignore.5')), | ||||
(["hgrc.5"], '', loaddoc('hgrc.5')), | ||||
(["hgignore.5.gendoc"], '', loaddoc('hgignore')), | ||||
(["hgrc.5.gendoc"], '', loaddoc('config')), | ||||
] | ||||
helpprinter(ui, helptable + extrahelptable, None, include=[topic]) | ||||
|
r19233 | def helpprinter(ui, helptable, sectionfunc, include=[], exclude=[]): | ||
for names, sec, doc in helptable: | ||||
if exclude and names[0] in exclude: | ||||
continue | ||||
if include and names[0] not in include: | ||||
continue | ||||
for name in names: | ||||
ui.write(".. _%s:\n" % name) | ||||
ui.write("\n") | ||||
if sectionfunc: | ||||
ui.write(sectionfunc(sec)) | ||||
|
r21793 | if callable(doc): | ||
|
r26413 | doc = doc(ui) | ||
|
r19233 | ui.write(doc) | ||
ui.write("\n") | ||||
|
r12781 | def commandprinter(ui, cmdtable, sectionfunc): | ||
|
r1814 | h = {} | ||
|
r12756 | for c, attr in cmdtable.items(): | ||
|
r6488 | f = c.split("|")[0] | ||
f = f.lstrip("^") | ||||
h[f] = c | ||||
|
r1814 | cmds = h.keys() | ||
cmds.sort() | ||||
for f in cmds: | ||||
|
r10282 | if f.startswith("debug"): | ||
continue | ||||
|
r12756 | d = get_cmd(h[f], cmdtable) | ||
|
r18748 | ui.write(sectionfunc(d['cmd'])) | ||
|
r20689 | # short description | ||
ui.write(d['desc'][0]) | ||||
|
r6488 | # synopsis | ||
|
r12813 | ui.write("::\n\n") | ||
synopsislines = d['synopsis'].splitlines() | ||||
for line in synopsislines: | ||||
# some commands (such as rebase) have a multi-line | ||||
# synopsis | ||||
|
r12814 | ui.write(" %s\n" % line) | ||
|
r12813 | ui.write('\n') | ||
|
r6488 | # description | ||
ui.write("%s\n\n" % d['desc'][1]) | ||||
# options | ||||
opt_output = list(d['opts']) | ||||
if opt_output: | ||||
opts_len = max([len(line[0]) for line in opt_output]) | ||||
|
r13345 | ui.write(_("Options:\n\n")) | ||
|
r20081 | multioccur = False | ||
|
r6488 | for optstr, desc in opt_output: | ||
if desc: | ||||
s = "%-*s %s" % (opts_len, optstr, desc) | ||||
else: | ||||
s = optstr | ||||
|
r12780 | ui.write("%s\n" % s) | ||
|
r20081 | if optstr.endswith("[+]>"): | ||
multioccur = True | ||||
if multioccur: | ||||
ui.write(_("\n[+] marked option can be specified" | ||||
" multiple times\n")) | ||||
|
r6488 | ui.write("\n") | ||
# aliases | ||||
if d['aliases']: | ||||
ui.write(_(" aliases: %s\n\n") % " ".join(d['aliases'])) | ||||
|
r1814 | |||
|
r3797 | |||
|
r12781 | def allextensionnames(): | ||
|
r14316 | return extensions.enabled().keys() + extensions.disabled().keys() | ||
|
r12781 | |||
|
r1814 | if __name__ == "__main__": | ||
|
r19425 | doc = 'hg.1.gendoc' | ||
if len(sys.argv) > 1: | ||||
doc = sys.argv[1] | ||||
|
r26412 | ui = uimod.ui() | ||
|
r19425 | if doc == 'hg.1.gendoc': | ||
|
r26412 | showdoc(ui) | ||
|
r19425 | else: | ||
|
r26412 | showtopic(ui, sys.argv[1]) | ||