#!/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(''' <P> <HR> <FONT SIZE=-1><I> Copyright %(COPYRIGHT)s <A HREF="http://www.perforce.com">Perforce Software</A>. All rights reserved. </I></FONT> </BODY></HTML> ''' % 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 <TITLE> 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