Skip to content

Commit

Permalink
work
Browse files Browse the repository at this point in the history
  • Loading branch information
Leonardo Cecchi committed Oct 9, 2012
1 parent 7a367fc commit 431ceb9
Showing 1 changed file with 92 additions and 11 deletions.
103 changes: 92 additions & 11 deletions sslit.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,65 @@
#>
# Bare literate programming tool
# ==============================
#<

import sys

#>
# This is an implementation of a bare literate programming tool.
# This literate programming style doesn't support macros not file
# generation.
#
# To cut a long story short, this literate programming tool extracts
# MarkDown-style comments from a source code. The code, instead, is
# formatted as a preformatted block.
#
# To recognize markdown-documentation from source code the documentation
# must came before a particular "documentation start" marker and must
# be followed by a particular "documentation end" marker.
#
# A documentation start line must:
#
# * be long 3 characters or less;
# * end with a `>` sign.
#<
import sys

def tabToSpaces(row):
result = ""
while len(row)>0 and row[0]=='\t':
result += " "
row = row[1:]
result += row
return result
def isDocumentationStart(line):
return len(line)<=3 and line.endswith(">")

#>
# A documentation end line must:
#
# * be long 3 characters or less;
# * end or start with a `<` sign.
#<

def isDocumentationEnd(line):
return len(line)<=3 and (line.endswith("<") or line.startswith("<"))

#>
# Documentation extractor
# -----------------------
#
# The documentation extractor is implemented as a simple state machine
# which can be in code-status or in documentation-status. Every state
# machine status can output the extracted documentation:
#<

class Status(object):
def output(self, s):
print s

#>
# ### Code status
#
# The code status outputs, before the source code, 4 spaces. This is the
# MarkDown syntax for a code block. The first line of a code block is used
# to calculate a common prefix for all the lines of the code block.
#
# This renders correctly source code with a common indentation level.
#<

class CodeStatus(Status):
def __init__(self):
self._firstLine = True
Expand All @@ -31,7 +74,14 @@ def process(self, row):
row = row[self._firstCol:]

self.output(" " + row)


#>
# ### Documentation status
#
# The documentation status simply output the documentation as-is without
# a common prefix (if exists):
#<

class TextStatus(Status):
def __init__(self):
self._firstLine = True
Expand All @@ -49,21 +99,51 @@ def process(self, row):

self.output(row)

#>
# ### State machine
#
# The current status is changed when the program see a documentation start/end line:
#<

def process(fileName):
status = CodeStatus()

for row in open(fileName):
row = row.rstrip()
row = tabToSpaces(row)

if len(row.strip())<=3 and row.endswith(">"):
if isDocumentationStart(row.strip()):
status = TextStatus()
status.process(row)
elif len(row.strip())<=3 and row.lstrip().startswith("<"):
elif isDocumentationEnd(row.strip()):
status = CodeStatus()
else:
status.process(row)

#>
# Utilities
# ---------
#
# To calculate the common prefix of a documentation block the source code lines
# are considerated with tabs expanded to 4 spaces:
#<

def tabToSpaces(row):
result = ""
while len(row)>0 and row[0]=='\t':
result += " "
row = row[1:]
result += row
return result

#>
# Starting point
# --------------
#
# The script file implements only a file filter: it takes an input file parameter
# and write, on the standard output device, the extracted documentation:
#<

def main():
if len(sys.argv)!=2:
print "Use:", sys.argv[0], "<in>"
Expand All @@ -72,3 +152,4 @@ def main():
process(sys.argv[1])

if __name__=="__main__": main()

0 comments on commit 431ceb9

Please sign in to comment.