]> git.sur5r.net Git - bacula/docs/blob - docs/manuals/en/concepts/fix_tex.pl
98657576d5d71a174c1ec833281717b729196ade
[bacula/docs] / docs / manuals / en / concepts / fix_tex.pl
1 #!/usr/bin/perl -w
2 # Fixes various things within tex files.
3
4 use strict;
5
6 my %args;
7
8
9 sub get_includes {
10         # Get a list of include files from the top-level tex file.
11         my (@list,$file);
12         
13         foreach my $filename (@_) {
14                 $filename or next;
15                 # Start with the top-level latex file so it gets checked too.
16                 push (@list,$filename);
17
18                 # Get a list of all the html files in the directory.
19                 open IF,"<$filename" or die "Cannot open input file $filename";
20                 while (<IF>) {
21                         chomp;
22                         push @list,"$1.tex" if (/\\include\{(.*?)\}/);
23                 }
24
25                 close IF;
26         }
27         return @list;
28 }
29
30 sub convert_files {
31         my (@files) = @_;
32         my ($linecnt,$filedata,$output,$itemcnt,$indentcnt,$cnt);
33         
34         $cnt = 0;
35         foreach my $file (@files) {
36                 # Open the file and load the whole thing into $filedata. A bit wasteful but
37                 #   easier to deal with, and we don't have a problem with speed here.
38                 $filedata = "";
39                 open IF,"<$file" or die "Cannot open input file $file";
40                 while (<IF>) {
41                         $filedata .= $_;
42                 }
43                 close IF;
44                 
45                 # We look for a line that starts with \item, and indent the two next lines (if not blank)
46                 #  by three spaces.
47                 my $linecnt = 3;
48                 $indentcnt = 0;
49                 $output = "";
50                 # Process a line at a time.
51                 foreach (split(/\n/,$filedata)) {
52                         $_ .= "\n"; # Put back the return.
53                         # If this line is less than the third line past the \item command,
54                         #  and the line isn't blank and doesn't start with whitespace
55                         #  add three spaces to the start of the line. Keep track of the number
56                         #  of lines changed.
57                         if ($linecnt < 3 and !/^\\item/) {
58                                 if (/^[^\n\s]/) {
59                                         $output .= "   " . $_;
60                                         $indentcnt++;
61                                 } else {
62                                         $output .= $_;
63                                 }
64                                 $linecnt++;
65                         } else {
66                                 $linecnt = 3;
67                                 $output .= $_;
68                         }
69                         /^\\item / and $linecnt = 1;
70                 }
71
72                 
73                 # This is an item line.  We need to process it too. If inside a \begin{description} environment, convert 
74                 #  \item {\bf xxx} to \item [xxx] or \item [{xxx}] (if xxx contains '[' or ']'.
75                 $itemcnt = 0;
76                 $filedata = $output;
77                 $output = "";
78                 my ($before,$descrip,$this,$between);
79
80                 # Find any \begin{description} environment
81                 while ($filedata =~ /(\\begin[\s\n]*\{[\s\n]*description[\s\n]*\})(.*?)(\\end[\s\n]*\{[\s\n]*description[\s\n]*\})/s) {
82                         $output .= $` . $1;
83                         $filedata = $3 . $';
84                         $descrip = $2;
85
86                         # Search for \item {\bf xxx}
87                         while ($descrip =~ /\\item[\s\n]*\{[\s\n]*\\bf[\s\n]*/s) {
88                                 $descrip = $';
89                                 $output .= $`;
90                                 ($between,$descrip) = find_matching_brace($descrip);
91                                 if (!$descrip) {
92                                         $linecnt = $output =~ tr/\n/\n/;
93                                         print STDERR "Missing matching curly brace at line $linecnt in $file\n" if (!$descrip);
94                                 }
95
96                                 # Now do the replacement.
97                                 $between = '{' . $between . '}' if ($between =~ /\[|\]/);
98                                 $output .= "\\item \[$between\]";       
99                                 $itemcnt++;
100                         }
101                         $output .= $descrip;
102                 }
103                 $output .= $filedata;
104         
105                 # If any hyphens or \item commnads were converted, save the file.
106                 if ($indentcnt or $itemcnt) {
107                         open OF,">$file" or die "Cannot open output file $file";
108                         print OF $output;
109                         close OF;
110                         print "$indentcnt indent", ($indentcnt == 1) ? "" : "s"," added in $file\n";
111                         print "$itemcnt item", ($itemcnt == 1) ? "" : "s"," Changed in $file\n";
112                 }
113
114                 $cnt += $indentcnt + $itemcnt;
115         }
116         return $cnt;
117 }
118
119 sub find_matching_brace {
120         # Finds text up to the next matching brace.  Assumes that the input text doesn't contain
121         #  the opening brace, but we want to find text up to a matching closing one.
122         # Returns the text between the matching braces, followed by the rest of the text following
123         #   (which does not include the matching brace).
124         # 
125         my $str = shift;
126         my ($this,$temp);
127         my $cnt = 1;
128
129         while ($cnt) {
130                 # Ignore verbatim constructs involving curly braces, or if the character preceding
131                 #  the curly brace is a backslash.
132                 if ($str =~ /\\verb\*?\{.*?\{|\\verb\*?\}.*?\}|\{|\}/s) {
133                         $this .= $`;
134                         $str = $';
135                         $temp = $&;
136
137                         if ((substr($this,-1,1) eq '\\') or 
138                                 $temp =~ /^\\verb/) {
139                                         $this .= $temp;
140                                         next;
141                         }
142                                 
143                         $cnt +=  ($temp eq '{') ? 1 : -1;
144                         # If this isn't the matching curly brace ($cnt > 0), include the brace.
145                         $this .= $temp if ($cnt);
146                 } else {
147                         # No matching curly brace found.
148                         return ($this . $str,'');
149                 }
150         }
151         return ($this,$str);
152 }
153
154 sub check_arguments {
155         # Checks command-line arguments for ones starting with --  puts them into
156         #   a hash called %args and removes them from @ARGV.
157         my $args = shift;
158         my $i;
159
160         for ($i = 0; $i < $#ARGV; $i++) {
161                 $ARGV[$i] =~ /^\-+/ or next;
162                 $ARGV[$i] =~ s/^\-+//;
163                 $args{$ARGV[$i]} = "";
164                 delete ($ARGV[$i]);
165                 
166         }
167 }
168
169 ##################################################################
170 #                       MAIN                                  ####
171 ##################################################################
172
173 my @includes;
174 my $cnt;
175
176 check_arguments(\%args);
177 die "No Files given to Check\n" if ($#ARGV < 0);
178
179 # Examine the file pointed to by the first argument to get a list of 
180 #  includes to test.
181 @includes = get_includes(@ARGV);
182
183 $cnt = convert_files(@includes);
184 print "No lines changed\n" unless $cnt;