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 )