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:: |
|
41 | output.extend([".. magic:: {}".format(name), | |
25 | "", |
|
42 | "", | |
26 |
|
|
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:: |
|
59 | output.extend([".. cellmagic:: {}".format(name), | |
40 | "", |
|
60 | "", | |
41 |
|
|
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 |
|
|
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 = |
|
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 = |
|
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