Skip to content

Commit

Permalink
Merge branch 'mrestelli-predocmark'
Browse files Browse the repository at this point in the history
  • Loading branch information
cmacmackin committed Jan 19, 2015
2 parents a9e2026 + a0fd0a1 commit f2896de
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 23 deletions.
1 change: 1 addition & 0 deletions example-project-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ author: John Doe
author_description: I program stuff in Fortran.
github: https://github.com/cmacmackin
email: [email protected]
predocmark: >

This is a project which I wrote. This file will provide the documents. I'm
writing the body of the text here. It contains an overall description of the
Expand Down
6 changes: 4 additions & 2 deletions ford/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def main():
u'google_plus',u'linkedin',u'email',u'website',u'project_github',
u'project_bitbucket',u'project_website',u'project_download',
u'project_sourceforge',u'project_url',u'display',u'version',
u'year',u'docmark',u'media_dir',u'favicon']
u'year',u'docmark',u'predocmark',u'media_dir',u'favicon']
defaults = {u'project_dir': u'./src',
u'extensions': [u"f90",u"f95",u"f03",u"f08"],
u'output_dir': u'./doc',
Expand All @@ -91,6 +91,7 @@ def main():
u'year': date.today().year,
u'exclude': [],
u'docmark': '!',
u'predocmark': '',
u'favicon': 'default-icon',
}

Expand Down Expand Up @@ -124,7 +125,8 @@ def main():
# Parse the files in your project
project = ford.fortran_project.Project(proj_data['project'],
proj_data['project_dir'], proj_data['extensions'],
proj_data['display'], proj_data['exclude'], proj_data['docmark'])
proj_data['display'], proj_data['exclude'],
proj_data['docmark'], proj_data['predocmark'])
if len(project.files) < 1:
print "Error: No source files with appropriate extension found in specified directory."
quit()
Expand Down
5 changes: 3 additions & 2 deletions ford/fortran_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ class Project(object):
project which is to be documented.
"""
def __init__(self,name,topdir=".",extensions=["f90","f95","f03","f08"],
display=['public','protected'], exclude=[],docmark='!'):
display=['public','protected'], exclude=[],
docmark='!', predocmark=''):
self.name = name
self.topdir = topdir
self.extensions = extensions
Expand All @@ -47,7 +48,7 @@ def __init__(self,name,topdir=".",extensions=["f90","f95","f03","f08"],
self.types = []
self.display = display

ford.sourceform.set_doc_mark(docmark)
ford.sourceform.set_doc_mark(docmark,predocmark)

# Get all files within topdir, recursively
srctree = os.walk(topdir)
Expand Down
60 changes: 43 additions & 17 deletions ford/reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ class FortranReader(object):
- combine line continuations into one
- remove any normal comments and any comments following an ampersand
(line continuation)
- if there are documentation comments preceding a piece of code, buffer
them and return them after the code, but before and documentation
following it
- keep any documentation comments and, if they are at the end of a line
of actual code, place them on a new line
- removes blank lines and trailing white-space
Expand All @@ -46,13 +49,19 @@ class FortranReader(object):
COM_RE = re.compile("^([^\"'!]|(\'[^']*')|(\"[^\"]*\"))*(!.*)$")
SC_RE = re.compile("^([^;]*);(.*)$")

def __init__(self,filename,docmark='!'):
def __init__(self,filename,docmark='!',predocmark=''):
self.name = filename
self.reader = open(filename,'r')
self.docbuffer = ""
self.docbuffer = []
self.pending = []
self.prevdoc = False
self.docmark = docmark
self.doc_re = re.compile("^([^\"'!]|('[^']*')|(\"[^\"]*\"))*(!{}.*)$".format(docmark))
self.predocmark = predocmark
if len(self.predocmark) != 0:
self.predoc_re = re.compile("^([^\"'!]|('[^']*')|(\"[^\"]*\"))*(!{}.*)$".format(predocmark))
else:
self.predoc_re = None

def __iter__(self):
return self
Expand All @@ -65,39 +74,57 @@ def next(self):
if len(self.pending) != 0:
self.prevdoc = False
return self.pending.pop(0)
# If there was documentation at the end of the previous line, return
# it as the next line.
# If there are any documentation lines waiting to be returned, return them.
# This can happen for inline and preceding docs
elif len(self.docbuffer) != 0:
tmp = self.docbuffer
self.docbuffer = ""
self.prevdoc = True
return tmp
return self.docbuffer.pop(0)

# Loop through the source code until you have a complete line (including
# all line continuations)
# all line continuations), or a complete preceding doc block
done = False
continued = False
reading_predoc = False
linebuffer = ""
while not done:
line = self.reader.next()
if len(line.strip()) > 0 and line.strip()[0] == '#': continue

# Capture any preceding documenation comments
if self.predoc_re:
match = self.predoc_re.match(line)
else:
match = False
if match:
# Switch to predoc: following comment lines are predoc until the end of the block
reading_predoc = True
# Substitute predocmark with docmark
tmp = match.group(4)
tmp = tmp[:1] + self.docmark + tmp[1+len(self.predocmark):]
self.docbuffer.append(tmp)
if len(line[0:match.start(4)].strip()) > 0:
raise Exception("Preceding documentation lines can not be inline")

# Capture any documentation comments
match = self.doc_re.match(line)
if match:
self.docbuffer = match.group(4)
self.docbuffer.append(match.group(4))
line = line[0:match.start(4)]

# Remove any regular comments
match = self.COM_RE.match(line)
if match:
line = line[0:match.start(4)]
line = line.strip()

# If this is a blank line following previous documentation, return
# a line of empty documentation.
if len(line) == 0:
if self.prevdoc and len(self.docbuffer) == 0:
#~ self.prevdoc = False
self.docbuffer = "!!"
self.docbuffer.append("!"+self.docmark)
else:
reading_predoc = False
# Check if line is immediate continuation of previous
if line[0] == '&':
if continued:
Expand All @@ -109,14 +136,14 @@ def next(self):
# Check if line will be continued
if line[-1] == '&':
continued = True
self.docbuffer = ""
line = line[0:-1]
else:
continued = False
# Add this line to the buffer then check whether we're done here

# Add this line to the buffer then check whether we're done here
linebuffer += line
done = (len(self.docbuffer) > 0) or ((not continued) and
(len(linebuffer) > 0))
done = ( ((len(self.docbuffer) > 0) or (len(linebuffer) > 0)) and
not continued and not reading_predoc )

# Split buffer with semicolons
frags = ford.utils.quote_split(';',linebuffer)
Expand All @@ -127,9 +154,8 @@ def next(self):
self.prevdoc = False
return self.pending.pop(0)
else:
tmp = self.docbuffer
self.docbuffer = ""
if tmp != "!!":
tmp = self.docbuffer.pop(0)
if tmp != "!"+self.docmark:
self.prevdoc = True;
return tmp

Expand Down
7 changes: 5 additions & 2 deletions ford/sourceform.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@

base_url = ''
docmark = '!'
predocmark = ''

#TODO: Add ability to note EXTERNAL procedures, PARAMETER statements, and DATA statements.
class FortranBase(object):
Expand Down Expand Up @@ -429,7 +430,7 @@ def __init__(self,filepath):
self.doc = []
self.hierarchy = []
self.obj = 'sourcefile'
source = ford.reader.FortranReader(self.path,docmark)
source = ford.reader.FortranReader(self.path,docmark,predocmark)
FortranContainer.__init__(self,source,"")
readobj = open(self.path,'r')
self.src = readobj.read()
Expand Down Expand Up @@ -1074,9 +1075,11 @@ def parse_type(string,capture_strings):
def set_base_url(url):
FortranBase.base_url = url

def set_doc_mark(mark):
def set_doc_mark(mark,premark):
global docmark
docmark = mark
global predocmark
predocmark = premark

def get_mod_procs(source,line,parent):
inherit_permission = parent.permission
Expand Down

0 comments on commit f2896de

Please sign in to comment.