LaTeXML
view release on metacpan or search on metacpan
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
# [note, this will load name.tex, if it exists, else name]
DefPrimitive('\includeonly{}', sub {
my ($stomach, $paths) = @_;
$paths = ToString($paths);
my $table = LookupValue('including@only');
AssignValue('including@only', $table = {}, 'global') unless $table;
map { $$table{$_} = 1 } map { /^\s*(.*?)\s*$/ && $1; } split(/,/, $paths);
return; });
# NOTE: In the long run, we want to SAVE the contents and associate them with the given file name
# AND, arrange so that when a file is read, we'll use the contents!
DefConstructorI(T_CS("\\begin{filecontents}"), "Semiverbatim",
'',
reversion => '',
afterDigest => [sub {
my ($stomach, $whatsit) = @_;
my $filename = ToString($whatsit->getArg(1));
my @lines = ();
my $gullet = $stomach->getGullet;
my $line;
while (defined($line = $gullet->readRawLine) && ($line ne '\end{filecontents}')) {
push(@lines, $line); }
AssignValue($filename . '_contents' => join("\n", @lines), 'global');
NoteLog("Cached filecontents for $filename (" . scalar(@lines) . " lines)"); }]);
DefConstructorI(T_CS("\\begin{filecontents*}"), "Semiverbatim",
'',
reversion => '',
afterDigest => [sub {
my ($stomach, $whatsit) = @_;
my $filename = ToString($whatsit->getArg(1));
my @lines = ();
my $gullet = $stomach->getGullet;
my $line;
while (defined($line = $gullet->readRawLine) && ($line ne '\end{filecontents*}')) {
push(@lines, $line); }
AssignValue($filename . '_contents' => join("\n", @lines), 'global');
NoteLog("Cached filecontents* for $filename (" . scalar(@lines) . " lines)"); }]);
DefMacro('\endfilecontents', '');
DefPrimitive('\listfiles', undef);
#======================================================================
# C.11.5 Index and Glossary
#======================================================================
# ---- The index commands
# Format of Index entries:
# \index{entry!entry} gives multilevel index
# Each entry:
# foo@bar sorts on "foo" but prints "bar"
# The entries can end with a |expression:
# \index{...|(} this page starts a range for foo
# \index{...|)} this page ends a range
# The last two aren't handled in any particular way.
# We _could_ mark start & end, and then the postprocessor would
# need to fill in all likely links... ???
# \index{...|see{key}} cross reference.
# \index{...|seealso{key}} cross reference.
# \index{...|textbf} (etc) causes the number to be printed in bold!
#
# I guess the formula is that
# \index{foo|whatever{pi}{pa}{po}} => \whatever{pi}{pa}{po}{page}
# How should this get interpreted??
our %index_style = (textbf => 'bold', bf => 'bold', textrm => '', rm => '',
textit => 'italic', it => 'italic', emph => 'italic'); # What else?
# A bit screwy, but....
# Expand \index{a!b!...} into \@index{\@indexphrase{a}\@indexphrase{b}...}
sub process_index_phrases {
my ($gullet, $phrases, $inlist) = @_;
my @expansion = ();
my @tokens = $phrases->unlist;
# check we have a well-formed argument
return unless @tokens;
if (!$phrases->isBalanced) { # if ill-formed, discard;
Warn("malformed", "indexentry", $gullet,
'index entry has unbalanced groups, discarding: "' . ToString($phrases) . '"');
return; }
# Split the text into phrases, separated by "!"
push(@tokens, T_OTHER('!')) unless $tokens[-1]->getString eq '!'; # Add terminal !
my @phrase = ();
my @sortas = ();
my $style;
while (@tokens) {
my $tok = shift(@tokens);
my $string = $tok->getString;
if ($string eq '"') {
push(@phrase, shift(@tokens)); }
elsif ($string eq '@') {
while (@phrase && ($phrase[-1]->getString =~ /\s/)) { pop(@phrase); } # Trim
@sortas = @phrase; @phrase = (); }
elsif (($string eq '!') || ($string eq '|')) {
while (@phrase && ($phrase[-1]->getString =~ /\s/)) { pop(@phrase); } # Trim
push(@expansion, T_CS('\@indexphrase'),
(@sortas ? (T_OTHER('['), @sortas, T_OTHER(']')) : ()),
T_BEGIN, @phrase, T_END)
if @phrase;
@phrase = (); @sortas = ();
if ($string eq '|') {
pop(@tokens); # Remove the extra "!" stopbit.
my $extra = ToString(Tokens(@tokens));
if ($extra =~ /^see\s*{/) { push(@expansion, T_CS('\@indexsee'), @tokens[3 .. $#tokens]); }
elsif ($extra =~ /^seealso\s*\{/) { push(@expansion, T_CS('\@indexseealso'), @tokens[7 .. $#tokens]); }
elsif ($extra eq '(') { $style = 'rangestart'; } # ?
elsif ($extra eq ')') { $style = 'rangeend'; } # ?
else { $style = $index_style{$extra} || $extra; }
@tokens = (); } }
elsif (!@phrase && ($string =~ /\s/)) { } # Skip leading whitespace
else {
push(@phrase, $tok); } }
@expansion = (T_CS('\@index'),
($style || $inlist ? (T_OTHER('['), ($style ? T_OTHER($style) : ()), T_OTHER(']')) : ()),
($inlist ? (T_OTHER('['), T_OTHER($inlist), T_OTHER(']')) : ()),
T_BEGIN, @expansion, T_END);
return @expansion; }
# read verbatim, as if with LaTeX's \@sanitize;
# useful for \index (maybe others?)
DefParameterType('SanitizedVerbatim', sub {
my ($gullet) = @_;
$gullet->readUntil(T_BEGIN);
( run in 1.846 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )