3 """Convert a LaTeX .toc file to some PDFTeX magic to create that neat outline.
5 The output file has an extension of '.bkm' instead of '.out', since hyperref
6 already uses that extension.
16 # Ench item in an entry is a tuple of:
18 # Section #, Title String, Page #, List of Sub-entries
20 # The return value of parse_toc() is such a tuple.
23 \\contentsline\ \{([a-z]*)} # type of section in $1
24 \{(?:\\numberline\ \{([0-9.A-Z]+)})? # section number
26 \{(\d+)}$""" # page number
28 cline_rx = re.compile(cline_re, re.VERBOSE)
33 ('chapter', 'section'): OUTER_TO_INNER,
34 ('section', 'subsection'): OUTER_TO_INNER,
35 ('subsection', 'subsubsection'): OUTER_TO_INNER,
36 ('subsubsection', 'subsection'): 1,
37 ('subsection', 'section'): 1,
38 ('section', 'chapter'): 1,
39 ('subsection', 'chapter'): 2,
40 ('subsubsection', 'section'): 2,
41 ('subsubsection', 'chapter'): 3,
44 INCLUDED_LEVELS = ("chapter", "section", "subsection", "subsubsection")
47 def parse_toc(fp, bigpart=None):
50 level = bigpart or 'chapter'
57 m = cline_rx.match(line)
59 stype, snum, title, pageno = m.group(1, 2, 3, 4)
60 title = clean_title(title)
61 entry = (stype, snum, title, string.atoi(pageno), [])
65 if stype not in INCLUDED_LEVELS:
66 # we don't want paragraphs & subparagraphs
68 direction = _transition_map[(level, stype)]
69 if direction == OUTER_TO_INNER:
74 for i in range(direction):
80 sys.stderr.write("l.%s: " + line)
84 hackscore_rx = re.compile(r"\\hackscore\s*{[^}]*}")
85 raisebox_rx = re.compile(r"\\raisebox\s*{[^}]*}")
86 title_rx = re.compile(r"\\([a-zA-Z])+\s+")
87 title_trans = string.maketrans("", "")
89 def clean_title(title):
90 title = raisebox_rx.sub("", title)
91 title = hackscore_rx.sub(r"\\_", title)
94 m = title_rx.search(title, pos)
97 if title[start:start+15] != "\\textunderscore":
98 title = title[:start] + title[m.end():]
102 title = string.translate(title, title_trans, "{}")
106 def write_toc(toc, fp):
108 write_toc_entry(entry, fp, 0)
110 def write_toc_entry(entry, fp, layer):
111 stype, snum, title, pageno, toc = entry
112 s = "\\pdfoutline goto name{page%03d}" % pageno
114 s = "%s count -%d" % (s, len(toc))
116 title = "%s %s" % (snum, title)
117 s = "%s {%s}\n" % (s, title)
120 write_toc_entry(entry, fp, layer + 1)
123 def process(ifn, ofn, bigpart=None):
124 toc = parse_toc(open(ifn), bigpart)
125 write_toc(toc, open(ofn, "w"))
130 opts, args = getopt.getopt(sys.argv[1:], "c:")
136 for filename in args:
137 base, ext = os.path.splitext(filename)
139 process(base + ext, base + ".bkm", bigpart)
142 if __name__ == "__main__":