##// END OF EJS Templates
Various improvements to docs infrastructure for magics
Thomas Kluyver -
Show More
@@ -70,7 +70,7 b' html html_noapi:'
70
70
71 automagic: source/interactive/magics-generated.txt
71 automagic: source/interactive/magics-generated.txt
72
72
73 source/interactive/magics-generated.txt:
73 source/interactive/magics-generated.txt: autogen_magics.py
74 python autogen_magics.py
74 python autogen_magics.py
75 @echo "Created docs for line & cell magics"
75 @echo "Created docs for line & cell magics"
76
76
@@ -11,34 +11,54 b' def isalias(name):'
11 line_magics = magic_docs['line']
11 line_magics = magic_docs['line']
12 cell_magics = magic_docs['cell']
12 cell_magics = magic_docs['cell']
13
13
14 def _strip_underline(line):
15 chars = set(line.strip())
16 if len(chars) == 1 and ('-' in chars or '=' in chars):
17 return ""
18 else:
19 return line
20
21 def format_docstring(docstring):
22 docstring = indent(dedent(docstring))
23 # Sphinx complains if indented bits have rst headings in, so strip out
24 # any underlines in the docstring.
25 lines = [_strip_underline(l) for l in docstring.splitlines()]
26 return "\n".join(lines)
27
14 output = [
28 output = [
15 "Line magics",
29 "Line magics",
16 "===========",
30 "===========",
17 "",
31 "",
18 ]
32 ]
19
33
20 for name, docstring in sorted(line_magics.items()):
34 # Case insensitive sort by name
35 def sortkey(s): return s[0].lower()
36
37 for name, docstring in sorted(line_magics.items(), key=sortkey):
21 if isalias(name):
38 if isalias(name):
22 # Aliases are magics, but shouldn't be documented here
39 # Aliases are magics, but shouldn't be documented here
23 continue
40 continue
24 output.extend([".. magic:: %{}".format(name),
41 output.extend([".. magic:: {}".format(name),
25 "",
42 "",
26 indent(dedent(docstring)),
43 format_docstring(docstring),
27 ""])
44 ""])
28
45
29 output.extend([
46 output.extend([
30 "Cell magics"
47 "Cell magics",
31 "==========="
48 "===========",
32 "",
49 "",
33 ])
50 ])
34
51
35 for name, docstring in sorted(cell_magics.items()):
52 for name, docstring in sorted(cell_magics.items(), key=sortkey):
53 if name == "!":
54 # Special case - don't encourage people to use %%!
55 continue
36 if docstring == line_magics.get(name, 'QQQP'):
56 if docstring == line_magics.get(name, 'QQQP'):
37 # Don't redocument line magics that double as cell magics
57 # Don't redocument line magics that double as cell magics
38 continue
58 continue
39 output.extend([".. cellmagic:: %%{}".format(name),
59 output.extend([".. cellmagic:: {}".format(name),
40 "",
60 "",
41 indent(dedent(docstring)),
61 format_docstring(docstring),
42 ""])
62 ""])
43
63
44 with open("source/interactive/magics-generated.txt", "w") as f:
64 with open("source/interactive/magics-generated.txt", "w") as f:
@@ -1,24 +1,42 b''
1 import re
1 import re
2 from sphinx import addnodes
2 from sphinx import addnodes
3 from sphinx.domains.std import StandardDomain
4 from sphinx.roles import XRefRole
3
5
4 line_magic_re = re.compile(r"%([\w_]+)")
6 name_re = re.compile(r"[\w_]+")
5 cell_magic_re = re.compile(r"%%([\w_]+)")
6
7
7 def parse_magic(env, sig, signode):
8 def parse_magic(env, sig, signode):
8 m = line_magic_re.match(sig)
9 m = name_re.match(sig)
9 if not m:
10 if not m:
10 raise Exception("Invalid magic command: %s" % sig)
11 raise Exception("Invalid magic command: %s" % sig)
11 signode += addnodes.desc_name(sig, sig)
12 name = "%" + sig
12 return m.group(1)
13 signode += addnodes.desc_name(name, name)
14 return m.group(0)
15
16 class LineMagicRole(XRefRole):
17 """Cross reference role displayed with a % prefix"""
18 prefix = "%"
19
20 def process_link(self, env, refnode, has_explicit_title, title, target):
21 if not has_explicit_title:
22 title = self.prefix + title.lstrip("%")
23 target = target.lstrip("%")
24 return title, target
13
25
14 def parse_cell_magic(env, sig, signode):
26 def parse_cell_magic(env, sig, signode):
15 m = cell_magic_re.match(sig)
27 m = name_re.match(sig)
16 if not m:
28 if not m:
17 raise ValueError("Invalid cell magic: %s" % sig)
29 raise ValueError("Invalid cell magic: %s" % sig)
18 signode += addnodes.desc_name(sig, sig)
30 name = "%%" + sig
19 return m.group(1)
31 signode += addnodes.desc_name(name, name)
32 return m.group(0)
20
33
34 class CellMagicRole(LineMagicRole):
35 """Cross reference role displayed with a %% prefix"""
36 prefix = "%%"
21
37
22 def setup(app):
38 def setup(app):
23 app.add_object_type('magic', 'magic', 'pair: %s; magic command', parse_magic)
39 app.add_object_type('magic', 'magic', 'pair: %s; magic command', parse_magic)
40 StandardDomain.roles['magic'] = LineMagicRole()
24 app.add_object_type('cellmagic', 'cellmagic', 'pair: %s; cell magic', parse_cell_magic)
41 app.add_object_type('cellmagic', 'cellmagic', 'pair: %s; cell magic', parse_cell_magic)
42 StandardDomain.roles['cellmagic'] = CellMagicRole()
General Comments 0
You need to be logged in to leave comments. Login now