mkdocs-apidescribed-plugin 1.0.1__tar.gz → 1.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mkdocs_apidescribed_plugin-1.0.1 → mkdocs_apidescribed_plugin-1.1.0}/PKG-INFO +1 -1
- {mkdocs_apidescribed_plugin-1.0.1 → mkdocs_apidescribed_plugin-1.1.0}/pyproject.toml +1 -1
- mkdocs_apidescribed_plugin-1.1.0/src/mkdocs_apidescribed/__init__.py +2 -0
- {mkdocs_apidescribed_plugin-1.0.1 → mkdocs_apidescribed_plugin-1.1.0/src}/mkdocs_apidescribed/inspector.py +3 -3
- {mkdocs_apidescribed_plugin-1.0.1 → mkdocs_apidescribed_plugin-1.1.0/src}/mkdocs_apidescribed/parsers.py +110 -49
- mkdocs_apidescribed_plugin-1.0.1/mkdocs_apidescribed/__init__.py +0 -2
- {mkdocs_apidescribed_plugin-1.0.1 → mkdocs_apidescribed_plugin-1.1.0}/.gitignore +0 -0
- {mkdocs_apidescribed_plugin-1.0.1 → mkdocs_apidescribed_plugin-1.1.0}/LICENSE +0 -0
- {mkdocs_apidescribed_plugin-1.0.1 → mkdocs_apidescribed_plugin-1.1.0}/README.md +0 -0
- {mkdocs_apidescribed_plugin-1.0.1 → mkdocs_apidescribed_plugin-1.1.0/src}/mkdocs_apidescribed/config.py +0 -0
- {mkdocs_apidescribed_plugin-1.0.1 → mkdocs_apidescribed_plugin-1.1.0/src}/mkdocs_apidescribed/extension.py +0 -0
- {mkdocs_apidescribed_plugin-1.0.1 → mkdocs_apidescribed_plugin-1.1.0/src}/mkdocs_apidescribed/formatter.py +0 -0
- {mkdocs_apidescribed_plugin-1.0.1 → mkdocs_apidescribed_plugin-1.1.0/src}/mkdocs_apidescribed/plugin.py +0 -0
- {mkdocs_apidescribed_plugin-1.0.1 → mkdocs_apidescribed_plugin-1.1.0/src}/mkdocs_apidescribed/probe.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mkdocs-apidescribed-plugin
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: mkdocs plugin to generate API documentation for Python programs
|
|
5
5
|
Project-URL: Homepage, https://github.com/idlesign/mkdocs-apidescribed-plugin
|
|
6
6
|
Project-URL: Documentation, https://mkdocs-apidescribed-plugin.readthedocs.org/
|
|
@@ -25,7 +25,7 @@ class Symbol:
|
|
|
25
25
|
type: SymbolType
|
|
26
26
|
name: str
|
|
27
27
|
source: str
|
|
28
|
-
docstr:
|
|
28
|
+
docstr: str
|
|
29
29
|
path: str
|
|
30
30
|
fpath: str
|
|
31
31
|
params: griffe.Parameters | None
|
|
@@ -108,7 +108,7 @@ def get_symbol(
|
|
|
108
108
|
|
|
109
109
|
if not symbol_type:
|
|
110
110
|
log.error(f'Unsupported symbol type: {obj}. Skipped.')
|
|
111
|
-
return
|
|
111
|
+
return None
|
|
112
112
|
|
|
113
113
|
symbol = Symbol(
|
|
114
114
|
depth=depth,
|
|
@@ -116,7 +116,7 @@ def get_symbol(
|
|
|
116
116
|
type=symbol_type,
|
|
117
117
|
name=obj.name,
|
|
118
118
|
source=obj.source,
|
|
119
|
-
docstr=obj.docstring,
|
|
119
|
+
docstr=getattr(obj.docstring, 'value', None) or '',
|
|
120
120
|
path=obj.path,
|
|
121
121
|
fpath=f'{obj.relative_package_filepath}',
|
|
122
122
|
params=params,
|
|
@@ -4,8 +4,6 @@ from dataclasses import dataclass, field
|
|
|
4
4
|
from textwrap import dedent
|
|
5
5
|
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
|
-
import griffe
|
|
8
|
-
|
|
9
7
|
if TYPE_CHECKING:
|
|
10
8
|
from .formatter import Formatter
|
|
11
9
|
|
|
@@ -25,7 +23,7 @@ class Block:
|
|
|
25
23
|
|
|
26
24
|
def __init__(self, marker: str = '', arg: str = '', value: str = ''):
|
|
27
25
|
self.marker = marker or self.unmarked
|
|
28
|
-
self.arg = arg.strip()
|
|
26
|
+
self.arg = arg.strip().partition(' ')[0] # e.g.: "arg (int)"
|
|
29
27
|
self.value = value
|
|
30
28
|
self.addition = []
|
|
31
29
|
|
|
@@ -47,9 +45,9 @@ class DocstrParser:
|
|
|
47
45
|
registry: dict[str, type['DocstrParser']] = {}
|
|
48
46
|
|
|
49
47
|
@classmethod
|
|
50
|
-
def parse(cls, docstr:
|
|
48
|
+
def parse(cls, docstr: str, *, config: dict, formatter: 'Formatter') -> Docstring:
|
|
51
49
|
|
|
52
|
-
value =
|
|
50
|
+
value = docstr
|
|
53
51
|
docstring = Docstring(text=f'{value}')
|
|
54
52
|
|
|
55
53
|
if value:
|
|
@@ -87,9 +85,64 @@ class DocstrParser:
|
|
|
87
85
|
def run(self) -> Docstring | None:
|
|
88
86
|
return self._parse(self.src)
|
|
89
87
|
|
|
88
|
+
def normalize(self, text: str) -> str:
|
|
89
|
+
return text
|
|
90
|
+
|
|
90
91
|
def postprocess(self, text: str) -> str:
|
|
91
92
|
return text
|
|
92
93
|
|
|
94
|
+
def parse_blocks(
|
|
95
|
+
self,
|
|
96
|
+
*,
|
|
97
|
+
pattern: re.Pattern,
|
|
98
|
+
value: str,
|
|
99
|
+
) -> tuple[dict[str, list[Block]], list[Block]]:
|
|
100
|
+
|
|
101
|
+
blocks: dict[str, list[Block]] = defaultdict(list)
|
|
102
|
+
block_last: Block | None = None
|
|
103
|
+
marker_detected = False
|
|
104
|
+
|
|
105
|
+
processed = []
|
|
106
|
+
|
|
107
|
+
for line in value.splitlines():
|
|
108
|
+
|
|
109
|
+
is_empty = len(line.strip()) == 0
|
|
110
|
+
|
|
111
|
+
if block_last:
|
|
112
|
+
if line.startswith(' ') or is_empty:
|
|
113
|
+
# must be a continuation of a block
|
|
114
|
+
block_last.contribute(line)
|
|
115
|
+
continue
|
|
116
|
+
|
|
117
|
+
# previous block ended
|
|
118
|
+
processed.append(block_last)
|
|
119
|
+
block_last = None
|
|
120
|
+
|
|
121
|
+
if matched := pattern.match(line):
|
|
122
|
+
marker_detected = True
|
|
123
|
+
marker = matched.group('marker')
|
|
124
|
+
|
|
125
|
+
arg = matched.group('arg')
|
|
126
|
+
val = matched.group('value')
|
|
127
|
+
|
|
128
|
+
block = Block(marker, arg, val.strip())
|
|
129
|
+
blocks[marker].append(block)
|
|
130
|
+
block_last = block
|
|
131
|
+
|
|
132
|
+
else:
|
|
133
|
+
block = Block()
|
|
134
|
+
block.contribute(line)
|
|
135
|
+
blocks[Block.unmarked].append(block)
|
|
136
|
+
processed.append(block)
|
|
137
|
+
|
|
138
|
+
if block_last:
|
|
139
|
+
# block in the last line
|
|
140
|
+
processed.append(block_last)
|
|
141
|
+
|
|
142
|
+
self.markers_detected = self.markers_detected or marker_detected
|
|
143
|
+
|
|
144
|
+
return blocks, processed
|
|
145
|
+
|
|
93
146
|
def _parse(self, value: str) -> Docstring | None: # pragma: nocover
|
|
94
147
|
return
|
|
95
148
|
|
|
@@ -154,76 +207,84 @@ class SphinxParser(DocstrParser):
|
|
|
154
207
|
|
|
155
208
|
return '\n'.join(lines)
|
|
156
209
|
|
|
157
|
-
def
|
|
158
|
-
self,
|
|
159
|
-
*,
|
|
160
|
-
pattern: re.Pattern,
|
|
161
|
-
value: str,
|
|
162
|
-
) -> tuple[dict[str, list[Block]], list[Block]]:
|
|
210
|
+
def _parse(self, value: str) -> Docstring | None:
|
|
163
211
|
|
|
164
|
-
blocks
|
|
165
|
-
|
|
166
|
-
|
|
212
|
+
blocks, processed = self.parse_blocks(
|
|
213
|
+
pattern=self.re_markers,
|
|
214
|
+
value=self.normalize(value),
|
|
215
|
+
)
|
|
167
216
|
|
|
168
|
-
|
|
217
|
+
return Docstring(
|
|
218
|
+
text=self.postprocess('\n'.join(map(str, blocks[Block.unmarked]))),
|
|
219
|
+
params=self.to_dict(blocks['param']),
|
|
220
|
+
returns=self.to_list(blocks['return']),
|
|
221
|
+
raises=self.to_dict(blocks['raises']),
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
class GoogleParser(DocstrParser):
|
|
226
|
+
alias: str = 'google'
|
|
227
|
+
|
|
228
|
+
re_markers = re.compile(
|
|
229
|
+
r'^::(?P<marker>Args|Yields|Returns|Raises|Examples)::'
|
|
230
|
+
r'(?P<arg>[^:]*):\s*(?P<value>.*)'
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
re_preproc = re.compile(r'^(?P<marker>Args|Yields|Returns|Raises|Examples):$')
|
|
234
|
+
|
|
235
|
+
def normalize(self, value: str) -> str:
|
|
236
|
+
pattern = self.re_preproc
|
|
237
|
+
normalized = []
|
|
238
|
+
marker_stack = []
|
|
239
|
+
marker_depth = 0
|
|
169
240
|
|
|
170
241
|
for line in value.splitlines():
|
|
171
242
|
|
|
172
243
|
is_empty = len(line.strip()) == 0
|
|
173
244
|
|
|
174
|
-
if
|
|
245
|
+
if marker_stack:
|
|
175
246
|
if line.startswith(' ') or is_empty:
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
continue
|
|
247
|
+
unindented = line.lstrip(' ')
|
|
248
|
+
indent_size = len(line) - len(unindented)
|
|
179
249
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
250
|
+
if not marker_depth or indent_size == marker_depth:
|
|
251
|
+
marker_depth = indent_size
|
|
252
|
+
marker_stack.append(f"::{marker_stack[0]}:: {unindented}")
|
|
183
253
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
254
|
+
elif indent_size > marker_depth:
|
|
255
|
+
# deeper: block body (continuation)
|
|
256
|
+
reindented = f'{" " * (indent_size-marker_depth)}{unindented}'
|
|
257
|
+
marker_stack[-1] = f'{marker_stack[-1]}\n{reindented}'
|
|
258
|
+
else:
|
|
259
|
+
# end of block
|
|
260
|
+
normalized.extend(marker_stack[1:])
|
|
261
|
+
marker_stack.clear()
|
|
262
|
+
marker_depth = 0
|
|
187
263
|
|
|
188
|
-
|
|
189
|
-
val = matched.group('value')
|
|
264
|
+
continue
|
|
190
265
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
block_last = block
|
|
266
|
+
if matched := pattern.match(line):
|
|
267
|
+
marker_stack.append(matched.group('marker'))
|
|
194
268
|
|
|
195
269
|
else:
|
|
196
|
-
|
|
197
|
-
block.contribute(line)
|
|
198
|
-
blocks[Block.unmarked].append(block)
|
|
199
|
-
processed.append(block)
|
|
270
|
+
normalized.append(line)
|
|
200
271
|
|
|
201
|
-
|
|
202
|
-
# block in the last line
|
|
203
|
-
processed.append(block_last)
|
|
204
|
-
|
|
205
|
-
self.markers_detected = self.markers_detected or marker_detected
|
|
206
|
-
|
|
207
|
-
return blocks, processed
|
|
272
|
+
return '\n'.join(normalized)
|
|
208
273
|
|
|
209
274
|
def _parse(self, value: str) -> Docstring | None:
|
|
210
275
|
|
|
211
276
|
blocks, processed = self.parse_blocks(
|
|
212
277
|
pattern=self.re_markers,
|
|
213
|
-
value=value,
|
|
278
|
+
value=self.normalize(value),
|
|
214
279
|
)
|
|
215
280
|
|
|
216
281
|
return Docstring(
|
|
217
282
|
text=self.postprocess('\n'.join(map(str, blocks[Block.unmarked]))),
|
|
218
|
-
params=self.to_dict(blocks['
|
|
219
|
-
returns=self.to_list(blocks['
|
|
220
|
-
raises=self.to_dict(blocks['
|
|
283
|
+
params=self.to_dict(blocks['Args']),
|
|
284
|
+
returns=self.to_list(blocks['Returns']),
|
|
285
|
+
raises=self.to_dict(blocks['Raises']),
|
|
221
286
|
)
|
|
222
287
|
|
|
223
288
|
|
|
224
|
-
class GoogleParser(DocstrParser):
|
|
225
|
-
alias: str = 'google'
|
|
226
|
-
|
|
227
|
-
|
|
228
289
|
class NumpyParser(DocstrParser):
|
|
229
290
|
alias: str = 'numpy'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|