]> git.lyx.org Git - lyx.git/blob - lib/reLyX/Verbatim.pm
clean up french language handling
[lyx.git] / lib / reLyX / Verbatim.pm
1 #######################  VERBATIM COPYING SUBROUTINES  ########################
2 # This file is part of reLyX.
3 # Copyright (c) 1998-9 Amir Karger karger@post.harvard.edu
4 # You are free to use and modify this code under the terms of
5 # the GNU General Public Licence version 2 or later.
6 #
7 # Subs for copying stuff verbatim from a TeX file instead of parsing it.
8 # These subs use the rather low-level TT:OpenFile::paragraph method, because
9 # the higher level methods assume you've parsed, and verbatim stuff might be
10 # parsed normally.
11
12 package Verbatim;
13 use strict;
14
15 my $debug_on; # package-wide variable set if -d option is given
16
17 sub copy_verb {
18 # This subroutine handles a \verb token. Text is guaranteed to be on one line.
19 # \verb must be followed by a non-letter, then copy anything until the next
20 # occurrence of that character.
21     my ($fileobject, $token) = @_;
22     my $verb = $token->exact_print; # "\verb" or "\verb*"
23     my $textref = $fileobject->paragraph;
24     # eat e.g., !text $\% text!
25     if ($$textref =~ s/^([^A-Za-z*]).*?\1//) {
26         $verb .= $&;
27     } else { warn "unable to parse \\verb"; $verb .="||" }
28     return $verb;
29 }
30
31 sub copy_verbatim {
32     # Was -d option given?
33     $debug_on = (defined($main::opt_d) && $main::opt_d);
34
35 # This subroutine eats text verbatim until a certain text is reached
36 # The end text itself is not eaten; this is necessary so that
37 #    environments are properly nested (otherwise, TeX.pm complains)
38 # It returns a string containing the text
39 #
40 # Arg 0 is the Text::TeX::OpenFile file object, arg 1 is the beginning token
41     my $fileobject = shift;
42     my $begin_token = shift;
43     my %endtokentbl = (  '\(' => '\)',
44                          '\[' => '\]',
45                          '$'  => '$',
46                          '$$' => '$$' );
47
48     my $type = ref($begin_token);
49     $type =~ s/^Text::TeX:://o or die "unknown token type $type?!";
50
51 # Figure out beginning & end text of this token or environment
52 # Beginning text so we know if you have an environment nested within itself
53 # End text so we know when to finish copying OR when to 'pop' a level
54 #    if an environment is nested within itself
55 # Because the searches will generally be matching expressions with backslashes
56 #    and other meta-characters, we put \Q\E around (pieces of) the expressions
57     my ($begin_text, $end_text);
58     if ($type =~ /^Token$/) {  # \( or \[
59         $begin_text = $begin_token->print; # e.g., '\('
60         die "unknown begin_text" unless exists $endtokentbl{$begin_text};
61         $end_text = "\Q$endtokentbl{$begin_text}\E";
62         # actually, begin_text shouldn't be nec. since you can't nest math
63         $begin_text = "\Q$begin_text\E"; # quote slashes, etc.
64
65     } elsif (/^Begin::Group::Args$/) {    # \begin{foo}
66         # \s* to allow, e.g., '\begin {foo}'
67         $begin_text = $begin_token->print;
68         $begin_text = "\Q$begin_text\E";
69         $begin_text =~ s/begin/begin\\s*/;
70         ($end_text = $begin_text) =~ s/begin/end/;
71
72     } else {
73         die "copy_verbatim called with unknown token type $type!";
74     }
75     #print "\nsub copy_verbatim going to copy until $end_text\n" if $debug_on;
76
77 # Actual copying
78     my $textref; # reference to stuff we read in to print
79     my $to_print = ""; #text to print
80     # we're automatically "nested" once since we had the original \begin
81     my $nest_count = 1;
82
83     # (Eat and) Print out paragraphs until you find $end_text
84     # paragraph returns "" if it's time to get a new paragraph -- if that
85     # happens, we want to continue, but we can't dereference $textref
86     #    Call paragraph with an argument so that it gets a new paragraph if
87     # it gets to the end of a paragraph
88     #    Allow nesting of this environment!
89     while (defined ($textref = $fileobject->paragraph(1))) {
90         next unless $textref; # new paragraph; keep going
91
92         # If we match begin or end text, eat everything up to it
93         # Make sure to handle (nested) begin & end texts in order, so we can
94         #    differentiate \begin \begin \end \end from \begin \end \begin \end
95         if ($$textref =~ /$end_text/ && $` !~ /$begin_text/) {
96             # Note that $` will be from the last *successful* match,
97             #    namely the end_text match
98             --$nest_count;
99             $to_print .= $`; # print until the \end command
100             if ($nest_count) {
101                 $to_print .= $&; # print the end text too
102                 $$textref = $'; # leave the rest in the paragraph
103             } else {
104                 # Leave end text (and anything after it) for TeX.pm
105                 $$textref = $& . $';
106                 last; # done copying since there's no more nesting
107             }
108
109         # If we match beginning text, we have a nested environment
110         } elsif ($$textref =~ /$begin_text/ && $` !~ /$end_text/) {
111             $to_print .= $`; # print up to and
112             $to_print .= $&; # INCLUDING the begin text
113             $$textref = $'; # leave the rest in the paragraph
114             ++$nest_count;
115
116         # If we didn't match begin OR end text, just eat the whole paragraph
117         } else {
118             $to_print .= $$textref;
119             $$textref = "";
120         } # end if $$textref
121     } #end while
122     die "eof without finding matching text $end_text" if (!defined $textref);
123
124     # return the string
125     #print "Exiting sub copy_verbatim\n" if $debug_on;
126     return $to_print;
127 } # end copy_verbatim
128
129 1; # return true to calling routine