forked from TRIQS/cpp2py
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprocessed_doc.py
More file actions
130 lines (106 loc) · 5.02 KB
/
processed_doc.py
File metadata and controls
130 lines (106 loc) · 5.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# Copyright (c) 2019-2020 Simons Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http:#www.apache.org/licenses/LICENSE-2.0.txt
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Authors: Gregory Kramida, Olivier Parcollet, Nils Wentzell
import re
from collections import OrderedDict
import cpp2py.clang_parser as CL
"""
Meaning of the @option in the doc:
* @param X Documentation of parameter X for a function
* @return Doc of the return of a function
* @tparam T Documentation of a template parameter of a function or a class
* @synopsis An explicit synopsis for the automatically generated one, for a function.
* @value Overrules the type of a using/typedef.
* @warning Warning
* @figure An illustration
* @note Note
* @include For a class, a function, the top level file to include [default: the definition file]
* @example filename File name of the example. Path should start from doc/reference/c++
* @manual_methods Comma separated list of methods which are referenced in the table,
but the page of doc is not generated. It will be written manually.
* @manual_friends Comma separated list of non member functions which are referenced in the table,
but the page of doc is not generated. It will be written manually.
The @ MUST BE THE LAST FIELDS
"""
# ---------------------------------
# Should be internal ??
def replace_latex(s, escape_slash=False):
"""replace
$XX X$ by :math:`XX X`
$$X XX$$ by \n\n.. math:\n\t\tX XX\n\n..\n
[[ XXX]] by :ref:` XXX`
"""
if not s: return s
any_math_char = 'A-Za-z0-9{}\[\],;|\(\)=./\/+-_^\'' # any math character
# matches all expressions starting and ending with any math char, with possibly whitespaces in between
pattern_1 = '\$([' + any_math_char + '][' + any_math_char + ' ]*[' + any_math_char + ']+)\$'
# matches any single math char
pattern_2 = '\$([' + any_math_char + '])\$'
# out of line formula
text = re.sub('\$' + pattern_1 + '\$', r'\n\n.. math::\n\t\t\1\n\n..\n', s)
text = re.sub('\$' + pattern_2 + '\$', r'\n\n.. math::\n\t\t\1\n\n..\n', text)
# inline formula
text = re.sub(pattern_1, r':math:`\1`', text)
text = re.sub(pattern_2, r':math:`\1`', text)
# to create a hyperlink
text = re.sub('\[\[([A-Za-z0-9{}\(,\)=./\/+-_]+)\]\]', r':ref:`\1`', text)
if escape_slash: text = text.encode('string_escape')
return text
def clean_doc_string(s):
if not s: return ""
for p in [r"/\*", r"\*/", r"^\s*\*", r'\*\s*\n', r'\*/\s*$', r"///", r"//", r"\\brief"]:
s = re.sub(p, "", s, flags=re.MULTILINE)
return s.strip()
# ------------------------------------------------------------------------
class ProcessedDoc:
fields_allowed_in_docs = ['include', 'return', 'synopsis', 'warning', 'figure', 'note', 'example', 'param',
'tparam', 'group']
fields_with_multiple_entry = ['param', 'tparam']
"""
Result of the processing of the documentation string for a function or a class
self.brief_doc : first line
self.doc : rest of the doc
self.elements : dict with all fields @XXX -> Value
params, tparams will always be a list, if present
Replace latex with proper rst call in all fields.
"""
def __init__(self, node):
raw_doc = node.raw_comment
if not raw_doc:
raw_doc = "\n\n" # default value
# Clean *, &&, /// and co.
doc = clean_doc_string(raw_doc.strip())
# split : the first line is brief, and the rest
doc = replace_latex(doc)
if '$' in doc:
print("FAILED to process the latex for node %s" % CL.fully_qualified(node))
print(doc)
doc2 = doc.strip().split('@', 1)[0] # Get rid of everything after the first @
spl = doc2.strip().split('\n', 1)
self.brief_doc, self.doc = spl[0], (spl[1] if len(spl) > 1 else '')
assert '@' not in self.doc, "ouch!"
# Extract the @XXXX elements with a regex @XXXX YYYY (YYYY can be multiline).
d = dict((key, []) for key in self.fields_with_multiple_entry)
regex = r'@(\w+)\s*([^@]*)'
for m in re.finditer(regex, doc, re.DOTALL):
key, val = m.group(1), replace_latex(m.group(2)).strip()
if key not in self.fields_allowed_in_docs:
print("Field %s is not recognized" % key)
if key in self.fields_with_multiple_entry:
d[key].append(val)
else:
d[key] = val
self.elements = d
# print "Final", self.brief_doc, self.doc, self.elements