#! /usr/bin/env python # # Severly hacked version of ht2html.py originally written by Guido van Rossum # My version allows eleven different color 'motifs': red, brown, pink, # orange, purple, black, olive, bluepurple, blue, green, and sienna # These are specified via the 'pagecolor' metadata tag. # # During the parsing of the links.h file (which contains the anchors # for the navigation bar, the program now also tries to determine the # color 'motif' for the page by opening its .ht file and looking for # the pagecolor tag. If it exists, it sets the background in the # nav bar for that row to be the lightcolor corresponding to the # color motif specified for that page. # # I also allow for a 'split_content' metadata tag which when defined # parses the contents into two parts 'shared' and 'not-shared'. The # shared part is to the left of the 'navigational-links'. The # 'not-shared' part is fully below the nav-links. This is so long # pages doe not waste so much space being occupied with en empty nav # bar toward the middle and bottom of the page. The catch is you need # to add: in your page where you want # the split to occur. # # You may use this script freely. While the authors have tryed to make the # results of using this script predictable, we are not liable for # any damages that may result from the use of this software. # # Roger E. Masse import os import sys import errno import re import rfc822 import string import getopt import whrandom # ROOTDIR must be set to the name of the web pages root directory, # and specifically, the dir which contains the script dir. ROOTDIR = "www.python.org" def fixpath(): """Add the directory containing the script to the front of sys.path. Do not do this if we're being imported as a module, or if it is absent or if it is the current directory, or if it is already there. """ if __name__ != '__main__': return scriptname = sys.argv[0] dirname = os.path.dirname(scriptname) if not dirname or dirname == os.curdir: return dirname if dirname not in sys.path: sys.path.insert(0, dirname) return dirname SCRIPTDIR = fixpath() from FileWrapper import FileWrapper def main(): backup = "" verbose = "" relative = "" compare = "C" rootdir = ROOTDIR root = None cornerbanner = None try: opts, args = getopt.getopt(sys.argv[1:], "vbfrR:t:s:c:") except getopt.error, msg: usage(msg) if not args: usage("no files specified") for o, a in opts: if o == '-v': verbose = "V" if o == '-b': backup = "B" if o == '-f': compare = "" if o == '-r': relative = "R" if o == '-R': relative = "R"; rootdir = a if o == '-s': root = a if o == '-t': loadtemplate(a) if o == '-c': cornerbanner = a mode = "w" + backup + compare + verbose + relative if relative: # - interpret args as being wrt current directory, # - and translate them to be wrt www.python.org web pages root # (named according to value of 'rootdir' variable) # - and then cd to the web pages root, so we work with respect to it. reldir, updir = below(os.getcwd(), rootdir) for i in range(len(args)): args[i] = os.path.normpath(os.path.join(reldir, args[i])) os.chdir(updir) dolist(args, mode, root, cornerbanner) def dosubdir(dir, mode, root): print "Checking subdirectory", dir, "..." files = [] try: names = os.listdir(dir) except os.error, msg: print "Can't list", dir, ":", msg return for name in names: if name[-5:] == 'html' or name[0] == '.': continue file = os.path.join(dir, name) if file[-3:] == '.ht' or (name != 'RCS' and name != 'CVS' and os.path.isdir(file) and not os.path.islink(file)): files.append(file) files.sort() dolist(files, mode, root) def dolist(args, mode, root=None, cornerbanner=None): for file in args: if os.path.isdir(file): dosubdir(file, mode, root) continue name, ext = os.path.splitext(file) if ext == '.html': print "Won't overwrite", file continue htmlfile = name + '.html' try: fi = open(file, "r") except IOError, msg: print "Can't open", file, ":", msg continue try: fo = FileWrapper(htmlfile, mode) except (os.error, IOError), msg: print "Can't create", htmlfile, ":", msg else: try: process(fi, fo, name, file, root, cornerbanner) fo.close() try: os.chmod(htmlfile, 0664) except os.error, e: # TBD: should we really discriminate? code, msg = e if code == errno.EPERM: sys.stderr.write( 'WARNING: Could not change permission on file: ' + htmlfile + ', %s (errcode: %d)\n' % (msg, code)) else: raise e finally: fo.close("abort") fi.close() def usage(msg=None): sys.stdout = sys.stderr if msg: print msg print "usage:", sys.argv[0], "[-v] [-b] [-f] file.ht ..." print "-v: verbose (report files written/moved/removed)" print "-b: make backup of old html file if overwritten" print "-f: force writing html file (even if no change)" print "-r: relative mode (ask Ken)" print "-R rootdir: set rootdir for relative mode; implies -r" print "-s url: set URL used for root; must end in /" print "-t file: use the template defined in file" print "-c : specify the cornerbanner for the page" sys.exit(2) def loadtemplate(name): if not name: return rootpath = os.path.normpath(os.path.join(SCRIPTDIR, os.pardir)) filename = os.path.join(rootpath, name) try: execfile(filename, globals()) except (IOError, SyntaxError), msg: print "%: Couldn't load template: %s" % (`filename`, str(msg)) SITELINKS = [ ("./", "Home"), ("About.html", "About"), ("Help.html", "Help"), ("People.html", "Community"), ] HEAD = """\ %(title)s%(meta)s """ SIDEBAR = """
   %(sitelinks)s
%(otherlinks)s
Email us
%(author)s

  
""" TAIL = """
""" TAILTOP = """

""" WIDEHEAD = """
""" WIDETAIL = """ """ SPLITMARKER = """""" DARKBGCOLORMARKER = 'BGCOLOR="#003366"' # these should be set to the dark and LIGHTBGCOLORMARKER = 'BGCOLOR="#99CCFF"' # light colors of your 'template' file # that is the style file that acts as # a template for all the content. def process(fi, fo, name, file, root=None, cornerbanner=None): print "Processing", file, "..." name = os.path.normpath(name) comps = string.split(name, os.sep) depth = len(comps) - 1 root = root or "../" * depth bgcolor = "#FFFFFF" fgcolor = "#000000" linkcolor = "#0000BB" vlinkcolor = "#551A8B" alinkcolor = "#FF0000" msg = rfc822.Message(fi) widepage = msg.getheader('wide-page') or "" title = msg.getheader('title') or comps[-1] meta = msg.getheader('meta') or "" if meta: meta = "\n" + meta author = msg.getheader('author') or 'webmaster@python.org' split_content = msg.getheader('split_content') or "" fixed_author = re.sub("(?i)
", "", author) rawbanner = msg.getheader('banner') or "" banner = root + "pics/" + (rawbanner or "pythonHi.gif") banneralt = msg.getheader('banner-alt') or "Python" ol1 = load_other_links(file, msg.getheader('links')) ol2 = msg.getheader('other-links') or "" pagecolor = msg.getheader('pagecolor') darkshade, mediumshade, lightshade = getpagecolor(pagecolor) ## lampshade = None sitelinks = make_sitelinks(name, root) % vars() otherlinks = fix_otherlinks(name, ol1 + ol2) % vars() # the command line arguement overrides the 'autoselect' mechanism if cornerbanner is None: if not pagecolor: cornerbanner = pick_cornerbanner() else: cornerbanner = "mswe613_%s.gif" % pagecolor fo.write(HEAD % vars()) if widepage: fo.write(WIDEHEAD % vars()) else: fo.write(SIDEBAR % vars()) # process user page if split_content or pagecolor: while 1: line = fi.readline() if not line: split_content = 0 break if string.find(line, SPLITMARKER) <> -1: fo.write(line) fo.write(TAILTOP) continue i = string.find(string.upper(line), DARKBGCOLORMARKER) if i <> -1: newline = replacecolor(line , i, DARKBGCOLORMARKER, darkshade) fo.write(newline) continue i = string.find(string.upper(line), LIGHTBGCOLORMARKER) if i <> -1: newline = replacecolor(line , i, LIGHTBGCOLORMARKER, lightshade) fo.write(newline) continue fo.write(line) else: fo.writelines(fi.readlines()) if widepage or split_content: fo.write(WIDETAIL % vars()) else: fo.write(TAIL % vars()) def getpagecolor(pagecolor): if pagecolor == 'green': lightshade = "#99FFCC" mediumshade = "#33FF99" darkshade = "#006633" elif pagecolor == 'sienna': lightshade = "#FFCC99" mediumshade = "#CC9966" darkshade = "#A1690C" elif pagecolor == 'blue': lightshade = "#99CCFF" mediumshade = "#3399FF" darkshade = "#003366" elif pagecolor == 'brown': lightshade = "#CA957A" mediumshade = "#AD5B32" darkshade = "#993300" elif pagecolor == 'shockingpink': lightshade = "#F28ACF" mediumshade = "#E93EB0" darkshade = "#E10096" elif pagecolor == 'pink': lightshade = "#F6A7DC" mediumshade = "#EE6CC3" darkshade = "#E661A2" elif pagecolor == 'orange': lightshade = "#FFA892" mediumshade = "#FF6842" darkshade = "#E8690C" elif pagecolor == 'purple': lightshade = "#C59BD0" mediumshade = "#9247A7" darkshade = "#680085" elif pagecolor == 'black': lightshade = "#9B9B9B" mediumshade = "#3C3C3C" darkshade = "#000000" elif pagecolor == 'olive': lightshade = "#AAAB8D" mediumshade = "#727342" darkshade = "#424301" elif pagecolor == 'bluepurple': lightshade = "#A59EBA" mediumshade = "#52467B" darkshade = "#110048" else: # pagecolor == 'red': lightshade = "#D3828A" mediumshade = "#B93845" darkshade = "#A60212" return darkshade, mediumshade, lightshade def replacecolor(line, i, oldmarker, newshade): """Replace the color specified by oldmarker with the one specified in newshade""" first = line[:i] middle = line[i:i+len(oldmarker)] last = line[i+len(oldmarker):] colorparts = string.split(middle, '"') middle = colorparts[0] + '"' + newshade + '"' newline = first + middle + last #print "replacing: ", line #print "with: ", newline return newline def make_sitelinks(name, root): """Massage the site navigation panel into submission.""" name = name + ".html" list = [] for (link, label) in SITELINKS: s = label if samedir(link, name): # Don't make an anchor if links.h refers to us s2 = "%s" % s s = "%s" % s if not samefile(link, name): s = '%s' % (root, link, s2) s = ' ' + s + '' list.append(s) list = [""] + list[:4] + ["", ""] + list[4:] + [""] return string.join(list, "\n ") def pick_cornerbanner(): # XXX Should really do a list of the pics directory... NBANNERS = 6 i = whrandom.randint(0, NBANNERS-1) s = "mswe613_%01d.gif" % i print "banner:", s return s def fix_otherlinks(name, otherlinks): """Apply various bits of magic to the otherlinks specs.""" # Assume the base text consists of a bunch of

  • items, # with

    ...

    items in between. # Change each of these into a table cell. s = otherlinks p = re.compile('

    (.*?)

    ', re.I | re.S) x = ' \n' s = p.sub(x + '' r'\1' '', s) n = len(x) if s[:n] == x: s = s[n:] p = re.compile('
  • ', re.I) s = p.sub('', s) head, name = os.path.split(name) name = name + ".html" p = re.compile('([^<>]*)', re.S | re.I) res = [] i = 0 m = p.search(s) while m: j = m.start() href, text = m.group(1, 2) if href == name or (href in ("", "./") and name == "index.html"): all = "%s" % text else: all = '%s' % (href, text) # see if the corresponding .ht file exists and if it has a pagecolor # attribute. if so use the lightcolor aspect of that pagecolor if href in ("", "./"): htfile = "index.ht" else: htfile = href[:-2] try: f = open(htfile, 'r') except IOError: res.append(s[i:j]) # Table row specifier else: msg = rfc822.Message(f) pc = msg.getheader('pagecolor') if pc: ds, ms, ls = getpagecolor(pc) colorow = '' % ls res.append(colorow) # Table row specifier with color else: res.append(s[i:j]) # Table row specifier f.close() res.append(all) # Anchor specifier i = m.end() m = p.search(s, i) res.append(s[i:]) if filter(None, res): res.append('\n ') return string.join(res, "") def load_other_links(file, names=None): head, tail = os.path.split(file) if names: files = [] for name in string.split(names): files.append(os.path.join(head, name)) else: file = os.path.join(head, "links.h") if os.path.exists(file): files = [file] else: files = [] texts = [] for file in files: f = open(file) text = f.read() f.close() texts.append(text) return string.join(texts, "\n") def samedir(a, b): aa = splitit(a) bb = splitit(b) return aa[:-1] == bb[:-1] def samefile(a, b): if a == b: return 1 aa = splitit(a) bb = splitit(b) if aa[:-1] != bb[:-1]: return 0 a = aa[-1] or "index.html" b = bb[-1] or "index.html" return a == b def splitit(a): aa = string.split(a, '/') while '.' in aa: aa.remove('.') return aa def below(path, dir): "Return all of path below last match of dir, and path to get up there." try: start = string.rindex(path, dir) except ValueError: raise RuntimeError, ("Can only process files in web hierarchy" " below %s dir" % `dir`) if start == -1: return path else: if start + len(dir) == len(path): return ".", "." else: reldir = path[start + len(dir) + 1:] updir = len(string.split(reldir, '/')) * "../" return reldir, updir if __name__ == '__main__': try: main() except KeyboardInterrupt: print "[Interrupted]" sys.exit(1)