##// END OF EJS Templates
doc: gendoc.py creates valid output for option descriptions with newlines...
Simon Heimberg -
r20655:37f3be9d default
parent child Browse files
Show More
@@ -1,200 +1,203 b''
1 """usage: %s DOC ...
1 """usage: %s DOC ...
2
2
3 where DOC is the name of a document
3 where DOC is the name of a document
4 """
4 """
5
5
6 import os, sys, textwrap
6 import os, sys, textwrap
7 # import from the live mercurial repo
7 # import from the live mercurial repo
8 sys.path.insert(0, "..")
8 sys.path.insert(0, "..")
9 # fall back to pure modules if required C extensions are not available
9 # fall back to pure modules if required C extensions are not available
10 sys.path.append(os.path.join('..', 'mercurial', 'pure'))
10 sys.path.append(os.path.join('..', 'mercurial', 'pure'))
11 from mercurial import demandimport; demandimport.enable()
11 from mercurial import demandimport; demandimport.enable()
12 from mercurial import minirst
12 from mercurial import minirst
13 from mercurial.commands import table, globalopts
13 from mercurial.commands import table, globalopts
14 from mercurial.i18n import gettext, _
14 from mercurial.i18n import gettext, _
15 from mercurial.help import helptable, loaddoc
15 from mercurial.help import helptable, loaddoc
16 from mercurial import extensions
16 from mercurial import extensions
17 from mercurial import util
17 from mercurial import util
18
18
19 def get_desc(docstr):
19 def get_desc(docstr):
20 if not docstr:
20 if not docstr:
21 return "", ""
21 return "", ""
22 # sanitize
22 # sanitize
23 docstr = docstr.strip("\n")
23 docstr = docstr.strip("\n")
24 docstr = docstr.rstrip()
24 docstr = docstr.rstrip()
25 shortdesc = docstr.splitlines()[0].strip()
25 shortdesc = docstr.splitlines()[0].strip()
26
26
27 i = docstr.find("\n")
27 i = docstr.find("\n")
28 if i != -1:
28 if i != -1:
29 desc = docstr[i + 2:]
29 desc = docstr[i + 2:]
30 else:
30 else:
31 desc = shortdesc
31 desc = shortdesc
32
32
33 desc = textwrap.dedent(desc)
33 desc = textwrap.dedent(desc)
34
34
35 return (shortdesc, desc)
35 return (shortdesc, desc)
36
36
37 def get_opts(opts):
37 def get_opts(opts):
38 for opt in opts:
38 for opt in opts:
39 if len(opt) == 5:
39 if len(opt) == 5:
40 shortopt, longopt, default, desc, optlabel = opt
40 shortopt, longopt, default, desc, optlabel = opt
41 else:
41 else:
42 shortopt, longopt, default, desc = opt
42 shortopt, longopt, default, desc = opt
43 optlabel = _("VALUE")
43 optlabel = _("VALUE")
44 allopts = []
44 allopts = []
45 if shortopt:
45 if shortopt:
46 allopts.append("-%s" % shortopt)
46 allopts.append("-%s" % shortopt)
47 if longopt:
47 if longopt:
48 allopts.append("--%s" % longopt)
48 allopts.append("--%s" % longopt)
49 if isinstance(default, list):
49 if isinstance(default, list):
50 allopts[-1] += " <%s[+]>" % optlabel
50 allopts[-1] += " <%s[+]>" % optlabel
51 elif (default is not None) and not isinstance(default, bool):
51 elif (default is not None) and not isinstance(default, bool):
52 allopts[-1] += " <%s>" % optlabel
52 allopts[-1] += " <%s>" % optlabel
53 if '\n' in desc:
54 # only remove line breaks and indentation
55 desc = ' '.join(l.lstrip() for l in desc.split('\n'))
53 desc += default and _(" (default: %s)") % default or ""
56 desc += default and _(" (default: %s)") % default or ""
54 yield (", ".join(allopts), desc)
57 yield (", ".join(allopts), desc)
55
58
56 def get_cmd(cmd, cmdtable):
59 def get_cmd(cmd, cmdtable):
57 d = {}
60 d = {}
58 attr = cmdtable[cmd]
61 attr = cmdtable[cmd]
59 cmds = cmd.lstrip("^").split("|")
62 cmds = cmd.lstrip("^").split("|")
60
63
61 d['cmd'] = cmds[0]
64 d['cmd'] = cmds[0]
62 d['aliases'] = cmd.split("|")[1:]
65 d['aliases'] = cmd.split("|")[1:]
63 d['desc'] = get_desc(gettext(attr[0].__doc__))
66 d['desc'] = get_desc(gettext(attr[0].__doc__))
64 d['opts'] = list(get_opts(attr[1]))
67 d['opts'] = list(get_opts(attr[1]))
65
68
66 s = 'hg ' + cmds[0]
69 s = 'hg ' + cmds[0]
67 if len(attr) > 2:
70 if len(attr) > 2:
68 if not attr[2].startswith('hg'):
71 if not attr[2].startswith('hg'):
69 s += ' ' + attr[2]
72 s += ' ' + attr[2]
70 else:
73 else:
71 s = attr[2]
74 s = attr[2]
72 d['synopsis'] = s.strip()
75 d['synopsis'] = s.strip()
73
76
74 return d
77 return d
75
78
76 def showdoc(ui):
79 def showdoc(ui):
77 # print options
80 # print options
78 ui.write(minirst.section(_("Options")))
81 ui.write(minirst.section(_("Options")))
79 multioccur = False
82 multioccur = False
80 for optstr, desc in get_opts(globalopts):
83 for optstr, desc in get_opts(globalopts):
81 ui.write("%s\n %s\n\n" % (optstr, desc))
84 ui.write("%s\n %s\n\n" % (optstr, desc))
82 if optstr.endswith("[+]>"):
85 if optstr.endswith("[+]>"):
83 multioccur = True
86 multioccur = True
84 if multioccur:
87 if multioccur:
85 ui.write(_("\n[+] marked option can be specified multiple times\n"))
88 ui.write(_("\n[+] marked option can be specified multiple times\n"))
86 ui.write("\n")
89 ui.write("\n")
87
90
88 # print cmds
91 # print cmds
89 ui.write(minirst.section(_("Commands")))
92 ui.write(minirst.section(_("Commands")))
90 commandprinter(ui, table, minirst.subsection)
93 commandprinter(ui, table, minirst.subsection)
91
94
92 # print help topics
95 # print help topics
93 # The config help topic is included in the hgrc.5 man page.
96 # The config help topic is included in the hgrc.5 man page.
94 helpprinter(ui, helptable, minirst.section, exclude=['config'])
97 helpprinter(ui, helptable, minirst.section, exclude=['config'])
95
98
96 ui.write(minirst.section(_("Extensions")))
99 ui.write(minirst.section(_("Extensions")))
97 ui.write(_("This section contains help for extensions that are "
100 ui.write(_("This section contains help for extensions that are "
98 "distributed together with Mercurial. Help for other "
101 "distributed together with Mercurial. Help for other "
99 "extensions is available in the help system."))
102 "extensions is available in the help system."))
100 ui.write("\n\n"
103 ui.write("\n\n"
101 ".. contents::\n"
104 ".. contents::\n"
102 " :class: htmlonly\n"
105 " :class: htmlonly\n"
103 " :local:\n"
106 " :local:\n"
104 " :depth: 1\n\n")
107 " :depth: 1\n\n")
105
108
106 for extensionname in sorted(allextensionnames()):
109 for extensionname in sorted(allextensionnames()):
107 mod = extensions.load(None, extensionname, None)
110 mod = extensions.load(None, extensionname, None)
108 ui.write(minirst.subsection(extensionname))
111 ui.write(minirst.subsection(extensionname))
109 ui.write("%s\n\n" % gettext(mod.__doc__))
112 ui.write("%s\n\n" % gettext(mod.__doc__))
110 cmdtable = getattr(mod, 'cmdtable', None)
113 cmdtable = getattr(mod, 'cmdtable', None)
111 if cmdtable:
114 if cmdtable:
112 ui.write(minirst.subsubsection(_('Commands')))
115 ui.write(minirst.subsubsection(_('Commands')))
113 commandprinter(ui, cmdtable, minirst.subsubsubsection)
116 commandprinter(ui, cmdtable, minirst.subsubsubsection)
114
117
115 def showtopic(ui, topic):
118 def showtopic(ui, topic):
116 extrahelptable = [
119 extrahelptable = [
117 (["common"], '', loaddoc('common')),
120 (["common"], '', loaddoc('common')),
118 (["hg.1"], '', loaddoc('hg.1')),
121 (["hg.1"], '', loaddoc('hg.1')),
119 (["hgignore.5"], '', loaddoc('hgignore.5')),
122 (["hgignore.5"], '', loaddoc('hgignore.5')),
120 (["hgrc.5"], '', loaddoc('hgrc.5')),
123 (["hgrc.5"], '', loaddoc('hgrc.5')),
121 (["hgignore.5.gendoc"], '', loaddoc('hgignore')),
124 (["hgignore.5.gendoc"], '', loaddoc('hgignore')),
122 (["hgrc.5.gendoc"], '', loaddoc('config')),
125 (["hgrc.5.gendoc"], '', loaddoc('config')),
123 ]
126 ]
124 helpprinter(ui, helptable + extrahelptable, None, include=[topic])
127 helpprinter(ui, helptable + extrahelptable, None, include=[topic])
125
128
126 def helpprinter(ui, helptable, sectionfunc, include=[], exclude=[]):
129 def helpprinter(ui, helptable, sectionfunc, include=[], exclude=[]):
127 for names, sec, doc in helptable:
130 for names, sec, doc in helptable:
128 if exclude and names[0] in exclude:
131 if exclude and names[0] in exclude:
129 continue
132 continue
130 if include and names[0] not in include:
133 if include and names[0] not in include:
131 continue
134 continue
132 for name in names:
135 for name in names:
133 ui.write(".. _%s:\n" % name)
136 ui.write(".. _%s:\n" % name)
134 ui.write("\n")
137 ui.write("\n")
135 if sectionfunc:
138 if sectionfunc:
136 ui.write(sectionfunc(sec))
139 ui.write(sectionfunc(sec))
137 if util.safehasattr(doc, '__call__'):
140 if util.safehasattr(doc, '__call__'):
138 doc = doc()
141 doc = doc()
139 ui.write(doc)
142 ui.write(doc)
140 ui.write("\n")
143 ui.write("\n")
141
144
142 def commandprinter(ui, cmdtable, sectionfunc):
145 def commandprinter(ui, cmdtable, sectionfunc):
143 h = {}
146 h = {}
144 for c, attr in cmdtable.items():
147 for c, attr in cmdtable.items():
145 f = c.split("|")[0]
148 f = c.split("|")[0]
146 f = f.lstrip("^")
149 f = f.lstrip("^")
147 h[f] = c
150 h[f] = c
148 cmds = h.keys()
151 cmds = h.keys()
149 cmds.sort()
152 cmds.sort()
150
153
151 for f in cmds:
154 for f in cmds:
152 if f.startswith("debug"):
155 if f.startswith("debug"):
153 continue
156 continue
154 d = get_cmd(h[f], cmdtable)
157 d = get_cmd(h[f], cmdtable)
155 ui.write(sectionfunc(d['cmd']))
158 ui.write(sectionfunc(d['cmd']))
156 # synopsis
159 # synopsis
157 ui.write("::\n\n")
160 ui.write("::\n\n")
158 synopsislines = d['synopsis'].splitlines()
161 synopsislines = d['synopsis'].splitlines()
159 for line in synopsislines:
162 for line in synopsislines:
160 # some commands (such as rebase) have a multi-line
163 # some commands (such as rebase) have a multi-line
161 # synopsis
164 # synopsis
162 ui.write(" %s\n" % line)
165 ui.write(" %s\n" % line)
163 ui.write('\n')
166 ui.write('\n')
164 # description
167 # description
165 ui.write("%s\n\n" % d['desc'][1])
168 ui.write("%s\n\n" % d['desc'][1])
166 # options
169 # options
167 opt_output = list(d['opts'])
170 opt_output = list(d['opts'])
168 if opt_output:
171 if opt_output:
169 opts_len = max([len(line[0]) for line in opt_output])
172 opts_len = max([len(line[0]) for line in opt_output])
170 ui.write(_("Options:\n\n"))
173 ui.write(_("Options:\n\n"))
171 multioccur = False
174 multioccur = False
172 for optstr, desc in opt_output:
175 for optstr, desc in opt_output:
173 if desc:
176 if desc:
174 s = "%-*s %s" % (opts_len, optstr, desc)
177 s = "%-*s %s" % (opts_len, optstr, desc)
175 else:
178 else:
176 s = optstr
179 s = optstr
177 ui.write("%s\n" % s)
180 ui.write("%s\n" % s)
178 if optstr.endswith("[+]>"):
181 if optstr.endswith("[+]>"):
179 multioccur = True
182 multioccur = True
180 if multioccur:
183 if multioccur:
181 ui.write(_("\n[+] marked option can be specified"
184 ui.write(_("\n[+] marked option can be specified"
182 " multiple times\n"))
185 " multiple times\n"))
183 ui.write("\n")
186 ui.write("\n")
184 # aliases
187 # aliases
185 if d['aliases']:
188 if d['aliases']:
186 ui.write(_(" aliases: %s\n\n") % " ".join(d['aliases']))
189 ui.write(_(" aliases: %s\n\n") % " ".join(d['aliases']))
187
190
188
191
189 def allextensionnames():
192 def allextensionnames():
190 return extensions.enabled().keys() + extensions.disabled().keys()
193 return extensions.enabled().keys() + extensions.disabled().keys()
191
194
192 if __name__ == "__main__":
195 if __name__ == "__main__":
193 doc = 'hg.1.gendoc'
196 doc = 'hg.1.gendoc'
194 if len(sys.argv) > 1:
197 if len(sys.argv) > 1:
195 doc = sys.argv[1]
198 doc = sys.argv[1]
196
199
197 if doc == 'hg.1.gendoc':
200 if doc == 'hg.1.gendoc':
198 showdoc(sys.stdout)
201 showdoc(sys.stdout)
199 else:
202 else:
200 showtopic(sys.stdout, sys.argv[1])
203 showtopic(sys.stdout, sys.argv[1])
General Comments 0
You need to be logged in to leave comments. Login now