]> git.lyx.org Git - lyx.git/blob - lib/doc/Doc_toc.pl
properly install Customization.lyx (bug 1628)
[lyx.git] / lib / doc / Doc_toc.pl
1 #!/usr/bin/perl -w
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")
4 #
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.)
9
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 
14 # docs.
15  
16 use strict;
17
18 my $Usage = <<ENDUSAGE;
19     $0 Toc_Top_File Doc [Doc ...]
20
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
24
25 ENDUSAGE
26
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;
30
31 # Get document header from language-specific TOC_top
32 open(HEAD, "<$Toc_Top_File") or die $!;
33 while (<HEAD>) {
34     last if /\\the_end/; # don't print last line!
35     print;
36 }
37 close HEAD;
38
39 # loop through files; print out headers
40 my @matches;
41 my $level;
42 my $match = "";
43 my $sub_match;
44 my $ignore = 0; # ignore lines (e.g. footnote in a heading)
45 my @sec_counter;
46
47 while (<>) {
48     # first few lines of the file
49     unless (@matches) {
50         if (/^\\textclass (\w+)/) {
51             # Hopefully it's book, report, or article
52             my $class = $1;
53             @matches = @LyX_classes;
54             # Article doesn't have Chapters
55             if ($class eq "article") {
56                 shift @matches;
57             }
58             $match = $matches[0];
59             $sub_match = $matches[1];
60         }
61
62         next;
63     }
64
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)/) { 
70         $ignore++;
71     } 
72     elsif ($ignore && /^\\begin_inset/ ) {
73         $ignore++; 
74     }
75     # Unset ignoring. But note that end_inset could be the end of another
76     # kind of inset!
77     if ($ignore && /^\\end_(float|inset)/) {
78         $ignore--;
79         next; # don't print out \end_float line
80     }
81     next if $ignore;
82
83     # Now actually handle title & section headings
84     if (/^\\layout\s+(\w+)/) {
85         my $layout = $1;
86         my $found = 0; # did we find the start of a heading?
87     
88         if ($layout eq "Title") {
89             $found = 1;
90             @sec_counter = scalar(@matches) x (0); # (re)start section counters
91             print "\\layout Section*\n";
92
93         } else {
94             my $level;
95             foreach $level (0 .. $#matches) {
96                 if ($layout eq $matches[$level]) {
97
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";
102                     }
103
104                     # A new section ends any sub- or subsubsections
105                     # below it, etc.
106                     # (Make sure to do this before calling &section_number!
107                     my $sublevel;
108                     foreach $sublevel ($level+1 .. $#sec_counter) {
109                         if ($sec_counter[$sublevel]) {
110                             print "\\end_deeper\n";
111                             $sec_counter[$sublevel] = 0;
112                         }
113                     }
114
115                     $found = 1;
116                     $sec_counter[$level]++;
117                     my $sec = &section_number (@sec_counter);
118                     print "\\layout Description\n$sec ";
119                     last; # don't need to try any more matches
120                 }
121             }
122         }
123
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.
127         $printing = $found;
128
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!
132     } else {
133         print if $printing;
134     }
135
136     # Cleanup at the end of each file
137     if (eof) {
138         # Finish nesting subsections
139         # I.e., if we had any subsections in this section, end subsectioning
140         my $level;
141         foreach $level (1 .. $#sec_counter) {
142             if ($sec_counter[$level]) {
143                 print "\\end_deeper\n";
144             }
145         }
146         # So that on next file we check whether it's an article or book
147         @matches = ();
148     }
149
150 }
151
152 print "\n\\the_end\n";
153
154 # Make a (nested) section number
155 # Input is current section numbers
156 sub section_number {
157     my $number = shift; # Highest level section counter
158     my $index;
159     foreach $index (@_) {
160         if ($index) {
161             $number .= ".$index";
162         } else {
163             # Done creating the number
164             last;
165         }
166     }
167     return $number;
168 }