#!/usr/bin/env python ############################################################################### # Takes a chapter as input and adds internal links and numbering to all # of the H1, H2, H3, H4 and H5 sections. # # Every heading HTML tag (H1, H2 etc) is given an autogenerated name to link # to. However, if the name is not an autogenerated name from a previous run, # it will be kept. If it is autogenerated, it might change on subsequent runs # of this program. Thus if you want to create links to one of the headings, # then change the heading link name to something that does not look like an # autogenerated link name. ############################################################################### import sys import re ############################################################################### # Functions ############################################################################### # Regexs for alink = re.compile(r".*", re.IGNORECASE) heading = re.compile(r"(_nn\d)", re.IGNORECASE) def getheadingname(m): autogeneratedheading = True; if m.group(1) != None: amatch = alink.match(m.group(1)) if amatch: # A non-autogenerated heading - keep it headingname = amatch.group(1) autogeneratedheading = heading.match(headingname) if autogeneratedheading: # The heading name was either non-existent or autogenerated, # We can create a new heading / change the existing heading headingname = "%s_nn%d" % (filenamebase, nameindex) return headingname # Return heading - 1.1. Introduction in the examples below: # old style example:

1.1 Introduction

# new style example:

1.1 Introduction

def getheadingtext(m, s): prevheadingtext_newstyle = m.group(2) prevheadingtext_oldstyle = m.group(3) if prevheadingtext_oldstyle is None or prevheadingtext_newstyle is None: raise RuntimeError("Ill-formed heading in line:\n%s" % s) if len(prevheadingtext_oldstyle) == 0 and len(prevheadingtext_newstyle) == 0: raise RuntimeError("No heading text in line:\n%s" % s) if len(prevheadingtext_oldstyle) > 0 and len(prevheadingtext_newstyle) > 0: raise RuntimeError("Two heading texts, only one should be specified in line:\n%s" % s) prevheadingtext = prevheadingtext_oldstyle if len(prevheadingtext_oldstyle) > 0 else prevheadingtext_newstyle return prevheadingtext ############################################################################### # Main program ############################################################################### if len(sys.argv) != 3: print("usage: makechap.py filename num") sys.exit(1) filename = sys.argv[1] filenamebase = filename.split(".")[0] num = int(sys.argv[2]) section = 0 subsection = 0 subsubsection = 0 nameindex = 0 name = "" # Regexs for

,...

sections h1 = re.compile(r".*?

(\s*[\d\.\s]*(.*?))*[\d\.\s]*(.*?)

", re.IGNORECASE) h2 = re.compile(r".*?

(\s*[\d\.\s]*(.*?))*[\d\.\s]*(.*?)

", re.IGNORECASE) h3 = re.compile(r".*?

(\s*[\d\.\s]*(.*?))*[\d\.\s]*(.*?)

", re.IGNORECASE) h4 = re.compile(r".*?

(\s*[\d\.\s]*(.*?))*[\d\.\s]*(.*?)

", re.IGNORECASE) h5 = re.compile(r".*?
(\s*[\d\.\s]*(.*?))*[\d\.\s]*(.*?)
", re.IGNORECASE) data = open(filename).read() # Read data open(filename+".bak","w").write(data) # Make backup lines = data.splitlines() result = [ ] # This is the result of postprocessing the file index = "\n
\n" # index contains the index for adding at the top of the file. Also printed to stdout. skip = 0 skipspace = 0 for s in lines: if s == "": if not skip: skip = 1 else: skip = 0 continue; if skip: continue if not s and skipspace: continue if skipspace: result.append("") result.append("") skipspace = 0 m = h1.match(s) if m: prevheadingtext = getheadingtext(m, s) nameindex += 1 headingname = getheadingname(m) result.append("""

%d %s

""" % (headingname,num,prevheadingtext)) result.append("@INDEX@") section = 0 subsection = 0 subsubsection = 0 subsubsubsection = 0 name = prevheadingtext skipspace = 1 continue m = h2.match(s) if m: prevheadingtext = getheadingtext(m, s) nameindex += 1 section += 1 headingname = getheadingname(m) result.append("""

%d.%d %s

""" % (headingname,num,section, prevheadingtext)) if subsubsubsection: index += "\n" if subsubsection: index += "\n" if subsection: index += "\n" if section == 1: index += "\n" if subsubsection: index += "\n" if subsection == 1: index += "\n" if subsubsection == 1: index += "\n" if subsection: index += "\n" if section: index += "\n" index += "
\n\n" data = "\n".join(result) data = data.replace("@INDEX@",index) + "\n"; # Write the file back out open(filename,"w").write(data) # Print the TOC data to stdout correcting the anchor links for external referencing index = index.replace("
  • %d %s\n""" % (filename,filenamebase,num,name)) print(index)