# -*- mode: Perl -*-
# /=====================================================================\ #
# | longtable | #
# | Implementation for LaTeXML | #
# |=====================================================================| #
# | Part of LaTeXML: | #
# | Public domain software, produced as part of work done by the | #
# | United States Government & not subject to copyright in the US. | #
# |---------------------------------------------------------------------| #
# | Bruce Miller <bruce.miller@nist.gov> #_# | #
# \=========================================================ooo==U==ooo=/ #
package LaTeXML::Package::Pool;
use strict;
use warnings;
use LaTeXML::Package;
#======================================================================
# NOTE: The way the headers & footers are captured causes trailing \hlines
# to generate empty rows.
#======================================================================
# Environment \begin{longtable}[align]{pattern} ... \end{longtable}
DefMacro('\longtable[]{}',
'\@longtable@bindings{#2}\@@longtable[#1]{#2}\@start@alignment');
DefMacro('\endlongtable',
'\@finish@alignment\@end@tabular');
DefMacro('\csname longtable*\endcsname []{}',
'\@longtable@bindings{#2}\@@longtable[#1]{#2}\@start@alignment');
DefMacro('\csname endlongtable*\endcsname',
'\@finish@alignment\@end@tabular');
DefConstructor('\@@longtable [] Undigested DigestedBody',
"<ltx:table xml:id='#id' refnum='#refnum' frefnum='#frefnum' rrefnum='#rrefnum' labels='#label'>"
. "?#caption(<ltx:caption>#caption</ltx:caption>)"
. "?#toccaption(<ltx:toccaption>#toccaption</ltx:toccaption>)"
. "#3"
. "</ltx:table>",
reversion => '\begin{longtable}[#1]{#2}#3\end{longtable}',
beforeDigest => sub { $_[0]->bgroup; },
afterDigest => sub {
my ($stomach, $whatsit) = @_;
$whatsit->setProperties(%{ LookupValue('LONGTABLE_PROPERTIES') || {} });
# Insert caption and toccaption, if any were encountered.
if (my $caption = LookupValue('LONGTABLE_CAPTION')) {
$whatsit->setProperty(caption => $caption); }
if (my $label = LookupValue('LONGTABLE_LABEL')) {
$whatsit->setProperty(label => $label); }
if (my $toccaption = LookupValue('LONGTABLE_TOCCAPTION')) {
$whatsit->setProperty(toccaption => $toccaption); }
my $alignment = LookupValue('Alignment');
# Reinsert the head and foot into the alignment.
if (my $head = LookupValue('LONGTABLE_HEAD')) {
$alignment->prependRows(@{$head}); }
if (my $foot = LookupValue('LONGTABLE_FOOT')) {
$alignment->appendRows(@{$foot}); }
return; },
mode => 'text');
DefPrimitive('\@longtable@bindings AlignmentTemplate', sub { longtableBindings($_[1]); });
sub longtableBindings {
my ($template) = @_;
tabularBindings($template, guess_headers => 0);
Let('\endfirsthead', '\@longtable@endfirsthead');
Let('\endhead', '\@longtable@endhead');
Let('\endfoot', '\@longtable@endfoot');
Let('\endlastfoot', '\@longtable@endlastfoot');
Let('\caption', '\@longtable@caption');
Let('\label', '\@longtable@label');
AssignValue(LONGTABLE_LABEL => undef, 'global'); # Clear these vars.
AssignValue(LONGTABLE_CAPTION => undef, 'global');
AssignValue(LONGTABLE_TOCCAPTION => undef, 'global');
AssignValue(LONGTABLE_HEAD => undef, 'global');
AssignValue(LONGTABLE_FOOT => undef, 'global');
## properties happen too late!!!
AssignValue(LONGTABLE_PROPERTIES => { RefStepCounter('table') }, 'global');
return; }
#======================================================================
# These macros appear within the longtable, at the beginning.
# They cut of the previous lines to be used as headers or footers.
DefMacro('\@longtable@endfirsthead',
'\@close@inner@column\@close@column\@close@row'
. '\@longtable@grab{FIRSTHEAD}'
. '\@open@row\@open@column\@open@inner@column');
DefMacro('\@longtable@endhead',
'\@close@inner@column\@close@column\@close@row'
. '\@longtable@grab{HEAD}'
. '\@open@row\@open@column\@open@inner@column');
DefMacro('\@longtable@endfoot',
'\@close@inner@column\@close@column\@close@row'
. '\@longtable@grab{FOOT}'
. '\@open@row\@open@column\@open@inner@column');
DefMacro('\@longtable@endlastfoot',
'\@close@inner@column\@close@column\@close@row'
. '\@longtable@grab{LASTFOOT}'
. '\@open@row\@open@column\@open@inner@column');
DefMacro('\@longtable@kill',
'\@close@inner@column\@close@column\@close@row'
. '\@longtable@kill@marker'
. '\@open@row\@open@column\@open@inner@column');
DefPrimitive('\@longtable@grab{}', sub {
my ($stomach, $name) = @_;
$name = ToString($name);
my $alignment = LookupValue('Alignment');
# Remove all preceding rows.
my @rows = ();
while (my $row = $alignment->removeRow) {
map { $$_{thead}{column} = 1; } $row->columns;
unshift(@rows, $row); }
if (($name eq 'FIRSTHEAD') || (($name eq 'HEAD') && !LookupValue('LONGTABLE_HEAD'))) {
AssignValue(LONGTABLE_HEAD => [@rows], 'global'); }
elsif (($name eq 'LASTFOOT') || (($name eq 'FOOT') && !LookupValue('LONGTABLE_FOOT'))) {
AssignValue(LONGTABLE_FOOT => [@rows], 'global'); }
return; });
DefConstructor('\@longtable@kill@marker', '', reversion => '\kill',
afterDigest => sub { LookupValue('Alignment')->removeRow; return; });
#======================================================================
# Caption gets redefined. We'll need to grab it and make it part
# of the table, rather than the tabular.
DefMacro('\@longtable@caption[]{}',
'\@longtable@@toccaption{\format@toctitle@{table}{\ifx.#1.#2\else#1\fi}}'
. '\@longtable@@caption{\format@title@{table}{#2}}');
DefPrimitive('\@longtable@label Semiverbatim', sub {
AssignValue(LONGTABLE_LABEL => CleanLabel(ToString($_[1])), 'global');
return; });
DefPrimitive('\@longtable@@caption{}', sub {
AssignValue(LONGTABLE_CAPTION => Digest($_[1]), 'global');
return; });
DefPrimitive('\@longtable@@toccaption{}', sub {
AssignValue(LONGTABLE_TOCCAPTION => Digest($_[1]), 'global');
return; });
#======================================================================
# Not used, but must be defined.
DefRegister('\LTLeft' => Glue(0));
DefRegister('\LTRight' => Glue(0));
DefRegister('\LTPre' => Glue(0));
DefRegister('\LTPost' => Glue(0));
DefRegister('\LTcapwidth' => Glue(0));
DefRegister('\LTchunksize' => Number(20));
#======================================================================
1;