Skip to content

Commit b9252ff

Browse files
committed
Implement signature detection, args, kwargs and improve prompt output
fixes #3
1 parent 196e7d7 commit b9252ff

File tree

2 files changed

+198
-81
lines changed

2 files changed

+198
-81
lines changed

docstring_to_markdown/rst.py

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,15 @@ def _find_directive_pattern(name: str):
7676
HIGHLIGHT_PATTERN = _find_directive_pattern('highlight')
7777
CODE_BLOCK_PATTERN = _find_directive_pattern('code-block')
7878

79-
_RST_SECTIONS = [
79+
_RST_SECTIONS = {
8080
'Parameters',
8181
'Returns',
8282
'See Also',
8383
'Examples',
8484
'Attributes',
8585
'Notes',
8686
'References'
87-
]
87+
}
8888

8989

9090
def looks_like_rst(value: str) -> bool:
@@ -128,7 +128,8 @@ def consume(self, line: str) -> None:
128128
def finish_consumption(self, final: bool) -> str:
129129
pass
130130

131-
follower: Union['IParser', None]
131+
def get_follower(self, line: str) -> Union['IParser', None]:
132+
return None
132133

133134

134135
class BlockParser(IParser):
@@ -249,7 +250,9 @@ def _strip_prompt(self, line: str) -> str:
249250
start = 4 if line.startswith('>>> ') or line.startswith('... ') else 3
250251
return line[start:]
251252

252-
follower = PythonOutputBlockParser()
253+
def get_follower(self, line: str) -> Union['IParser', None]:
254+
if line:
255+
return PythonOutputBlockParser()
253256

254257

255258
class DoubleColonBlockParser(IndentedBlockParser):
@@ -267,7 +270,7 @@ def initiate_parsing(self, line: str, current_language: str):
267270
line = re.sub(r'::$', '', line)
268271

269272
self._start_block(language)
270-
return IBlockBeginning(remainder=line + '\n\n')
273+
return IBlockBeginning(remainder=line.rstrip() + '\n\n')
271274

272275

273276
class MathBlockParser(IndentedBlockParser):
@@ -315,8 +318,6 @@ def initiate_parsing(self, line: str, current_language: str) -> IBlockBeginning:
315318
for section in _RST_SECTIONS
316319
}
317320

318-
NBSP_INDENT = ' '
319-
320321

321322
def rst_to_markdown(text: str):
322323
"""
@@ -337,7 +338,7 @@ def rst_to_markdown(text: str):
337338
- explicit code blocks
338339
- NumPy-like list items
339340
- external links (inline only)
340-
- as subset of paragraph-level and inline directives (which must fit into a single line)
341+
- as subset of paragraph-level and inline directives
341342
342343
Arguments:
343344
text - the input docstring
@@ -346,6 +347,8 @@ def rst_to_markdown(text: str):
346347
markdown = ''
347348
active_parser: Union[IParser, None] = None
348349
lines_buffer: List[str] = []
350+
most_recent_section: Union[str, None] = None
351+
is_first_line = True
349352

350353
def flush_buffer():
351354
nonlocal lines_buffer
@@ -357,11 +360,16 @@ def flush_buffer():
357360
for (section, header) in RST_SECTIONS.items():
358361
lines = lines.replace(header, '\n#### ' + section + '\n')
359362

360-
lines = lines.replace(NBSP_INDENT, ' ')
361363
lines_buffer = []
362364
return lines
363365

364366
for line in text.split('\n'):
367+
if is_first_line:
368+
signature_match = re.match(r'^(?P<name>\w+)\((?P<params>.*)\)$', line)
369+
if signature_match and signature_match.group('name').isidentifier():
370+
markdown += '```python\n' + line + '\n```\n'
371+
continue
372+
365373
trimmed_line = line.lstrip()
366374

367375
if active_parser:
@@ -370,8 +378,9 @@ def flush_buffer():
370378
else:
371379
markdown += flush_buffer()
372380
markdown += active_parser.finish_consumption(False)
373-
if active_parser.follower:
374-
active_parser = active_parser.follower
381+
follower = active_parser.get_follower(line)
382+
if follower:
383+
active_parser = follower
375384
active_parser.initiate_parsing(line, language)
376385
else:
377386
active_parser = None
@@ -387,10 +396,17 @@ def flush_buffer():
387396

388397
# ok, we are not in any code block (it may start with the next line, but this line is clear - or empty)
389398

390-
# lists handling: items detection
399+
if trimmed_line.rstrip() in RST_SECTIONS:
400+
most_recent_section = trimmed_line.rstrip()
401+
402+
# lists handling: items detection
391403
match = re.match(r'^(?P<argument>[^: ]+) : (?P<type>.+)$', trimmed_line)
392404
if match:
393405
line = '- `' + match.group('argument') + '`: ' + match.group('type') + ''
406+
elif most_recent_section == 'Parameters':
407+
kwargs_or_args_match = re.match(r'^(?P<other_args>\*\*kwargs|\*args)$', trimmed_line)
408+
if kwargs_or_args_match:
409+
line = '- `' + kwargs_or_args_match.group('other_args') + '`'
394410

395411
# change highlight language if requested
396412
# this should not conflict with the parsers starting above

0 commit comments

Comments
 (0)