#!/usr/bin/env python # convert CLAWPACK source code, data files, READMEs, etc. into html. # for example, # clawcode2html filename.f # generates # filename.f.html # If filename.f.html already exists, you will be prompted before # overwriting unless the -f or --force flag is used, e.g. # clawcode2html --force filename.f # # Based on mathcode2html.py from # http://www.amath.washington.edu/~rjl/mathcode2html # with some modifications for CLAWPACK. # # The environment variable CLAW must be properly set to the root # of the claw directory before using this script. # # Most of code is put into
environment.
# Any comments enclosed by begin_html and end_html are taken out
# of the environment and indented properly (using a table)
# to match the surrounding code.
# By default, the html comments are offset in blue font, except if the
# input file has extension .txt or no extension, in which case it's
# left as black. The default_color can be changed below.
# Also, the begin_html line may contain [color: red] for example,
# to determine the color of this comment.
# You may modify the recognized extensions and comment characters below.
# Allows many latex commands in comments if jsMath is used on webpage.
# In this case make sure the variable jsMathScript is properly set below.
# If you don't want to include a call to the jsMath script on the html
# page, invoke mathcode2html with the --nojsmath option.
#---------------------------------------------------------------------------
# Copyright (C) 2008 Randall J. LeVeque
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details,
# http://www.gnu.org/licenses/
#---------------------------------------------------------------------------
import sys,os,glob
import string,re
import time
from optparse import OptionParser
# parse command line arguments:
parser = OptionParser()
parser.add_option("-f", "--force",
action="store_true", dest="forced", default=False,
help="force action even if it overwrites html file")
parser.add_option("--nojsmath",
action="store_false", dest="usejsMath", default=True,
help="don't include call to jsMath script in html")
parser.add_option("-q", "--quiet",
action="store_false", dest="verbose", default=True,
help="don't print status messages to stdout")
parser.add_option("--noheader",
action="store_false", dest="header", default=True,
help="suppress printing header at top of html page")
(options, infiles) = parser.parse_args()
forced = options.forced
usejsMath = options.usejsMath
verbose = options.verbose
header = options.header
# CLAWPACK environment variables:
try:
clawdir = os.getenv('CLAW') # assumes environment variable set properly
except:
print "CLAW environment variable not set"
print "You need to run setenv.py before setup.py"
sys.exit(1)
if clawdir == None:
print "CLAW environment variable not set"
print "You need to run setenv.py before setup.py"
sys.exit(1)
# Create addresses for links on html pages.
# change the lines below if you want to point to a webpage home instead
# of the local file system (e.g. clawaddr = "http://www.mywebpage/claw")
clawaddr = 'file://%s' % os.getcwd()
# Set comment characters for different programming languages:
# Augment or modify as desired.
commentchar = { '.f' : ['!', '#'], \
'.m' : '%', \
'.py' : '#', \
'.data' : ['#','=:'], \
'.txt': None, \
'' : None}
firstfort = ['c','*','C','!'] # valid fortran comment char's in col. 1
leadingindent = '' # additional indentation for webpage, if desired
default_color = 'blue'
try:
infiles.remove('clawcode2html.py') # can't apply this code to itself!
except:
pass
for infilename in infiles:
# check if this is a code file of a recognized language.
ext = os.path.splitext(infilename)[1]
if not commentchar.has_key(ext):
print " "
print " Warning: Unrecognized extension, will proceed"
print " with no replacement of comment characters"
commentchar[ext] = None
# open input and output files:
#-----------------------------
try:
ifile = open(infilename,'r')
except:
print "File not found:", infilename
sys.exit(1)
outfilename = infilename + '.html'
if (glob.glob(outfilename) != []) & (not forced):
sys.stdout.write(' OK to overwrite %s? ' % outfilename)
answer = raw_input()
if answer not in ['y','Y','yes']:
print ' Aborting!'
sys.exit(1)
ofile = open(outfilename,'w')
# start creating html file:
#--------------------------
if verbose:
print ' Converting ', infilename, ' to ', outfilename
ofile.write('\n %s \n' % outfilename)
# determine time and reformat:
time1 = time.asctime()
year = time1[-5:]
day = time1[:-14]
hour = time1[-13:-5]
creationtime = day + year + ' at ' + hour
# put full file name with path into a comment for future reference:
fullinfilename = os.path.join(os.getcwd(),infilename)
ofile.write('\n\n' % fullinfilename)
ofile.write('\n\n' % creationtime)
if header:
ofile.write(
"""
""")
#ofile.write(' \n')
ofile.write(' \n')
ofile.write(' %s \n' % outfilename)
ofile.write('clawcode2html\n'\
% clawaddr)
ofile.write(' \n')
ofile.write(' Source file: %s \n' \
% (infilename,infilename))
ofile.write(' \n')
ofile.write(' Directory: %s \n' % os.getcwd())
ofile.write(' \n')
ofile.write(' Converted: %s \n' % creationtime)
ofile.write(' \n')
ofile.write(' This documentation file will \n')
ofile.write('not reflect any later changes in the source file. \n')
ofile.write('
\n')
ofile.write('\n')
if usejsMath:
# jsMath stuff: (delete if you don't want jsMath for latex commands)
# Set jsMathScript to the file or URL of the java script load.js.
jsMathScript = "%s/doc/load.js" % clawaddr
ofile.write(" \n")
ofile.write(" \n" % jsMathScript)
ofile.write("""
$\phantom{******** If you see this on the webpage then the
browser could not locate *********}$
$\phantom{******** jsMath/easy/load.js or the variable root
is set wrong in this file *********}$
\n""")
# define any latex macros that you want to use in jsMath:
ofile.write("""
$\\newcommand{\\vector}[1]{\\left[\\begin{array}{c} #1 \\end{array}\\right]}$
$\\newenvironment{matrix}{\\left[\\begin{array}{cccccccccc}} {\\end{array}\\right]}$
$\\newcommand{\\A}{{\\cal A}}$
$\\newcommand{\\W}{{\\cal W}}$
\n""")
#
# end of jsMath stuff
#----------------------------------------------------------------------
# start writing input file to output file...
# code is in pre-formatted environment:
ofile.write('
\n')
insidehtml = 0; # set to 1 when we're processing html comments
lineno = 0; # line number counter for error message
for line in ifile:
lineno += 1
if string.count(line,"begin_html"):
regexp = re.compile(r"\[color:(?P[^\]]*)\]")
result = regexp.search(line)
if result:
font_color = result.group('color')
else:
font_color = default_color
if insidehtml:
print ' Error at line ', lineno, '\n'
print ' Unexpected begin_html when already in html mode\n'
print ' Missing end_html? \n'
sys.exit(1)
# switch out of pre-formatted mode and create table to indent
ofile.write(' \n\n')
# The first column of the table is spaces for indentation
# to match surrounding source code.
# Count how many spaces there are before the begin_html
# or to the first comment character preceeding that string:
regexp = re.compile(r"(?P[ ]*)(#|!|%|begin)")
result = regexp.search(line)
if result:
numindent = len(leadingindent) + len(result.group('spaces'))
numindent = numindent
ofile.write('')
for i in range(numindent):
ofile.write(' ')
ofile.write('')
else:
print ' Strange error in clawcode2html - should not be here'
print ' at line number ', lineno
ofile.write('\n \n')
# the next column of the table has the comment itself:
ofile.write('\n')
if ext not in ('.txt', ''):
# use colored font for comments except for text files.
ofile.write('\n' % font_color)
insidehtml = 1;
elif string.count(line,"end_html"):
# switch back to pre-formatted environment
ofile.write('
\n')
ofile.write('\n')
insidehtml = 0;
else:
if insidehtml:
# replace blank line in html comment by new paragraph :
blankline = (string.split(line) == [])
if not blankline:
firstchar = string.split(line)[0][0]
if ((ext == '.f') & (firstchar not in firstfort)):
if firstchar not in commentchar[ext]:
print ' Error... in line ', lineno,'\n' \
' In html but not in a comment.'\
' Forgotten "end_html" ?'
sys.exit(1)
if ext == '.f':
# fortran comments may have comment symbol in column 1
# strip lines inside an html comment of leading symbol:
if line[0] in firstfort:
line = ' ' + line[1:]
# replace any comment character by ' '
if commentchar[ext]:
for char in commentchar[ext]:
line = string.replace(line,char,' ')
blankline = (string.split(line) == [])
if blankline:
line = ('
\n')
# Allow wiki formatting of links:
# replace links of the form [code: target]
# by html links to both target and target.html
regexp = re.compile(r"\[code:(?P[^\]]*)\]")
result = regexp.search(line)
while result:
targetname = result.group('target')
oldpat = result.group()
newpat = '' + \
targetname + ' ' + \
'' + \
'[.html]'
line = line.replace(oldpat,newpat)
result = regexp.search(line)
# replace links of the form [link: target text]
# by an html link from text to the target page.
regexp = re.compile(r"\[link:[ ]?(?P[^ ]*)" + \
r"([ ]*)(?P[^\]]*)\]")
result = regexp.search(line)
while result:
targetname = result.group('target')
text = result.group('text')
oldpat = result.group()
if text=='':
text = targetname
newpat = '' + \
text + ' '
line = line.replace(oldpat,newpat)
result = regexp.search(line)
# replace links of the form [http:etc text]
# by an html link from text to the http page.
regexp = re.compile(r"\[http:(?P[^ ]*)" + \
r"([ ]*)(?P[^\]]*)\]")
result = regexp.search(line)
while result:
targetname = result.group('target')
text = result.group('text')
oldpat = result.group()
if text=='':
text = targetname[2:]
newpat = '' + \
text + ' '
line = line.replace(oldpat,newpat)
result = regexp.search(line)
# replace links of the form [www.etc text]
# by an html link from text to the http://www.etc page.
regexp = re.compile(r"\[www.(?P[^ ]*)" + \
r"([ ]*)(?P[^\]]*)\]")
result = regexp.search(line)
while result:
targetname = result.group('target')
text = result.group('text')
oldpat = result.group()
if text=='':
text = 'www.' + targetname
newpat = '' + \
text + ' '
line = line.replace(oldpat,newpat)
result = regexp.search(line)
# special things for CLAWPACK:
# replace links of the form [clawcode:clawpack/1d/lib/step1.f]
# for example by links relative to clawaddr,
# along with a link to the .html version.
regexp = re.compile(r"\[clawcode:(?P[^\]]*)\]")
result = regexp.search(line)
while result:
targetname = result.group('target').lstrip()
oldpat = result.group()
newpat = '' + 'claw/' + targetname + ' ' + \
'' + '[.html]'
line = line.replace(oldpat,newpat)
result = regexp.search(line)
# replace links of the form [claw:clawpack/1d/lib]
# for example by links relative to clawaddr,
# with no .html version.
regexp = re.compile(r"\[claw:(?P[^\]]*)\]")
result = regexp.search(line)
while result:
targetname = result.group('target')
oldpat = result.group()
newpat = '' + 'claw/' + targetname + ' '
line = line.replace(oldpat,newpat)
result = regexp.search(line)
else:
# not insidehtml - make regular comments default_color.
# Determine if this line contains a comment and if so,
# what column the comment starts in:
startcomment = 1000
if (ext == '.f') & (line[0] in firstfort):
startcomment = 0
else:
if commentchar[ext]:
for c in commentchar[ext]:
commentcol = string.find(line,c)
if (commentcol>-1)&(commentcol' % default_color + \
line[startcomment:-1] + '\n'
# output the (possibly modified) line to the output file:
ofile.write('%s' % leadingindent+line)
# Done with all lines. Add closing stuff at bottom of html file:
ofile.write('
\n')
ifile.close()
ofile.close()