13 @EXPORT = qw(initLyxStack checkLyxLine closeLyxStack diestack);
16 my @stack = (); # list of HASH-Arrays
18 my $useNonTexFont = "true";
21 # type (layout, inset, header, preamble, ...)
23 # matching list of matching spes
24 # search: regular expression
25 # ext: list of extensions needed for the full path of the file spec
26 # filetype: one of prefix_only,replace_only,copy_only,prefix_for_list,interpret
27 # fileidx: index into the resulting array, defining the filename
28 # result: conatenation of the elements should reflect the parsed line
29 # but first set the modified value into $result->[$fileidx]
30 # numerical value will be replaced with appropriate matching group value
35 if ($_[1] eq "systemF") {
36 $useNonTexFont = "true";
39 $useNonTexFont = "false";
41 $stack[0] = { type => "Starting"};
48 print "Called stack\n";
50 for my $depth ( 0 .. 100) {
51 #my ($pkg, $file, $line, $subname, $hasargs, $wantarray) = caller($depth)
52 my @stack = caller($depth);
53 last if ($stack[0] ne "main");
54 push(@call_stack, \@stack);
56 for my $depth ( 0 .. 100) {
57 last if (! defined($call_stack[$depth]));
58 my $subname = $call_stack[$depth]->[3];
59 my $line = $call_stack[$depth]->[2];
60 print "($depth) $subname()";
62 my $oldline = $call_stack[$depth-1]->[2];
65 print " called from ";
66 if (defined($call_stack[$depth+1])) {
67 my $parent = $call_stack[$depth+1]->[3];
68 print "$parent():$line\n";
71 my $file = $call_stack[$depth]->[1];
72 print "\"$file\":$line\n";
80 &diestack("Stack not OK") if ($stack[0]->{type} ne "Starting");
87 $stack[0]->{"matching"} = $match;
92 return($stack[0]->{"matching"});
95 ###########################################################
97 sub checkForEndBlock($)
101 for my $et ( qw( layout inset preamble header)) {
102 if ($l =~ /^\\end_$et$/) {
103 &diestack("Not in $et") if ($stack[0]->{type} ne "$et");
116 if (! defined($elem{"ext"})) {
119 if (! defined($elem{"filetype"})) {
120 $elem{"filetype"} = "prefix_only";
122 if (! defined($elem{"fileidx"})) {
123 $elem{"fileidx"} = 1;
125 &diestack("No result defined") if (! defined($elem{"result"}));
133 return($m->{"search"});
140 return($m->{"filetype"});
147 return($m->{"fileidx"});
161 return($m->{"result"});
164 sub checkForHeader($)
168 if ($l =~ /^\\begin_header\s*$/) {
170 $selem{type} = "header";
172 unshift(@stack, \%selem);
174 $rElems[0] = &newMatch("search" => '^\\\\master\s+(.*\.lyx)',
175 "filetype" => "prefix_only",
176 "result" => ["\\master ", ""]);
177 if (keys %{$rFont}) {
178 for my $ff ( keys %{$rFont}) {
179 my $elem = &newMatch("search" => '^\\\\font_' . $ff . '\s+',
180 "filetype" => "replace_only",
181 "result" => ["\\font_$ff ", $rFont->{$ff}]);
182 push(@rElems, $elem);
185 my $elemntf = &newMatch("search" => '^\\\\use_non_tex_fonts\s+(false|true)',
186 "filetype" => "replace_only",
187 "result" => ["\\use_non_tex_fonts $useNonTexFont"]);
188 push(@rElems, $elemntf);
189 &setMatching(\@rElems);
195 sub checkForPreamble($)
199 if ($l =~ /^\\begin_preamble\s*$/) {
201 $selem{type} = "preamble";
203 unshift(@stack, \%selem);
204 my $rElem = &newMatch("ext" => [".eps", ".png"],
205 "search" => '^\\\\(photo|ecvpicture)(.*\{)(.*)\}',
207 "result" => ["\\", "1", "2", "3", "}"]);
208 &setMatching([$rElem]);
214 sub checkForLayoutStart($)
218 if ($l =~ /^\\begin_layout\s+(.+)$/) {
219 #print "started layout\n";
221 $selem{type} = "layout";
223 unshift(@stack, \%selem);
224 if ($selem{name} =~ /^(Picture|Photo)$/ ) {
225 my $rElem = &newMatch("ext" => [".eps", ".png"],
227 "result" => ["", "", ""]);
228 &setMatching([$rElem]);
235 sub checkForInsetStart($)
239 if ($l =~ /^\\begin_inset\s+(.*)$/) {
240 #print "started inset\n";
242 $selem{type} = "inset";
244 unshift(@stack, \%selem);
245 if ($selem{name} =~ /^(Graphics|External)$/) {
246 my $rElem = &newMatch("search" => '^\s+filename\s+(.+)$',
247 "filetype" => "copy_only",
248 "result" => ["\tfilename ", "", ""]);
249 &setMatching([$rElem]);
256 sub checkForLatexCommand($)
260 if ($stack[0]->{type} eq "inset") {
261 if ($l =~ /^LatexCommand\s+([^\s]+)\s*$/) {
263 if ($stack[0]->{name} =~ /^CommandInset\s+bibtex$/) {
264 if ($param eq "bibtex") {
265 my $rElem1 = &newMatch("ext" => ".bib",
266 "filetype" => "prefix_for_list",
267 "search" => '^bibfiles\s+\"(.+)\"',
268 "result" => ["bibfiles \"", "1", "\""]);
269 my $rElem2 = &newMatch("ext" => ".bst",
270 "filetype" => "prefix_for_list",
271 "search" => '^options\s+\"(.+)\"',
272 "result" => ["options \"", "1", "\""]);
273 &setMatching([$rElem1, $rElem2]);
276 elsif ($stack[0]->{name} =~ /^CommandInset\s+include$/) {
277 if ($param =~ /^(verbatiminput\*?|lstinputlisting)$/) {
278 my $rElem = &newMatch("search" => '^filename\s+\"(.+)\"',
279 "filetype" => "copy_only",
280 "result" => ["filename \"", "", "\""]);
281 &setMatching([$rElem]);
283 elsif ($param =~ /^(include|input)$/) {
284 my $rElem = &newMatch("search" => '^filename\s+\"(.+)\"',
285 "filetype" => "interpret",
286 "result" => ["filename \"", "", "\""]);
287 &setMatching([$rElem]);
296 # parse the given line
297 # returns a hash with folloving values
298 # found: 1 if line matched some regex
299 # fileidx: index into result
300 # ext: list of possible extensions to use for a valid file
301 # filelist: list of found file-pathes (may be more then one, e.g. in bibfiles spec)
302 # separator: to be used while concatenating the filenames
303 # filetype: prefix_only,replace_only,copy_only,interpret
304 # same as before, but without 'prefix_for_list'
309 return({"found" => 0}) if (&checkForHeader($l));
310 return({"found" => 0}) if (&checkForPreamble($l));
311 return({"found" => 0}) if (&checkForEndBlock($l));
312 return({"found" => 0}) if (&checkForLayoutStart($l));
313 return({"found" => 0}) if (&checkForInsetStart($l));
314 return({"found" => 0}) if (&checkForLatexCommand($l));
315 if (defined($stack[0])) {
316 my $rMatch = &getMatching();
317 for my $m ( @{$rMatch}) {
318 my $search = &getSearch($m);
319 if ($l =~ /$search/) {
320 my @matches = ($1, $2, $3, $4);
321 my $filetype = &getFileType($m);
322 my @result2 = @{&getResult($m)};
324 for my $r (@result2) {
329 if ($filetype eq "replace_only") {
331 my %result = ("found" => 1,
332 "filetype" => $filetype,
333 "result" => \@result2);
337 my $fileidx = &getFileIdx($m);
338 my $filename = $matches[$fileidx-1];
339 if ($filename !~ /^\.*$/) {
340 my %result = ("found" => 1,
341 "fileidx" => $fileidx,
342 "ext" => &getExt($m),
343 "result" => \@result2);
344 if ($filetype eq "prefix_for_list") {
345 # bibfiles|options in CommandInset bibtex
346 my @filenames = split(',', $filename);
347 $result{"separator"} = ",";
348 $result{"filelist"} = \@filenames;
349 $result{"filetype"} = "prefix_only";
352 $result{"separator"} = "";
353 $result{"filelist"} = [$filename];
354 $result{"filetype"} = $filetype;
362 return({"found" => 0});