comparison mercurial/help.py @ 24098:067540702f64

help: teach topic symbols how to dedent When using docstrings for documenting symbols such as revsets, templates, or hgweb commands, documentation likely has leading whitespace corresponding to the indentation from the Python source file. Up until this point, the help system stripped all leading and trailing whitespace and replaced it with 2 spaces of leading whitespace. There were a few bad side-effects. First, sections could not be used in docstrings because they would be indented and the rst parser would fail to parse them as sections. Also, any rst elements that required indentation would lose their indentation, again causing them to be parsed and rendered incorrectly. In this patch, we teach the topic symbols system how to dedent text properly. I argue this mode should be enabled by default. However, I stopped short of changing that because it would cause a lot of documentation reformatting to occur. I'm not sure if people are relying on or wanting indentation. So, dedenting has only been turned on for hgweb symbols. This decision should be scrutinized.
author Gregory Szorc <gregory.szorc@gmail.com>
date Mon, 09 Feb 2015 14:59:04 -0800
parents a3f2ea1d4943
children be83fd9d46d5
comparison
equal deleted inserted replaced
24097:8e04a73b5502 24098:067540702f64
4 # 4 #
5 # This software may be used and distributed according to the terms of the 5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version. 6 # GNU General Public License version 2 or any later version.
7 7
8 from i18n import gettext, _ 8 from i18n import gettext, _
9 import itertools, os 9 import itertools, os, textwrap
10 import error 10 import error
11 import extensions, revset, fileset, templatekw, templatefilters, filemerge 11 import extensions, revset, fileset, templatekw, templatefilters, filemerge
12 import encoding, util, minirst 12 import encoding, util, minirst
13 import cmdutil 13 import cmdutil
14 import hgweb.webcommands as webcommands 14 import hgweb.webcommands as webcommands
170 helphooks = {} 170 helphooks = {}
171 171
172 def addtopichook(topic, rewriter): 172 def addtopichook(topic, rewriter):
173 helphooks.setdefault(topic, []).append(rewriter) 173 helphooks.setdefault(topic, []).append(rewriter)
174 174
175 def makeitemsdoc(topic, doc, marker, items): 175 def makeitemsdoc(topic, doc, marker, items, dedent=False):
176 """Extract docstring from the items key to function mapping, build a 176 """Extract docstring from the items key to function mapping, build a
177 .single documentation block and use it to overwrite the marker in doc 177 .single documentation block and use it to overwrite the marker in doc
178 """ 178 """
179 entries = [] 179 entries = []
180 for name in sorted(items): 180 for name in sorted(items):
181 text = (items[name].__doc__ or '').rstrip() 181 text = (items[name].__doc__ or '').rstrip()
182 if not text: 182 if not text:
183 continue 183 continue
184 text = gettext(text) 184 text = gettext(text)
185 if dedent:
186 text = textwrap.dedent(text)
185 lines = text.splitlines() 187 lines = text.splitlines()
186 doclines = [(lines[0])] 188 doclines = [(lines[0])]
187 for l in lines[1:]: 189 for l in lines[1:]:
188 # Stop once we find some Python doctest 190 # Stop once we find some Python doctest
189 if l.strip().startswith('>>>'): 191 if l.strip().startswith('>>>'):
190 break 192 break
191 doclines.append(' ' + l.strip()) 193 if dedent:
194 doclines.append(l.rstrip())
195 else:
196 doclines.append(' ' + l.strip())
192 entries.append('\n'.join(doclines)) 197 entries.append('\n'.join(doclines))
193 entries = '\n\n'.join(entries) 198 entries = '\n\n'.join(entries)
194 return doc.replace(marker, entries) 199 return doc.replace(marker, entries)
195 200
196 def addtopicsymbols(topic, marker, symbols): 201 def addtopicsymbols(topic, marker, symbols, dedent=False):
197 def add(topic, doc): 202 def add(topic, doc):
198 return makeitemsdoc(topic, doc, marker, symbols) 203 return makeitemsdoc(topic, doc, marker, symbols, dedent=dedent)
199 addtopichook(topic, add) 204 addtopichook(topic, add)
200 205
201 addtopicsymbols('filesets', '.. predicatesmarker', fileset.symbols) 206 addtopicsymbols('filesets', '.. predicatesmarker', fileset.symbols)
202 addtopicsymbols('merge-tools', '.. internaltoolsmarker', filemerge.internals) 207 addtopicsymbols('merge-tools', '.. internaltoolsmarker', filemerge.internals)
203 addtopicsymbols('revsets', '.. predicatesmarker', revset.symbols) 208 addtopicsymbols('revsets', '.. predicatesmarker', revset.symbols)
204 addtopicsymbols('templates', '.. keywordsmarker', templatekw.dockeywords) 209 addtopicsymbols('templates', '.. keywordsmarker', templatekw.dockeywords)
205 addtopicsymbols('templates', '.. filtersmarker', templatefilters.filters) 210 addtopicsymbols('templates', '.. filtersmarker', templatefilters.filters)
206 addtopicsymbols('hgweb', '.. webcommandsmarker', webcommands.commands) 211 addtopicsymbols('hgweb', '.. webcommandsmarker', webcommands.commands,
212 dedent=True)
207 213
208 def help_(ui, name, unknowncmd=False, full=True, **opts): 214 def help_(ui, name, unknowncmd=False, full=True, **opts):
209 ''' 215 '''
210 Generate the help for 'name' as unformatted restructured text. If 216 Generate the help for 'name' as unformatted restructured text. If
211 'name' is None, describe the commands available. 217 'name' is None, describe the commands available.