Skip to content

Commit 2848c80

Browse files
committed
0.5.4 Update
Properly account for bindings in variables and functions. Backup description if not accessible. Add the possibility of describing a variable in the function description using the keyword "@param $name:" at the beginning of lines. Those lines will be removed from the comment. All lines with the same $name will be added to the description of the parameter $name
1 parent 51da4f5 commit 2848c80

File tree

3 files changed

+74
-21
lines changed

3 files changed

+74
-21
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = 'sphinxfortran_ng'
3-
version = '0.5.3'
3+
version = '0.5.4'
44
authors = [{name = "Lorenzo Crippa", email="[email protected]"}]
55
description = "An improved version of the sphinx-fortran python module"
66
readme = "README.md"

src/sphinxfortran_ng/crackfortran_for_sphinx.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,10 @@ def _simplifyargs(argsline):
683683

684684
crackline_re_1 = re.compile(r'\s*(?P<result>\b[a-z]+\w*\b)\s*=.*', re.I)
685685
crackline_bind_1 = re.compile(r'\s*(?P<bind>\b[a-z]+\w*\b)\s*=.*', re.I)
686-
crackline_bindlang = re.compile(r'\s*bind\(\s*(?P<lang>[^,]+)\s*,\s*name\s*=\s*"(?P<lang_name>[^"]+)"\s*\)', re.I)
686+
crackline_bindlang = re.compile(
687+
r'\bbind\s*\(\s*(?P<lang>[^,()]+)\s*,\s*name\s*=\s*[\'"](?P<lang_name>[^\'"]+)[\'"]\s*\)',
688+
re.I,
689+
)
687690

688691
def crackline(line, reset=0):
689692
"""
@@ -957,7 +960,7 @@ def _resolvetypedefpattern(line):
957960
return None, [], None
958961

959962
def parse_name_for_bind(line):
960-
pattern = re.compile(r'bind\(\s*(?P<lang>[^,]+)(?:\s*,\s*name\s*=\s*["\'](?P<name>[^"\']+)["\']\s*)?\)', re.I)
963+
pattern = re.compile(r'(?:\s*\bbind\s*\(\s*[^()]*?\))+', re.I)
961964
match = pattern.search(line)
962965
bind_statement = None
963966
if match:
@@ -1150,12 +1153,9 @@ def analyzeline(m, case, line):
11501153
if block in ['function', 'subroutine']: # set global attributes
11511154
# name is fortran name
11521155
if bindcline:
1153-
bindcdat = re.search(crackline_bindlang, bindcline)
1156+
bindcdat = re.findall(crackline_bindlang, bindcline)
11541157
if bindcdat:
1155-
groupcache[groupcounter]['bindlang'] = {name : {}}
1156-
groupcache[groupcounter]['bindlang'][name]["lang"] = bindcdat.group('lang')
1157-
if bindcdat.group('lang_name'):
1158-
groupcache[groupcounter]['bindlang'][name]["name"] = bindcdat.group('lang_name')
1158+
groupcache[groupcounter]['bindlang'] = bindcdat
11591159
try:
11601160
groupcache[groupcounter]['vars'][name] = appenddecl(
11611161
groupcache[groupcounter]['vars'][name], groupcache[groupcounter - 2]['vars'][''])

src/sphinxfortran_ng/fortran_autodoc.py

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858

5959
logger = logging.getLogger(__name__)
6060
fortran_invs = {}
61+
backup_desc = {}
6162

6263
# Fortran parser and formatter
6364
# ----------------------------
@@ -342,6 +343,7 @@ def scan(self):
342343

343344
# Get module description
344345
block['desc'],block['synopsis'] = self.get_comment(modsrc, aslist=True)
346+
345347

346348
# Scan types and routines
347349
for subblock in block['body']:
@@ -393,6 +395,11 @@ def scan_container(self, block, insrc=None):
393395

394396
# Comment
395397
block['desc'],block['synopsis'] = self.get_comment(subsrc, aslist=True)
398+
399+
if block['name'] in backup_desc or block['desc'] == []:
400+
pass
401+
else:
402+
backup_desc[block['name']]=block['desc']
396403

397404
# Scan comments to find descriptions
398405
if block['desc'] and block['block'] in [
@@ -1391,10 +1398,26 @@ def format_var(self, block, indent=0, bullet=False):
13911398
typeshape += '\n\n'
13921399
thedescription = block.get('desc', None)
13931400
try:
1394-
attrs = re.split(r"default=", options['attrs'])
1395-
attrs[0] = re.sub(r",\s*", ", ",':Attributes: ' + attrs[0].strip(','))
1396-
if len(attrs) > 1:
1397-
attrs[1] = ':Default: ' + attrs[1].strip(',')
1401+
1402+
attrstmp = re.split(r"default=", options['attrs'])
1403+
attrs = []
1404+
1405+
pattern = r'bind\(\s*(\w+)\s*,\s*name\s*=\s*"(\w+)"\s*\)'
1406+
match = re.search(pattern, attrstmp[0])
1407+
if match:
1408+
full_match = match.group(0) # e.g., 'bind(x, name="y")'
1409+
bindlang = match.group(1) # e.g., 'x'
1410+
bindname = match.group(2) # e.g., 'y'
1411+
attrstmp[0] = attrstmp[0].replace(full_match, '')
1412+
1413+
if attrstmp[0].strip(',') != '':
1414+
attrs.append(re.sub(r",\s*", ", ",':Attributes: ' + attrstmp[0].strip(',')))
1415+
1416+
if match:
1417+
attrs.append(':Bindings: '+'Language = **'+bindlang+'**, Name = **'+bindname+'** ')
1418+
1419+
if len(attrstmp) > 1:
1420+
attrs.append(':Default: ' + attrstmp[1].strip(','))
13981421
except:
13991422
attrs = ''
14001423
#Search for patterns in the description of the type :something $varname:`something else`
@@ -1481,7 +1504,18 @@ def format_interface(self, block):
14811504

14821505
def format_routine(self, block, indent=0):
14831506
"""Format the description of a function, a subroutine or a program"""
1484-
# Declaration of a subroutine or function
1507+
1508+
try:
1509+
listbinds=block['bindlang']
1510+
attrs = self.format_lines([':Bindings: '])
1511+
attrlist=[]
1512+
for i in range(len(listbinds)):
1513+
stringtoadd = 'Language = **'+block['bindlang'][i][0]+'**, Name = **'+block['bindlang'][i][1]+'** '
1514+
attrlist.append(stringtoadd)
1515+
attrs = attrs + self.format_lines(attrlist, bullet = len(listbinds)>1, indent=indent+1)
1516+
except:
1517+
attrs = ''
1518+
14851519
if isinstance(block, six.string_types):
14861520
if block not in list(self.programs.keys()) + \
14871521
list(self.routines.keys()):
@@ -1512,17 +1546,36 @@ def format_routine(self, block, indent=0):
15121546

15131547
# Treat variables in comment (subroutines and functions only)
15141548
comments = list(block['desc']) + ['']
1549+
if comments == ['']:
1550+
try:
1551+
comments = list(backup_desc[block['name']]) + ['']
1552+
except:
1553+
pass
1554+
1555+
comments.append(attrs)
1556+
15151557
if blocktype == 'subroutine' or blocktype == 'function':
15161558
found = []
1517-
for iline in range(len(comments)):
1518-
if 'vardescmatch' in block:
1519-
m = block['vardescmatch'](comments[iline])
1559+
iline = 0
1560+
while iline < len(comments):
1561+
for key in block['vars']:
1562+
sreg = r'^\s*@param\w*\s+(?P<varname>%s)\s*[:\-–—]\s*(?P<vardesc>.+)' % key
1563+
theregex = re.compile(sreg).match
1564+
m = theregex(comments[iline])
15201565
if m:
1521-
varname = m.group('varname')
1522-
found.append(varname)
1566+
varname = key
15231567
if varname != '':
1524-
comments[iline] = self.format_argfield(
1525-
block['vars'][varname], block=block)
1568+
block['vars'][varname]['desc'] += ' ' + m.group('vardesc')
1569+
comments.pop(iline)
1570+
iline = iline - 1
1571+
iline = iline + 1
1572+
1573+
#comments.append(
1574+
# self.format_argfield(
1575+
# block['vars'][varname],
1576+
# block=block))
1577+
#found.append(varname)
1578+
15261579
for varname in block['args'] + block['sortvars']:
15271580
if varname not in found:
15281581
comments.append(
@@ -1584,7 +1637,7 @@ def format_routine(self, block, indent=0):
15841637
# calls.append(callto)
15851638
#calls = '\n' + self.format_lines(calls, indent=indent + 1)
15861639
#return declaration + description + use + calls + '\n\n'
1587-
return declaration + description + use + '\n\n'
1640+
return declaration + description + use + '\n\n'
15881641

15891642
format_function = format_routine
15901643
format_subroutine = format_routine

0 commit comments

Comments
 (0)