')
html_suffix_regex = re.compile('\.html$')
def __init__(self, current_directory):
self.current_directory = current_directory
self.originals_directory = os.path.join(current_directory, 'original_html')
if not os.path.exists(self.originals_directory):
os.mkdir(self.originals_directory)
self.modifiers = []
def RegisterModifier(self, modifier):
"""Adds the modifier function to the list of modifier functions.
Args:
modifier: the function modifies a list of strings of code
"""
self.modifiers += [modifier]
def MakeBackupCopy(self, input_file):
"""Makes backup copy of input_file by copying to originals directory.
Args:
input_file: basename of file to backup.
"""
shutil.copy(os.path.join(self.current_directory, input_file),
self.originals_directory)
def PerformFunctionsOnFile(self, input_file):
"""Opens a file as a list, modifies the list and writes to same file.
Args:
input_file: the file being operated on.
"""
infile = open(input_file, 'r')
lines_list = infile.readlines()
infile.close()
for function in self.modifiers:
lines_list = function(lines_list)
outfile = open(input_file, 'w')
outfile.writelines(lines_list)
outfile.close()
def FixBrackets(self, lines_list):
"""Adjust brackets to be ezt style.
Fix the brackets such that any open bracket '[' becomes '[[]' in order to
not conflict with the brackets ezt uses as special characters.
EZT uses boilerplate code at the beginning and end of each file. When
editing a file, however, we don't want to touch the boilerplate code.
We can look for special indicators through regular expressions of
where the content lies between the boilerplate sections and then only
apply the desired function line by line to the html between those
sections.
This is a destructive operation and will write over the input file.
Args:
lines_list: the file to fix broken into lines.
Returns:
the lines_list with correctly formatted brackets.
"""
outside_boilerplate = False
for index, line in enumerate(lines_list):
if self.content_end_regex.search(line) and outside_boilerplate:
# We've reached the end of content; return our work
return lines_list
elif self.content_start_regex.search(line):
# We've found the start of real content, end of boilerplate
outside_boilerplate = True
elif outside_boilerplate:
# Inside real content; fix brackets
lines_list[index] = line.replace('[', '[[]')
else:
pass # Inside boilerplate.
return lines_list
def RemoveNavigation(self, lines_list):
"""Remove html defining navigation tabs.
This function removes the lines between the
...
which will eliminate the navigation tabs Doxygen outputs at the top of
its documentation. These are extraneous for Google's codesite which
produces its own navigation using the ezt templates.
Nested
's are handled, but it currently expects no more than one
...
set per line.
This is a destructive operation and will write over the input file.
Args:
lines_list: the lines of the file to fix.
Returns:
the lines_list reformatted to not include tabs div set.
"""
start_index = -1
div_queue = []
start_end_pairs = {}
for index, line in enumerate(lines_list):
# Start by looking for the start of the navigation section
if self.navigation_regex.search(line):
start_index = index
if self.div_regex.search(line):
if start_index > -1:
div_queue.append(index)
if self.div_end_regex.search(line):
if start_index > -1:
# If we pop our start_index, we have found the matching
# to our
if div_queue.pop() == start_index:
start_end_pairs[start_index] = index
start_index = -1
# Delete the offending lines
keys = start_end_pairs.keys()
keys.sort()
keys.reverse()
for k in keys:
del lines_list[k:start_end_pairs[k]+1]
return lines_list
def RenameFiles(self, input_file):
"""Fix file suffixes from .html to .ezt.
This will also backup original html files to the originals directory.
This operation will overwrite the previous ezt file.
NOTE: If the originals directory is not a directory, the file will
be overwritten.
Args:
input_file: the file to fix.
"""
# If the file does not end in .html, we do not want to continue
if self.html_suffix_regex.search(input_file):
new_name = re.sub(self.html_suffix_regex, '.ezt', input_file)
shutil.copy(input_file, self.originals_directory)
# Rename file. If file exists, rename will not overwrite, and produce
# OSError. So delete the old file first in that case.
try:
os.rename(input_file, new_name)
except OSError:
os.remove(new_name)
os.rename(input_file, new_name)
def main():
usage_string = ('This script is meant to convert .html files into .ezt files '
'in addition to eliminating any C++-style notations and '
'replacing them with their Javascript-style counter parts.\n'
'Note: This will write over existing files as well as nuke '
'any associated directories such as "original_html" located '
'in the same directory as the first argument\n'
'Usage: ezt_formatter.py ')
files = sys.argv[1:]
if not files:
# We have no files, so return, showing usage
print usage_string
return
# current_directory should be the same for all files
current_directory = os.path.dirname(files[0])
formatter = EZTFormatter(current_directory)
dj = DoxygenJavascriptifier()
formatter.RegisterModifier(formatter.RemoveNavigation)
formatter.RegisterModifier(dj.Javascriptify)
formatter.RegisterModifier(formatter.FixBrackets)
for f in files:
formatter.PerformFunctionsOnFile(f)
formatter.RenameFiles(f)
formatter.MakeBackupCopy('stylesheet.css')
if __name__ == '__main__':
main()