##// END OF EJS Templates
doc: generate separate commands/topics/extension pages...
Ludovic Chabant -
r52914:2a875530 default
parent child Browse files
Show More
@@ -0,0 +1,22 b''
1 .. _hg-%(cmdname)s.1:
2
3 %(cmdtitle)s
4
5 %(cmdshortdesc)s
6
7 .. contents::
8 :backlinks: top
9 :class: htmlonly
10 :depth: 1
11
12 Synopsis
13 --------
14
15 ::
16
17 %(cmdsynopsis)s
18
19 Description
20 -----------
21 %(cmdlongdesc)s
22
@@ -0,0 +1,9 b''
1 .. _ext-%(extname)s:
2
3 %(exttitle)s
4
5 .. contents::
6 :backlinks: top
7 :class: htmlonly
8 :depth: 2
9
@@ -0,0 +1,9 b''
1 .. _topic-%(topicname)s:
2
3 %(topictitle)s
4
5 .. contents::
6 :backlinks: top
7 :class: htmlonly
8 :depth: 2
9
@@ -40,10 +40,17 b' contrib/merge-lists/target/'
40 dist
40 dist
41 packages
41 packages
42 doc/common.txt
42 doc/common.txt
43 doc/commandlist.txt
44 doc/extensionlist.txt
45 doc/topiclist.txt
46 doc/*.mk
43 doc/*.[0-9]
47 doc/*.[0-9]
44 doc/*.[0-9].txt
48 doc/*.[0-9].txt
45 doc/*.[0-9].gendoc.txt
49 doc/*.[0-9].gendoc.txt
46 doc/*.[0-9].{x,ht}ml
50 doc/*.[0-9].{x,ht}ml
51 doc/build
52 doc/html
53 doc/man
47 MANIFEST
54 MANIFEST
48 MANIFEST.in
55 MANIFEST.in
49 patches
56 patches
@@ -3,6 +3,7 b' MAN=$(SOURCES:%.txt=%)'
3 HTML=$(SOURCES:%.txt=%.html)
3 HTML=$(SOURCES:%.txt=%.html)
4 GENDOC=gendoc.py ../mercurial/commands.py ../mercurial/help.py \
4 GENDOC=gendoc.py ../mercurial/commands.py ../mercurial/help.py \
5 ../mercurial/helptext/*.txt ../hgext/*.py ../hgext/*/__init__.py
5 ../mercurial/helptext/*.txt ../hgext/*.py ../hgext/*/__init__.py
6 RUNRST=runrst
6 PREFIX=/usr/local
7 PREFIX=/usr/local
7 MANDIR=$(PREFIX)/share/man
8 MANDIR=$(PREFIX)/share/man
8 INSTALL=install -m 644
9 INSTALL=install -m 644
@@ -14,10 +15,150 b' PYTHON?=py -3'
14 else
15 else
15 PYTHON?=python3
16 PYTHON?=python3
16 endif
17 endif
18
17 RSTARGS=
19 RSTARGS=
20 GENDOCARGS=
21 GENDOCCMD=$(PYTHON) gendoc.py $(GENDOCARGS)
22
23 # Output directories for individual help pages.
24 MANOUT=man
25 HTMLOUT=html
26 BUILDDIR=build
18
27
19 export HGENCODING=UTF-8
28 export HGENCODING=UTF-8
20
29
30 .PHONY: all man html install clean knownrefs
31
32 # Generate a list of hg commands and extensions.
33 commandlist.txt: $(GENDOC)
34 ${GENDOCCMD} commandlist > $@.tmp
35 mv $@.tmp $@
36
37 topiclist.txt: $(GENDOC)
38 ${GENDOCCMD} topiclist > $@.tmp
39 mv $@.tmp $@
40
41 extensionlist.txt: $(GENDOC)
42 ${GENDOCCMD} extensionlist > $@.tmp
43 mv $@.tmp $@
44
45 # Build target for running runrst more easily by hand
46 knownrefs: commandlist.txt topiclist.txt extensionlist.txt
47
48 BUILDFILES=commandlist.txt topiclist.txt extensionlist.txt
49
50 # We want to generate a sub-Makefile that can build the RST/man/html doc for
51 # each hg command. Here are templates that we'll use to generate this
52 # sub-Makefile.
53 HGCMDTPL=templates/cmdheader.txt
54 TOPICTPL=templates/topicheader.txt
55 EXTTPL=templates/extheader.txt
56
57 define RuleAllCommandsTemplate
58 HG_COMMANDS=$(1)
59 all-commands: $$(HG_COMMANDS:%=$$(BUILDDIR)/hg-%.gendoc.txt)
60 endef
61
62 define RuleAllTopicsTemplate
63 HG_TOPICS=$(1)
64 all-topics: $$(HG_TOPICS:%=$$(BUILDDIR)/%.gendoc.txt)
65 endef
66
67 define RuleAllExtensionsTemplate
68 HG_EXTENSIONS=$(1)
69 all-extensions: $$(HG_EXTENSIONS:%=$$(BUILDDIR)/%.gendoc.txt)
70 endef
71
72 define RuleCommandTemplate
73 $$(BUILDDIR)/hg-$C.gendoc.txt: $$(GENDOC) $$(HGCMDTPL)
74 mkdir -p $$(@D)
75 $${GENDOCCMD} cmd-$C > $$@.tmp
76 mv $$@.tmp $$@
77 endef
78
79 define RuleTopicTemplate
80 $$(BUILDDIR)/topic-$T.gendoc.txt: $$(GENDOC) $$(TOPICTPL)
81 mkdir -p $$(@D)
82 $${GENDOCCMD} topic-$T > $$@.tmp
83 mv $$@.tmp $$@
84 endef
85
86 define RuleExtensionTemplate
87 $$(BUILDDIR)/ext-$E.gendoc.txt: $$(GENDOC) $$(EXTTPL)
88 mkdir -p $$(@D)
89 $${GENDOCCMD} ext-$E > $$@.tmp
90 mv $$@.tmp $$@
91 endef
92
93 # Actually generate the sub-Makefile.
94 # The $file function is only supported by GNU Make 4 and above.
95 CommandsTopicsExtensions.mk: commandlist.txt topiclist.txt extensionlist.txt Makefile
96 ifeq (4.0,$(firstword $(sort $(MAKE_VERSION) 4.0)))
97 $(file > $@.tmp,# Generated by Makefile)
98 $(file >> $@.tmp,$(call RuleAllCommandsTemplate,$(file < commandlist.txt)))
99 $(file >> $@.tmp,$(call RuleAllTopicsTemplate,$(file < topiclist.txt)))
100 $(file >> $@.tmp,$(call RuleAllExtensionsTemplate,$(file < extensionlist.txt)))
101 $(foreach C,$(file < commandlist.txt),$(file >> $@.tmp,$(RuleCommandTemplate)))
102 $(foreach T,$(file < topiclist.txt),$(file >> $@.tmp,$(RuleTopicTemplate)))
103 $(foreach E,$(file < extensionlist.txt),$(file >> $@.tmp,$(RuleExtensionTemplate)))
104 mv $@.tmp $@
105 else
106 @echo "You are running make ${MAKE_VERSION} but you need make 4.0 or above"
107 endif
108
109 BUILDFILES+=CommandsTopicsExtensions.mk
110
111 # Include the sub-Makefile that contains rules for generating each individual
112 # command/help-topic/extension help page. This sub-Makefile is created by the
113 # rule above (CommandsTopicsExtensions.mk) which in turn is created from the
114 # plain-text lists of commands/help-topics/extensions.
115 #
116 # Any time the source code changes, these plain-text lists and this
117 # sub-Makefile will get regenerated. Make will then restart itself to take
118 # into account the rules inside the sub-Makefile.
119 #
120 # We want to avoid doing all this work for targets that we know don't need it
121 # however. For example, running `make clean` would only generate these files
122 # in order to delete them immediately. As a result, we don't include the
123 # sub-Makefile (and therefore don't require generating it) if clean is one of
124 # the targets. This might not do what we want when other targets are specified
125 # but it's most likely what we want.
126 ifeq (,$(filter clean,$(MAKECMDGOALS)))
127 -include CommandsTopicsExtensions.mk
128 endif
129
130 # If the sub-Makefile is available, add all the hg commands, help-topics, and
131 # extensions to the list of things to generate html and man pages for.
132 #
133 # Naming convention:
134 # - commands: hg-foo (html and man)
135 # - help topics: topic-foo (html), hgfoo (man)
136 # - extensions: ext-foo (html), hgext-foo (man)
137 #
138 # Man pages for commands are in section 1 (user commands), topics and
139 # extensions are in section 7 (miscellanea)
140 #
141 # NOTE: topics and extension are temporarily disabled for man pages because
142 # they make docutils' RST converter crash.
143 ifdef HG_COMMANDS
144 HTML+=$(HG_COMMANDS:%=$(HTMLOUT)/hg-%.html)
145 MAN+=$(HG_COMMANDS:%=$(MANOUT)/hg-%.1)
146 endif
147
148 ifdef HG_TOPICS
149 HTML+=$(HG_TOPICS:%=$(HTMLOUT)/topic-%.html)
150 #MAN+=$(HG_TOPICS:%=$(MANOUT)/hg%.7)
151 endif
152
153 ifdef HG_EXTENSIONS
154 HTML+=$(HG_EXTENSIONS:%=$(HTMLOUT)/ext-%.html)
155 #MAN+=$(HG_EXTENSIONS:%=$(MANOUT)/hgext-%.7)
156 endif
157
158 # Also add the HTML index page
159 HTML+=$(HTMLOUT)/index.html
160
161
21 all: man html
162 all: man html
22
163
23 man: $(MAN)
164 man: $(MAN)
@@ -26,17 +167,45 b' html: $(HTML)'
26
167
27 # This logic is duplicated in setup.py:hgbuilddoc()
168 # This logic is duplicated in setup.py:hgbuilddoc()
28 common.txt $(SOURCES) $(SOURCES:%.txt=%.gendoc.txt): $(GENDOC)
169 common.txt $(SOURCES) $(SOURCES:%.txt=%.gendoc.txt): $(GENDOC)
29 ${PYTHON} gendoc.py "$(basename $@)" > $@.tmp
170 ${GENDOCCMD} "$(basename $@)" > $@.tmp
30 mv $@.tmp $@
171 mv $@.tmp $@
31
172
32 %: %.txt %.gendoc.txt common.txt
173 %: %.txt %.gendoc.txt common.txt $(RUNRST)
33 $(PYTHON) runrst hgmanpage $(RSTARGS) --halt warning \
174 $(PYTHON) runrst hgmanpage $(RSTARGS) --halt warning \
34 --strip-elements-with-class htmlonly $*.txt $*
175 --strip-elements-with-class htmlonly $*.txt $*
35
176
36 %.html: %.txt %.gendoc.txt common.txt
177 %.html: %.txt %.gendoc.txt common.txt $(RUNRST)
37 $(PYTHON) runrst html $(RSTARGS) --halt warning \
178 $(PYTHON) runrst html $(RSTARGS) --halt warning \
38 --link-stylesheet --stylesheet-path style.css $*.txt $*.html
179 --link-stylesheet --stylesheet-path style.css $*.txt $*.html
39
180
181 # Rules for index page and individual command/help-topic/extension pages
182 # Because the naming isn't the same between html and man pages, we need to
183 # break down man pages rules a bit more.
184 $(BUILDDIR)/index.gendoc.txt: $(GENDOC)
185 mkdir -p $(@D)
186 ${GENDOCCMD} index > $@.tmp
187 mv $@.tmp $@
188
189 $(MANOUT)/hg-%.1: $(BUILDDIR)/hg-%.gendoc.txt common.txt $(RUNRST)
190 mkdir -p $(@D)
191 $(PYTHON) runrst hgmanpage --hg-individual-pages $(RSTARGS) --halt warning \
192 --strip-elements-with-class htmlonly $(BUILDDIR)/hg-$*.gendoc.txt $@
193
194 $(MANOUT)/hg%.7: $(BUILDDIR)/topic-%.gendoc.txt common.txt $(RUNRST)
195 mkdir -p $(@D)
196 $(PYTHON) runrst hgmanpage --hg-individual-pages $(RSTARGS) --halt warning \
197 --strip-elements-with-class htmlonly $(BUILDDIR)/topic-$*.gendoc.txt $@
198
199 $(MANOUT)/hgext-%.7: $(BUILDDIR)/ext-%.gendoc.txt common.txt $(RUNRST)
200 mkdir -p $(@D)
201 $(PYTHON) runrst hgmanpage --hg-individual-pages $(RSTARGS) --halt warning \
202 --strip-elements-with-class htmlonly $(BUILDDIR)/ext-$*.gendoc.txt $@
203
204 $(HTMLOUT)/%.html: $(BUILDDIR)/%.gendoc.txt common.txt $(RUNRST)
205 mkdir -p $(@D)
206 $(PYTHON) runrst html --hg-individual-pages $(RSTARGS) --halt warning \
207 --link-stylesheet --stylesheet-path style.css $(BUILDDIR)/$*.gendoc.txt $@
208
40 MANIFEST: man html
209 MANIFEST: man html
41 # tracked files are already in the main MANIFEST
210 # tracked files are already in the main MANIFEST
42 $(RM) $@
211 $(RM) $@
@@ -51,5 +220,9 b' install: man'
51 $(INSTALL) $$i "$(DESTDIR)$(MANDIR)"/$$subdir ; \
220 $(INSTALL) $$i "$(DESTDIR)$(MANDIR)"/$$subdir ; \
52 done
221 done
53
222
223 # The clean target explicitly doesn't bother with the sub-Makefile, so we don't
224 # know anything about all the command/topic/extension targets and files.
225 # $(HTML) only has the basic topics, so we need to delete $(HTMLOUT)/*.html and
226 # other similar files "by hand" here.
54 clean:
227 clean:
55 $(RM) $(MAN) $(HTML) common.txt $(SOURCES) $(SOURCES:%.txt=%.gendoc.txt) MANIFEST
228 $(RM) $(MAN) $(HTML) common.txt $(SOURCES) MANIFEST *.gendoc.txt $(BUILDFILES) $(BUILDDIR)/*.gendoc.* $(HTMLOUT)/*.html
@@ -178,6 +178,202 b' def showdoc(ui, debugcmds=False):'
178 )
178 )
179
179
180
180
181 def showcommandlist(ui, debugcmds=False):
182 """Render a plain text list of all command names
183
184 Args:
185 ui: the UI object to output to
186 debugcmds: whether to include debug commands
187 """
188 cmdnames = allcommandnames(table, debugcmds=debugcmds)
189 for mainname in cmdnames.keys():
190 # Make does not like semicolons in filenames (or what it
191 # considers as filenames). We use command names as targets so
192 # it applies here. For now let's skip commands with semicolons
193 # in them (at this time it only includes the `admin::verify`
194 # advanced command).
195 if b'::' in mainname:
196 continue
197 ui.write(mainname)
198 ui.write(b" ")
199
200
201 def showtopiclist(ui):
202 """Render a plain text list of all help topic names
203
204 Args:
205 ui: the UI object to output to
206 """
207 for topic in helptable:
208 topicname = topic[0][0]
209 if help.filtertopic(ui, topicname):
210 continue
211 ui.write(topicname)
212 ui.write(b" ")
213
214
215 def showextensionlist(ui):
216 """Render a plain text list of all extension names
217
218 Args:
219 ui: the UI object to output to
220 """
221 for extensionname in allextensionnames():
222 ui.write(extensionname)
223 ui.write(b" ")
224
225
226 def showhelpindex(ui, debugcmds=False):
227 """Render restructured text for a complete mercurial help index
228
229 This index will show a list of commands, followed by a list of help topics,
230 and finally a list of extensions. These lists are split in categories and
231 ordered 'nicely' as defined by alphabetical and categeory order.
232
233 Each entry in this index is a reference to the specific help page of the
234 command, topic, or extension at hand.
235 """
236 ui.write(minirst.section(_(b"Mercurial Distributed SCM")))
237
238 missingdoc = _(b"(no help text available)")
239
240 cats, h, syns = help._getcategorizedhelpcmds(ui, table, None)
241 ui.write(minirst.subsection(_(b"Commands")))
242
243 for cat in help.CATEGORY_ORDER:
244 catfns = sorted(cats.get(cat, []))
245 if not catfns:
246 continue
247
248 catname = gettext(help.CATEGORY_NAMES[cat])
249 ui.write(minirst.subsubsection(catname))
250 for c in catfns:
251 url = b'hg-%s.html' % c
252 ui.write(b" :`%s <%s>`__: %s" % (c, url, h[c]))
253 syns[c].remove(c)
254 if syns[c]:
255 ui.write(_(b" (aliases: *%s*)") % (b', '.join(syns[c])))
256 ui.write(b"\n")
257 ui.write(b"\n\n")
258
259 ui.write(b"\n\n")
260
261 ui.write(minirst.subsection(_(b"Additional Help Topics")))
262 topiccats, topicsyns = help._getcategorizedhelptopics(ui, helptable)
263 for cat in help.TOPIC_CATEGORY_ORDER:
264 topics = topiccats.get(cat, [])
265 if not topics:
266 continue
267
268 catname = gettext(help.TOPIC_CATEGORY_NAMES[cat])
269 ui.write(minirst.subsubsection(catname))
270 for t, desc in topics:
271 url = b'topic-%s.html' % t
272 ui.write(b" :`%s <%s>`__: %s" % (t, url, desc))
273 topicsyns[t].remove(t)
274 if topicsyns[t]:
275 ui.write(_(b" (aliases: *%s*)") % (b', '.join(topicsyns[t])))
276 ui.write(b"\n")
277 ui.write(b"\n\n")
278
279 ui.write(b"\n\n")
280
281 # Add an alphabetical list of extensions, categorized by group.
282 sectionkeywords = [
283 (b"(ADVANCED)", _(b"(ADVANCED)")),
284 (b"(EXPERIMENTAL)", _(b"(EXPERIMENTAL)")),
285 (b"(DEPRECATED)", _(b"(DEPRECATED)")),
286 ]
287 extensionsections = [
288 (b"Extensions", []),
289 (b"Advanced Extensions", []),
290 (b"Experimental Extensions", []),
291 (b"Deprecated Extensions", []),
292 ]
293 for extensionname in allextensionnames():
294 mod = extensions.load(ui, extensionname, None)
295 shortdoc, longdoc = _splitdoc(mod)
296 for i, kwds in enumerate(sectionkeywords):
297 if any([kwd in shortdoc for kwd in kwds]):
298 extensionsections[i + 1][1].append(
299 (extensionname, mod, shortdoc)
300 )
301 break
302 else:
303 extensionsections[0][1].append((extensionname, mod, shortdoc))
304 for sectiontitle, extinfos in extensionsections:
305 ui.write(minirst.subsection(_(sectiontitle)))
306 for extinfo in sorted(extinfos, key=lambda ei: ei[0]):
307 extensionname, mod, shortdoc = extinfo
308 url = b'ext-%s.html' % extensionname
309 ui.write(
310 minirst.subsubsection(b'`%s <%s>`__' % (extensionname, url))
311 )
312 ui.write(shortdoc)
313 ui.write(b'\n\n')
314 cmdtable = getattr(mod, 'cmdtable', None)
315 if cmdtable:
316 cmdnames = allcommandnames(cmdtable, debugcmds=debugcmds)
317 for f in sorted(cmdnames.keys()):
318 d = get_cmd(cmdnames[f], cmdtable)
319 ui.write(b':%s: ' % d[b'cmd'])
320 ui.write(d[b'desc'][0] or (missingdoc + b"\n"))
321 ui.write(b'\n')
322 ui.write(b'\n')
323
324
325 def showcommand(ui, mainname):
326 # Always pass debugcmds=True so that we find whatever command we are told
327 # to display.
328 cmdnames = allcommandnames(table, debugcmds=True)
329 allnames = cmdnames[mainname]
330 d = get_cmd(allnames, table)
331
332 header = _rendertpl(
333 'cmdheader.txt',
334 {
335 'cmdname': mainname,
336 'cmdtitle': minirst.section(b'hg ' + mainname),
337 'cmdshortdesc': minirst.subsection(d[b'desc'][0]),
338 'cmdlongdesc': d[b'desc'][1],
339 'cmdsynopsis': d[b'synopsis'],
340 },
341 )
342 ui.write(header.encode())
343
344 _optionsprinter(ui, d, minirst.subsubsection)
345 if d[b'aliases']:
346 ui.write(minirst.subsubsection(_(b"Aliases")))
347 ui.write(b"::\n\n ")
348 ui.write(b", ".join(d[b'aliases']))
349 ui.write(b"\n")
350
351
352 def _splitdoc(obj):
353 objdoc = pycompat.getdoc(obj)
354 firstnl = objdoc.find(b'\n')
355 if firstnl > 0:
356 shortdoc = objdoc[:firstnl]
357 longdoc = objdoc[firstnl + 1 :]
358 else:
359 shortdoc = objdoc
360 longdoc = ''
361 return shortdoc.lstrip(), longdoc.lstrip()
362
363
364 def _rendertpl(tplname, data):
365 tplpath = os.path.join(os.path.dirname(__file__), 'templates', tplname)
366 with open(tplpath, 'r') as f:
367 tpl = f.read()
368
369 if isinstance(tpl, bytes):
370 tpl = tpl.decode()
371 for k in data:
372 data[k] = data[k].decode()
373
374 return tpl % data
375
376
181 def gettopicstable():
377 def gettopicstable():
182 extrahelptable = [
378 extrahelptable = [
183 ([b"common"], b'', loaddoc(b'common'), help.TOPIC_CATEGORY_MISC),
379 ([b"common"], b'', loaddoc(b'common'), help.TOPIC_CATEGORY_MISC),
@@ -268,6 +464,41 b' def helpprinter(ui, topics, sectionfunc)'
268 ui.write(b"\n")
464 ui.write(b"\n")
269
465
270
466
467 def showextension(ui, extensionname, debugcmds=False):
468 """Render the help text for an extension
469
470 Args:
471 ui: the UI object to output to
472 extensionname: the name of the extension to output
473 debugcmds: whether to include the extension's debug commands, if any
474 """
475 mod = extensions.load(ui, extensionname, None)
476
477 header = _rendertpl(
478 'extheader.txt',
479 {'extname': extensionname, 'exttitle': minirst.section(extensionname)},
480 )
481 ui.write(header.encode())
482
483 shortdoc, longdoc = _splitdoc(mod)
484 if shortdoc:
485 ui.write(b"%s\n\n" % gettext(shortdoc))
486 if longdoc:
487 ui.write(minirst.subsection(_(b"Description")))
488 ui.write(b"%s\n\n" % gettext(longdoc))
489
490 cmdtable = getattr(mod, 'cmdtable', None)
491 if cmdtable:
492 ui.write(minirst.subsection(_(b'Commands')))
493 commandprinter(
494 ui,
495 cmdtable,
496 minirst.subsubsection,
497 minirst.subsubsubsection,
498 debugcmds=debugcmds,
499 )
500
501
271 def commandprinter(ui, cmdtable, sectionfunc, subsectionfunc, debugcmds=False):
502 def commandprinter(ui, cmdtable, sectionfunc, subsectionfunc, debugcmds=False):
272 """Render restructuredtext describing a list of commands and their
503 """Render restructuredtext describing a list of commands and their
273 documentations, grouped by command category.
504 documentations, grouped by command category.
@@ -427,7 +658,27 b' if __name__ == "__main__":'
427 # ui.debugflag determines if the help module returns debug commands to us.
658 # ui.debugflag determines if the help module returns debug commands to us.
428 ui.debugflag = debugcmds
659 ui.debugflag = debugcmds
429
660
661 # Render the 'all-in-one' giant documentation file
430 if doc == b'hg.1.gendoc':
662 if doc == b'hg.1.gendoc':
431 showdoc(ui)
663 showdoc(ui)
664 # Render a command/help-topic/extension name list (for internal use)
665 elif doc == b'commandlist':
666 showcommandlist(ui, debugcmds=debugcmds)
667 elif doc == b'topiclist':
668 showtopiclist(ui)
669 elif doc == b'extensionlist':
670 showextensionlist(ui)
671 # Render the help index/main page
672 elif doc == b'index':
673 showhelpindex(ui, debugcmds=debugcmds)
674 # Render an individual command/help-topic/extension page
675 elif doc.startswith(b'cmd-'):
676 showcommand(ui, doc[4:])
677 elif doc.startswith(b'topic-'):
678 showtopic(ui, doc[6:], wraptpl=True)
679 elif doc.startswith(b'ext-'):
680 showextension(ui, doc[4:], debugcmds=debugcmds)
681 # Render a help-topic page without any title/footer, for later inclusion
682 # into a hand-written help text file
432 else:
683 else:
433 showtopic(ui, doc)
684 showtopic(ui, doc)
@@ -13,6 +13,7 b' where WRITER is the name of a Docutils w'
13 """
13 """
14
14
15
15
16 import re
16 import sys
17 import sys
17
18
18 try:
19 try:
@@ -31,13 +32,63 b' except ImportError:'
31 )
32 )
32 sys.exit(-1)
33 sys.exit(-1)
33
34
35 # Whether we are rendering a help page for a single topic.
36 # If false, we are rendering a monolithic page with all topics together.
37 is_individual_pages_mode = False
38
39
40 def make_cmd_ref_uri(cmd):
41 if is_individual_pages_mode:
42 return "hg-%s.html" % cmd
43 else:
44 return "hg.1.html#%s" % cmd
45
46
47 known_refs = None
48
49
50 def load_known_refs(fname):
51 try:
52 with open(fname, 'r') as fp:
53 text = fp.read()
54 return re.split(r'[ \n]+', text)
55 except OSError:
56 sys.stderr.write(
57 "abort: couldn't find '%', please run documentation generation "
58 "through the Makefile, or run 'make knownrefs'\n"
59 )
60 sys.exit(-1)
61
62
63 def find_known_ref(ref):
64 global known_refs
65 if known_refs is None:
66 cmds = load_known_refs('commandlist.txt')
67 topics = load_known_refs('topiclist.txt')
68 exts = load_known_refs('extensionlist.txt')
69 known_refs = {'hg': cmds, 'topic': topics, 'ext': exts}
70 for reftype, refnames in known_refs.items():
71 if ref in refnames:
72 return reftype
73 return None
74
75
76 def make_any_ref_uri(ref):
77 if is_individual_pages_mode:
78 # Try to find if ref is a command, topic, or extension. If not,
79 # reference the anchor in the main hg.1 help page.
80 reftype = find_known_ref(ref)
81 if reftype:
82 return '%s-%s.html' % (reftype, ref)
83 return "hg.1.html#%s" % ref
84
34
85
35 def role_hg(name, rawtext, text, lineno, inliner, options=None, content=None):
86 def role_hg(name, rawtext, text, lineno, inliner, options=None, content=None):
36 text = "hg " + utils.unescape(text)
87 text = "hg " + utils.unescape(text)
37 linktext = nodes.literal(rawtext, text)
88 linktext = nodes.literal(rawtext, text)
38 parts = text.split()
89 parts = text.split()
39 cmd, args = parts[1], parts[2:]
90 cmd, args = parts[1], parts[2:]
40 refuri = "hg.1.html#%s" % cmd
91 refuri = make_cmd_ref_uri(cmd)
41 if cmd == 'help' and args:
92 if cmd == 'help' and args:
42 if args[0] == 'config':
93 if args[0] == 'config':
43 # :hg:`help config`
94 # :hg:`help config`
@@ -48,9 +99,9 b' def role_hg(name, rawtext, text, lineno,'
48 elif len(args) >= 2 and args[0] == '-c':
99 elif len(args) >= 2 and args[0] == '-c':
49 # :hg:`help -c COMMAND ...` is equivalent to :hg:`COMMAND`
100 # :hg:`help -c COMMAND ...` is equivalent to :hg:`COMMAND`
50 # (mainly for :hg:`help -c config`)
101 # (mainly for :hg:`help -c config`)
51 refuri = "hg.1.html#%s" % args[1]
102 refuri = make_cmd_ref_uri(args[1])
52 else:
103 else:
53 refuri = "hg.1.html#%s" % args[0]
104 refuri = make_any_ref_uri(args[0])
54 node = nodes.reference(rawtext, '', linktext, refuri=refuri)
105 node = nodes.reference(rawtext, '', linktext, refuri=refuri)
55 return [node], []
106 return [node], []
56
107
@@ -65,4 +116,8 b' if __name__ == "__main__":'
65 writer = sys.argv[1]
116 writer = sys.argv[1]
66 del sys.argv[1]
117 del sys.argv[1]
67
118
119 if sys.argv[1] == '--hg-individual-pages':
120 is_individual_pages_mode = True
121 del sys.argv[1]
122
68 core.publish_cmdline(writer_name=writer)
123 core.publish_cmdline(writer_name=writer)
General Comments 0
You need to be logged in to leave comments. Login now