#!/usr/bin/env python
'''Usage: %(program_name)s input.html [output.h|output.html]
where input.html is the HTML source that needs to be filtered
to a generated .h header file (for compiled-in help pages)
or a filtered .html file (for the online manual).
'''
import os, sys
import string, re
import time
# the directory where this script lives, and the Version file relative to it.
program_name = os.path.basename (sys.argv[0])
scriptdir = os.path.dirname (sys.argv[0]) or "."
versionfile = os.path.normpath (scriptdir + "/../../p4/Version")
# Retrieve version and copyright (build) info from p4/Version file
# We need this here so we can use it to initialize some global variables.
def read_Version (filename=versionfile):
f = open (filename)
param = {}
while 1:
line = f.readline ()
if not line:
break
match = re.match ('^\s*([A-Z]\w+)\s*=\s*(.*?)\s*;\s*$', line)
if match:
name = match.group (1)
vals = re.split ('\s+', match.group (2))
param[name] = vals
f.close ()
return param
Version = read_Version()
########################################################################
# Hardcoded AC codes (yuck) -- someday I'll put code to get them
# from the .h file that defines them, and put the dependency
# in the Jamfile. But for now they must be updated by hand.
# See p4-web/Help/p4wAllCommands.h, enum AllCommands.
# (hopefully that will never be necessary since it is recommended to append
# new values rather than insert them and break existing bookmarks.)
AC_HELP = 'ac=21'
AC_ICON = 'ac=20'
RELEASE_VERSION = string.join (Version['RELEASE'][:2], '.')
COPYRIGHT = Version['SUPPDATE'][0]
# X-ref links to other docs:
XREF_LINKS = [ ("quickstart", "Getting Started"),
("howto", "How To..."),
("tips", "Browser Tips"),
("defs", "Glossary"),
("roadmap", "Road Map") ]
# Except for the TITLE tags, the
# the input .html files are already in header-file format. We have to
# do some filtering to convert them to manual page format.
#
# The file suffixes on HREF and IMG tags vary depending on
# whether the output is a .h file or an online manual file.
#
# To make the manual page hrefs, we look for strings like
# href="foo?help#bar" and convert them to href="foo.html#bar"
#
# To make the manual page img links, we look for strings like
# "/foo?icon" and convert them to "../icons/foo.gif"
img_filter_m = '/(.*)\?icon', r'../icons/\1.gif'
href_filter_m = '\?help', r'.html'
# To make the manual page hrefs, we look for strings like
# href="foo?help#bar" and convert them to href="foo?ac=20#bar"
#
# To make the manual page img links, we look for strings like
# "/foo?icon" and convert them to "/fooIcon?ac=19"
img_filter_h = '/(.*)\?icon', r'/\1Icon?'+AC_ICON
href_filter_h = '\?help', r'?'+AC_HELP
# Because I don't have time to figure out how to make this script
# be more forgiving about input file format, note that
# the first line of the input .html must look exactly like
#
#
Help Topic Title
title_filter_h = '(?i)(.*)', r'\1
'
title_filter_m = '(?i)
(.*)', \
(r'P4Web User Guide - \1P4Web Release %(RELEASE_VERSION)s User Guide
' % globals())
heading_filter = '(?i)(.*)', r'\1
'
# Characters that need quoting in output header file:
QH = ['"',"'"]
def init_h(outfp):
# The generated header file has some initialization code:
# (tbd)
return None
def io_setup():
try:
infp = open(sys.argv[1],'r')
except IOError, msg:
print sys.argv[1], ":", msg
sys.exit(1)
# need the filename w/o suffix for the header file:
filename = string.split(os.path.split(sys.argv[1])[1],'.')[0]
outtype = string.split(os.path.split(sys.argv[2])[1],'.')[1]
# If outtype is 'h' we are writing a C++ header file.
# If it already exists, open it for append.
# Otherwise, initialize a new header file:
if outtype == 'h':
mode = 'a'
try:
os.stat(sys.argv[2])
except:
mode = 'w'
try:
outfp = open(sys.argv[2],mode)
except IOError, msg:
print sys.argv[2], ":", msg
sys.exit(1)
if mode == 'w':
init_h(outfp)
elif outtype == 'html':
# we are writing a normal HTML file:
try:
outfp = open(sys.argv[2],'w')
except IOError, msg:
print sys.argv[2], ":", msg
sys.exit(1)
else:
print "Error: output file suffix must be 'h' or 'html'"
sys.exit(1)
return infp, outfp, filename, outtype
########################################################################
def links(outtype):
#
# format the navigation xref links:
#
html_suffix = '.html'
if outtype == 'h':
html_suffix = '?' + AC_HELP
t = ""
for l in XREF_LINKS:
t = t + '[' + l[1] + '] '
t = t + "
\n"
return t
########################################################################
def filter_h(outfp,filename,lines):
# Turn input HTML page content into C++ literals
outfp.write("\n")
outfp.write("const char *" + filename + "Help = \n")
# Convert title to page heading:
lines[0] = re.sub(title_filter_h[0],title_filter_h[1],lines[0])
# Insert xref links into this page content:
lines.insert(0, links('h'))
# Now convert content to C++ literals:
for l in lines:
o = "\t\""
for ll in range(len(l) - 1):
c = l[ll]
if (c in QH): o = o + "\\"
o = o + c
o = o + "\\n\"\n"
o = re.sub(href_filter_h[0], href_filter_h[1], o)
o = re.sub(img_filter_h[0], img_filter_h[1], o)
outfp.write(o)
outfp.write("\t;\n\n")
########################################################################
def filter_m(outfp,lines):
# Turn input HTML file lines into normal HTML file lines
# and write them out.
# Write the page tags:
outfp.write(re.sub(title_filter_m[0], title_filter_m[1], lines[0]))
# Write the xref links:
outfp.write(links('html'))
# Write the page heading tags:
outfp.write(re.sub(heading_filter[0], heading_filter[1], lines[0]))
# Write the rest of the lines, filtering for ?ac stuff:
for l in lines[1:]:
l = re.sub(href_filter_m[0], href_filter_m[1], l)
l = re.sub(img_filter_m[0], img_filter_m[1], l)
outfp.write(l)
outfp.write('''
Copyright %(COPYRIGHT)s Perforce Software.
All rights reserved.
''' % globals())
########################################################################
def usage (status, msg=None):
if msg:
sys.stderr.write ("%s: %s\n\n" % (program_name, msg))
sys.stderr.write (__doc__ % globals ())
sys.exit (status)
def main():
if len(sys.argv) < 2 or len(sys.argv) > 3:
usage (1)
infp, outfp, filename, outtype = io_setup()
fc = infp.readlines()
if re.search(title_filter_m[0], fc[0]) == None:
print "Error: Can't find tags in first line of input " + filename + ".html"
sys.exit(1)
# Generate HTML for navigation links:
if outtype == 'h':
filter_h(outfp,filename,fc)
if outtype == 'html':
filter_m(outfp,fc)
outfp.close()
if __name__ == '__main__':
main()
# eof