# ListLayouts may have standard paragraphs nested inside them.
my $ListLayouts = "Itemize|Enumerate|Description";
+# passed a string and an array
+# returns true if the string is an element of the array.
+sub foundIn {
+ my $name = shift;
+ return grep {$_ eq $name} @_;
+}
+
+my @NatbibCommands = map {"\\$_"} qw(citet citealt citep citealp citeauthor);
+
+# passed a string.
+# returns true if it is a valid natbib citation
+sub isNatbibCitation {
+ my $name = shift;
+
+ # These two have a single form
+ return 1 if ($name eq '\citeyear' or $name eq '\citeyearpar');
+
+ # Natbib citations can start with a 'C' or a 'c'
+ $name =~ s/^\\C/\\c/;
+ # The can end with a '*'
+ $name =~ s/\*$//;
+ # Is this doctored string found in the list of valid commands?
+ return foundIn($name, @NatbibCommands);
+
+}
+
##################### PARSER INVOCATION ##################################
sub call_parser {
# This subroutine calls the TeX parser & translator
# Type=>report_args and count=>1
# Note that we don't have to bother putting in tokens which will be simply
# translated (e.g., from %TextTokenTransTable).
- my %MyTokens = (
+ my %MyTokens = (
'{' => $Text::TeX::Tokens{'{'},
'}' => $Text::TeX::Tokens{'}'},
'\begin' => $Text::TeX::Tokens{'\begin'},
# Just pretend they actually ARE new paragraph markers!
'\maketitle' => {'class' => 'Text::TeX::Paragraph'},
);
-
+
# Now add to MyTokens all of the commands that were read from the
# commands file by package ReadCommands
&ReadCommands::Merge(\%MyTokens);
return 0;
}
+
+sub regularizeLatexLength {
+ my $LatexLength = shift;
+
+ # Remove any whitespace
+ $LatexLength =~ s/\s//g;
+ # Remove a leading '+' as unnecessary
+ $LatexLength =~ s/^\+?(\d)/$1/;
+ # Split into value and unit parts
+ my $val;
+ my $unit;
+ if ($LatexLength =~ /(-?\d+[.,]?\d*)(\\?[a-zA-Z]*)$/) {
+ $val = $1;
+ $unit = $2;
+ }
+ # If the input is invalid, return what we have.
+ return $LatexLength if ($val eq '' || $unit eq '');
+
+ # '4,5' is a valid LaTeX number. Change it to '4.5'
+ $val =~ s/,/./;
+ # If the unit is not a LaTeX macro, then ensure it is lower case
+ if (!($unit =~ /^\\/)) {
+ $unit =~ s/([a-z]*)/\L$1/i;
+ }
+
+ $LatexLength = $val . $unit;
+ return $LatexLength;
+}
+
+
+sub getAsLyXLength {
+ # Straight translation of LaTeX lengths to LyX ones.
+ my %lengthAsLyXString = ('\textwidth' => 'text%',
+ '\columnwidth' => 'col%',
+ '\paperwidth' => 'page%',
+ '\linewidth' => 'line%',
+ '\paperheight' => 'pheight%',
+ '\textheight' => 'theight%');
+
+ my $LatexLength = shift;
+ $LatexLength = regularizeLatexLength($LatexLength);
+
+ my $LyXLength = $LatexLength;
+ # If $LatexLength is something like '4.5\columnwidth', translate into
+ # LyXese.
+ if ($LatexLength =~ /([+-]?\d+\.?\d*)(\\[a-z]*)/) {
+ if (defined($lengthAsLyXString{$2})) {
+ $LyXLength = ($1 * 100) . $lengthAsLyXString{$2};
+ }
+ }
+
+ return $LyXLength;
+}
+
########################## MAIN TRANSLATOR SUBROUTINE #####################
sub basic_lyx {
# This subroutine is called by Text::TeX::process each time subroutine
# If, e.g., there's just a comment in this token, don't do anything
# This actually shouldn't happen if CleanTeX has already removed them
last TYPESW if !defined $eaten->print;
-
+
# Handle LaTeX tokens
if (/^Token$/o) {
} # end special handling for \@
# Handle tokens that LyX translates as a "LatexCommand" inset
- } elsif (grep {$_ eq $name} @LatexCommands) {
+ } elsif (foundIn($name, @LatexCommands) ||
+ isNatbibCitation($name)){
&CheckForNewParagraph; #Start new paragraph if necessary
print OUTFILE "$pre_space\n\\begin_inset LatexCommand ",
$name,
# Items in list environments
} elsif ($name eq '\item') {
-
+
# What if we had a nested "Standard" paragraph?
# Then write \end_deeper to finish the standard layout
# before we write the new \layout ListEnv command
if $debug_on;
} # end deeper if
- # Upcoming text (the item) will be a new paragraph,
+ # Upcoming text (the item) will be a new paragraph,
# requiring a new layout command based on whichever
# kind of list environment we're in
$IsNewParagraph = 1;
$length =~ s/\s*$//; # may have \n at end
# If we can't parse the command, print it in tex mode
- &RelyxFigure::parse_epsfsize($name, $length) or
+ &RelyxFigure::parse_epsfsize($name, $length) or
&print_tex_mode("$name=$length");
# Miscellaneous...
last TYPESW;
}
-
+
# Handle tokens that take arguments, like \section{},\section*{}
if (/^BegArgsToken$/) {
my $name = $eaten->token_name;
print "$name" if $debug_on;
# Handle things that LyX translates as a "LatexCommand" inset
- if (grep {$_ eq $name} @LatexCommands) {
+ if (foundIn($name, @LatexCommands) || isNatbibCitation($name)){
&CheckForNewParagraph; #Start new paragraph if necessary
print OUTFILE "$pre_space\n\\begin_inset LatexCommand ";
($dummy, $dum2) = ($command =~ /(\S+)\s+(\w+)/);
# HACK so that "\emph{hi \emph{bye}}" yields unemph'ed "bye"
- if ( ($dummy eq "\\emph") &&
+ if ( ($dummy eq "\\emph") &&
($CurrentFontStatus->{$dummy}->[-1] eq "on")) {
$dum2 = "default"; # "on" instead of default?
$command =~ s/on/default/;
# Handle footnotes and margin notes
- # Make a new font table & layout stack which will be local to the
+ # Make a new font table & layout stack which will be local to the
# footnote or marginpar
} elsif (exists $FloatTransTable{$name}) {
my $command = $FloatTransTable{$name};
$CurrentLayoutStack = ["Standard"];
# Store whether we're at the end of a paragraph or not
- # for when we get to end of footnote AND
+ # for when we get to end of footnote AND
# Note that the footnote text will be starting a new paragraph
# Also store the current alignment (justification)
$OldINP = $IsNewParagraph; $OldMBD = $MayBeDeeper;
&CheckForNewParagraph; # may be at the beginning of a par
print OUTFILE "$pre_space\n",'\i ',$name,'{'
-
+
# Included Postscript Figures
# Currently, all postscript including commands take one
# required argument and 0 to 2 optional args, so we can
if ($eaten->base_token == $tok) {
©_latex_known($eaten,$fileobject);
}
-
+
last TYPESW;
}
# Handle things that LyX translates as a "LatexCommand" inset
# or "Include" insets
- if (grep {$_ eq $name} @LatexCommands, @IncludeCommands) {
+ if (foundIn($name, @LatexCommands, @IncludeCommands) ||
+ isNatbibCitation($name)){
print OUTFILE "\}\n\n\\end_inset \n\n";
} elsif (exists $ReadCommands::ToLayout->{$name}) {
} elsif ($name =~ m/^$AccentTokens$/) {
print OUTFILE "}\n";
-
+
} elsif ($name eq "\\bibitem") {
print OUTFILE "}\n";
} # End if on $name
if (/^Begin::Group::Args$/) {
print $eaten->print," " if $debug_on; # the string "\begin{foo}"
my $env = $eaten->environment;
-
+
# Any environment found in the layouts files
if (exists $ReadCommands::ToLayout->{$env}) {
&ConvertToLayout($env);
$tok = $fileobject->eatGroup;
new RelyxTable::Table $tok;
+ # minipage
+ } elsif ($env eq "minipage") {
+ &CheckForNewParagraph;
+
+ print OUTFILE "\\begin_inset Minipage\n";
+
+ # The minipage environment is defined as:
+ # \begin{minipage}[pos][height][inner-pos]{width} <text>
+ # \end{minipage}
+
+ # Read the position optional argument, if it exists
+ $tok = $fileobject->eatOptionalArgument;
+ my $pos = $tok->print if defined($tok->print);
+
+ my %map = ('t' => '0', 'c' => '1', 'b' => '2');
+ if ($debug_on && $pos ne '' && !defined($map{$pos})) {
+ print "\nIgnoring unknown positioning arg '$pos'\n";
+ }
+
+ # The minipage is centred by default.
+ $pos = '1' if (!defined($map{$pos}) ||
+ ($pos = $map{$pos}) eq '');
+
+ # Read the height optional argument, if it exists
+ my $height = '0pt';
+ $tok = $fileobject->eatOptionalArgument;
+ if (defined($tok->print)) {
+ $height = getAsLyXLength($tok->print);
+ }
+
+ # Read the inner-pos optional argument, if it exists
+ my $innerpos = $pos;
+ $tok = $fileobject->eatOptionalArgument;
+ if (defined($tok->print)) {
+ my $arg = $tok->print;
+ print("\nMinipage inner-pos argument, $arg, is ",
+ "currently ignored\n");
+ }
+
+ # Read the width as (a reference to) an array of tokens.
+ $tok = $fileobject->eatBalanced;
+ my $width = getAsLyXLength($tok->exact_print);
+
+ print OUTFILE "position $pos\n";
+ print OUTFILE "inner_position $innerpos\n";
+ print OUTFILE "height \"$height\"\n";
+ print OUTFILE "width \"$width\"\n";
+ print OUTFILE "collapsed false\n";
+
# \begin document
} elsif ($env eq "document") {
# do nothing
$tex_mode_string = "";
# print "\begin{env}
# For reLyXskip env, don't print the \begin & \end commands!
- $tex_mode_string .= $eaten->exact_print
+ $tex_mode_string .= $eaten->exact_print
unless $env eq "reLyXskip";
$tex_mode_string .=&Verbatim::copy_verbatim($fileobject,$eaten);
}
last TYPESW;
}
-
+
# Handle \end{foo}
if (/^End::Group::Args$/) {
print $eaten->print," " if $debug_on; # the string "\end{foo}"
# Anything after a table will be a new paragraph
$IsNewParagraph = 1; $MayBeDeeper = 1;
+ # minipage
+ } elsif ($env eq "minipage") {
+ print OUTFILE "\n\\end_inset \n\n";
+
+ # Next stuff will be new env.
+ # $IsNewParagraph = 1;
+
} elsif ($env eq "document") {
print "\nDone with document!" if $debug_on;
# If $CurrentAlignment is set, it prints the alignment command for this par.
# If $MayBeDeeper==1 and we're currently within a list environment,
# it starts a "deeper" Standard paragraph
- my $dummy;
+ my $dummy;
my $layout = $$CurrentLayoutStack[-1];
return if &RelyxTable::in_table;
( ([^A-Za-z] \*?) | # non-letter (and *) ($4) OR
([A-Za-z]+ \*?) ) # letters (and *) ($5)
)//xs) # /x to allow whitespace/comments, /s to copy \n's
- {
+ {
$output .= $1;
my $tok = $2;
if (exists $ReadCommands::math_trans{$tok}) {