@@ -76,15 +76,15 @@ def _find_directive_pattern(name: str):
76
76
HIGHLIGHT_PATTERN = _find_directive_pattern ('highlight' )
77
77
CODE_BLOCK_PATTERN = _find_directive_pattern ('code-block' )
78
78
79
- _RST_SECTIONS = [
79
+ _RST_SECTIONS = {
80
80
'Parameters' ,
81
81
'Returns' ,
82
82
'See Also' ,
83
83
'Examples' ,
84
84
'Attributes' ,
85
85
'Notes' ,
86
86
'References'
87
- ]
87
+ }
88
88
89
89
90
90
def looks_like_rst (value : str ) -> bool :
@@ -128,7 +128,8 @@ def consume(self, line: str) -> None:
128
128
def finish_consumption (self , final : bool ) -> str :
129
129
pass
130
130
131
- follower : Union ['IParser' , None ]
131
+ def get_follower (self , line : str ) -> Union ['IParser' , None ]:
132
+ return None
132
133
133
134
134
135
class BlockParser (IParser ):
@@ -249,7 +250,9 @@ def _strip_prompt(self, line: str) -> str:
249
250
start = 4 if line .startswith ('>>> ' ) or line .startswith ('... ' ) else 3
250
251
return line [start :]
251
252
252
- follower = PythonOutputBlockParser ()
253
+ def get_follower (self , line : str ) -> Union ['IParser' , None ]:
254
+ if line :
255
+ return PythonOutputBlockParser ()
253
256
254
257
255
258
class DoubleColonBlockParser (IndentedBlockParser ):
@@ -267,7 +270,7 @@ def initiate_parsing(self, line: str, current_language: str):
267
270
line = re .sub (r'::$' , '' , line )
268
271
269
272
self ._start_block (language )
270
- return IBlockBeginning (remainder = line + '\n \n ' )
273
+ return IBlockBeginning (remainder = line . rstrip () + '\n \n ' )
271
274
272
275
273
276
class MathBlockParser (IndentedBlockParser ):
@@ -315,8 +318,6 @@ def initiate_parsing(self, line: str, current_language: str) -> IBlockBeginning:
315
318
for section in _RST_SECTIONS
316
319
}
317
320
318
- NBSP_INDENT = ' '
319
-
320
321
321
322
def rst_to_markdown (text : str ):
322
323
"""
@@ -337,7 +338,7 @@ def rst_to_markdown(text: str):
337
338
- explicit code blocks
338
339
- NumPy-like list items
339
340
- 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
341
342
342
343
Arguments:
343
344
text - the input docstring
@@ -346,6 +347,8 @@ def rst_to_markdown(text: str):
346
347
markdown = ''
347
348
active_parser : Union [IParser , None ] = None
348
349
lines_buffer : List [str ] = []
350
+ most_recent_section : Union [str , None ] = None
351
+ is_first_line = True
349
352
350
353
def flush_buffer ():
351
354
nonlocal lines_buffer
@@ -357,11 +360,16 @@ def flush_buffer():
357
360
for (section , header ) in RST_SECTIONS .items ():
358
361
lines = lines .replace (header , '\n #### ' + section + '\n ' )
359
362
360
- lines = lines .replace (NBSP_INDENT , ' ' )
361
363
lines_buffer = []
362
364
return lines
363
365
364
366
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
+
365
373
trimmed_line = line .lstrip ()
366
374
367
375
if active_parser :
@@ -370,8 +378,9 @@ def flush_buffer():
370
378
else :
371
379
markdown += flush_buffer ()
372
380
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
375
384
active_parser .initiate_parsing (line , language )
376
385
else :
377
386
active_parser = None
@@ -387,10 +396,17 @@ def flush_buffer():
387
396
388
397
# ok, we are not in any code block (it may start with the next line, but this line is clear - or empty)
389
398
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
391
403
match = re .match (r'^(?P<argument>[^: ]+) : (?P<type>.+)$' , trimmed_line )
392
404
if match :
393
405
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' ) + '`'
394
410
395
411
# change highlight language if requested
396
412
# this should not conflict with the parsers starting above
0 commit comments