2 # Note! If your perl isn't in /usr/bin/perl, change the line above.
3 # (Or say "perl Doc_toc.pl" instead of just "Doc_toc.pl")
5 # This script creates a "master table of contents" for a set of LyX docs.
6 # It does so by going through the files and printing out all of the
7 # chapter, section, and sub(sub)section headings out. (It numbers the
8 # sections sequentially; hopefully noone's using Section* in the docs.)
10 # ./Doc_toc.pl TOC_top/TOC_top.lyx Intro.lyx FAQ.lyx Tutorial.lyx UserGuide.lyx Extended.lyx Customization.lyx >TOC.lyx
11 # The script tries hard to ignore Footnotes, Notes; ERT and labels in section
12 # headings. There is even some code to handle nested insets, but no doubt it
13 # can break on some files. The emphasis has been put on working with current
18 my $Usage = <<ENDUSAGE;
19 $0 Toc_Top_File Doc [Doc ...]
21 * Docs are LyX docs to be TOC-ified
22 * All information up to and including the TOC doc title is in a
23 language-specific file Toc_Top_File
27 my $printing = 0; # are we currently supposed to be copying input to STDOUT?
28 my @LyX_classes = qw (Chapter Section Subsection Subsubsection);
29 my $Toc_Top_File = shift;
31 # Get document header from language-specific TOC_top
32 open(HEAD, "<$Toc_Top_File") or die $!;
34 last if /\\the_end/; # don't print last line!
39 # loop through files; print out headers
44 my $ignore = 0; # ignore lines (e.g. footnote in a heading)
48 # first few lines of the file
50 if (/^\\textclass (\w+)/) {
51 # Hopefully it's book, report, or article
53 @matches = @LyX_classes;
54 # Article doesn't have Chapters
55 if ($class eq "article") {
59 $sub_match = $matches[1];
65 # Footnotes in a section heading could confuse things!
66 # And don't bother printing out section labels.
67 if (/^\\begin_float footnote/
68 || /^\\begin_inset OptArg/
69 || /^\\begin_inset (Foot|Note|ERT|LatexCommand \\label)/) {
72 elsif ($ignore && /^\\begin_inset/ ) {
75 # Unset ignoring. But note that end_inset could be the end of another
77 if ($ignore && /^\\end_(float|inset)/) {
79 next; # don't print out \end_float line
83 # Now actually handle title & section headings
84 if (/^\\layout\s+(\w+)/) {
86 my $found = 0; # did we find the start of a heading?
88 if ($layout eq "Title") {
90 @sec_counter = scalar(@matches) x (0); # (re)start section counters
91 print "\\layout Section*\n";
95 foreach $level (0 .. $#matches) {
96 if ($layout eq $matches[$level]) {
98 # If this is the first subsection of this level,
99 # start nesting. Top level (level 0) needs no nesting
100 if ($level && !$sec_counter[$level]) {
101 print "\\begin_deeper\n";
104 # A new section ends any sub- or subsubsections
106 # (Make sure to do this before calling §ion_number!
108 foreach $sublevel ($level+1 .. $#sec_counter) {
109 if ($sec_counter[$sublevel]) {
110 print "\\end_deeper\n";
111 $sec_counter[$sublevel] = 0;
116 $sec_counter[$level]++;
117 my $sec = §ion_number (@sec_counter);
118 print "\\layout Description\n$sec ";
119 last; # don't need to try any more matches
124 # If we found "Title" or one of the section layouts, then we're
125 # in a section header. Otherwise, this \layout command ENDS any section
126 # we might have been in before.
129 # Rare case of a section header w/ no text after it at the end of a file
130 } elsif (/^\\the_end/) {
131 $printing = 0; # obviously we're not in the section header any more!
136 # Cleanup at the end of each file
138 # Finish nesting subsections
139 # I.e., if we had any subsections in this section, end subsectioning
141 foreach $level (1 .. $#sec_counter) {
142 if ($sec_counter[$level]) {
143 print "\\end_deeper\n";
146 # So that on next file we check whether it's an article or book
152 print "\n\\the_end\n";
154 # Make a (nested) section number
155 # Input is current section numbers
157 my $number = shift; # Highest level section counter
159 foreach $index (@_) {
161 $number .= ".$index";
163 # Done creating the number