mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-23 02:14:50 +00:00
46ee486bda
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@9138 a592a061-630c-0410-9148-cb99ea01b6c8
130 lines
5.0 KiB
Perl
130 lines
5.0 KiB
Perl
####################### VERBATIM COPYING SUBROUTINES ########################
|
|
# This file is part of reLyX.
|
|
# Copyright (c) 1998-9 Amir Karger karger@post.harvard.edu
|
|
# You are free to use and modify this code under the terms of
|
|
# the GNU General Public Licence version 2 or later.
|
|
#
|
|
# Subs for copying stuff verbatim from a TeX file instead of parsing it.
|
|
# These subs use the rather low-level TT:OpenFile::paragraph method, because
|
|
# the higher level methods assume you've parsed, and verbatim stuff might be
|
|
# parsed normally.
|
|
|
|
package Verbatim;
|
|
use strict;
|
|
|
|
my $debug_on; # package-wide variable set if -d option is given
|
|
|
|
sub copy_verb {
|
|
# This subroutine handles a \verb token. Text is guaranteed to be on one line.
|
|
# \verb must be followed by a non-letter, then copy anything until the next
|
|
# occurrence of that character.
|
|
my ($fileobject, $token) = @_;
|
|
my $verb = $token->exact_print; # "\verb" or "\verb*"
|
|
my $textref = $fileobject->paragraph;
|
|
# eat e.g., !text $\% text!
|
|
if ($$textref =~ s/^([^A-Za-z*]).*?\1//) {
|
|
$verb .= $&;
|
|
} else { warn "unable to parse \\verb"; $verb .="||" }
|
|
return $verb;
|
|
}
|
|
|
|
sub copy_verbatim {
|
|
# Was -d option given?
|
|
$debug_on = (defined($main::opt_d) && $main::opt_d);
|
|
|
|
# This subroutine eats text verbatim until a certain text is reached
|
|
# The end text itself is not eaten; this is necessary so that
|
|
# environments are properly nested (otherwise, TeX.pm complains)
|
|
# It returns a string containing the text
|
|
#
|
|
# Arg 0 is the Text::TeX::OpenFile file object, arg 1 is the beginning token
|
|
my $fileobject = shift;
|
|
my $begin_token = shift;
|
|
my %endtokentbl = ( '\(' => '\)',
|
|
'\[' => '\]',
|
|
'$' => '$',
|
|
'$$' => '$$' );
|
|
|
|
my $type = ref($begin_token);
|
|
$type =~ s/^Text::TeX:://o or die "unknown token type $type?!";
|
|
|
|
# Figure out beginning & end text of this token or environment
|
|
# Beginning text so we know if you have an environment nested within itself
|
|
# End text so we know when to finish copying OR when to 'pop' a level
|
|
# if an environment is nested within itself
|
|
# Because the searches will generally be matching expressions with backslashes
|
|
# and other meta-characters, we put \Q\E around (pieces of) the expressions
|
|
my ($begin_text, $end_text);
|
|
if ($type =~ /^Token$/) { # \( or \[
|
|
$begin_text = $begin_token->print; # e.g., '\('
|
|
die "unknown begin_text" unless exists $endtokentbl{$begin_text};
|
|
$end_text = "\Q$endtokentbl{$begin_text}\E";
|
|
# actually, begin_text shouldn't be nec. since you can't nest math
|
|
$begin_text = "\Q$begin_text\E"; # quote slashes, etc.
|
|
|
|
} elsif (/^Begin::Group::Args$/) { # \begin{foo}
|
|
# \s* to allow, e.g., '\begin {foo}'
|
|
$begin_text = $begin_token->print;
|
|
$begin_text = "\Q$begin_text\E";
|
|
$begin_text =~ s/begin/begin\\s*/;
|
|
($end_text = $begin_text) =~ s/begin/end/;
|
|
|
|
} else {
|
|
die "copy_verbatim called with unknown token type $type!";
|
|
}
|
|
#print "\nsub copy_verbatim going to copy until $end_text\n" if $debug_on;
|
|
|
|
# Actual copying
|
|
my $textref; # reference to stuff we read in to print
|
|
my $to_print = ""; #text to print
|
|
# we're automatically "nested" once since we had the original \begin
|
|
my $nest_count = 1;
|
|
|
|
# (Eat and) Print out paragraphs until you find $end_text
|
|
# paragraph returns "" if it's time to get a new paragraph -- if that
|
|
# happens, we want to continue, but we can't dereference $textref
|
|
# Call paragraph with an argument so that it gets a new paragraph if
|
|
# it gets to the end of a paragraph
|
|
# Allow nesting of this environment!
|
|
while (defined ($textref = $fileobject->paragraph(1))) {
|
|
next unless $textref; # new paragraph; keep going
|
|
|
|
# If we match begin or end text, eat everything up to it
|
|
# Make sure to handle (nested) begin & end texts in order, so we can
|
|
# differentiate \begin \begin \end \end from \begin \end \begin \end
|
|
if ($$textref =~ /$end_text/ && $` !~ /$begin_text/) {
|
|
# Note that $` will be from the last *successful* match,
|
|
# namely the end_text match
|
|
--$nest_count;
|
|
$to_print .= $`; # print until the \end command
|
|
if ($nest_count) {
|
|
$to_print .= $&; # print the end text too
|
|
$$textref = $'; # leave the rest in the paragraph
|
|
} else {
|
|
# Leave end text (and anything after it) for TeX.pm
|
|
$$textref = $& . $';
|
|
last; # done copying since there's no more nesting
|
|
}
|
|
|
|
# If we match beginning text, we have a nested environment
|
|
} elsif ($$textref =~ /$begin_text/ && $` !~ /$end_text/) {
|
|
$to_print .= $`; # print up to and
|
|
$to_print .= $&; # INCLUDING the begin text
|
|
$$textref = $'; # leave the rest in the paragraph
|
|
++$nest_count;
|
|
|
|
# If we didn't match begin OR end text, just eat the whole paragraph
|
|
} else {
|
|
$to_print .= $$textref;
|
|
$$textref = "";
|
|
} # end if $$textref
|
|
} #end while
|
|
die "eof without finding matching text $end_text" if (!defined $textref);
|
|
|
|
# return the string
|
|
#print "Exiting sub copy_verbatim\n" if $debug_on;
|
|
return $to_print;
|
|
} # end copy_verbatim
|
|
|
|
1; # return true to calling routine
|