view release on metacpan or search on metacpan
lib/LaTeXML/Core/Definition.pm view on Meta::CPAN
# starts of pending calls...]
if (!defined $entry) {
$entry = [0, 0, 0, 0, 0]; $STATE->assignMapping('runtime_profile', $name, $entry); }
$$entry[0]++ unless $mode eq 'absorb'; # One more call.
$$entry[4]++; # One more pending...
#Debug("START PROFILE $mode of ".ToString($cs));
$STATE->pushValue('runtime_stack', [$name, $mode, [Time::HiRes::gettimeofday], $entry]);
return; }
# Stop profiling $CS.
# Complication w/Macros: If the expansion of a macro contains CS's that read tokens,
# the end MARKER of macros may get read before the macro's effects have really been processed.
# So we need to ignore a stop on a macro that isn't at the top of the stack,
# and conversely, automatically stop a macro that is at the top above a CS that is being stopped.
sub stopProfiling {
my ($cs, $mode) = @_;
$cs = $cs->getString if $cs->getCatcode == CC_MARKER; # Special case for macros!!
return unless ref $cs;
my $name = $cs->getCSName;
my $stack = $STATE->lookupValue('runtime_stack');
my $currdepth = scalar(@$stack);
lib/LaTeXML/Core/KeyVal.pm view on Meta::CPAN
if (scalar(@$paramlist) != 1) {
Warn('unexpected', 'keyval', $key,
"Too many parameters in keyval $key (in set $keyset with prefix $prefix)"
. "taking only first", $paramlist); }
keyval_set($qname, type => $$paramlist[0]);
# set the default
# Question: Why was $default converted ToString ???
if (defined $default) {
my @tdefault = LaTeXML::Package::Tokenize($default);
keyval_set($qname, default => Tokens(@tdefault));
LaTeXML::Package::DefMacroI('\\' . $qname . '@default', undef,
Tokens(T_CS('\\' . $qname), T_BEGIN, @tdefault, T_END)); }
# figure out the kind of key-val parameter we are defining
my $kind = $options{kind} || 'ordinary';
if ($kind eq 'ordinary') {
defineOrdinary($qname, $options{code}); }
elsif ($kind eq 'command') {
my $macroname = ($options{macroprefix} ? $options{macroprefix} . $key : "cmd" . $qname);
defineCommand($qname, $options{code}, $macroname); }
elsif ($kind eq 'choice') {
lib/LaTeXML/Core/KeyVal.pm view on Meta::CPAN
elsif ($kind eq 'boolean') {
my $macroname = ($options{macroprefix} ? $options{macroprefix} . $key : $qname);
defineBoolean($qname, $options{code}, $options{mismatch}, $macroname); }
else {
Warn('unknown', undef, "Unknown KeyVals kind $kind",
"should be one of 'ordinary', 'command', 'choice', 'boolean'. "); }
return; }
sub defineOrdinary {
my ($qname, $code) = @_;
LaTeXML::Package::DefMacroI('\\' . $qname, '{}', (defined($code) ? $code : ''));
return; }
sub defineCommand {
my ($qname, $code, $macroname) = @_;
LaTeXML::Package::DefMacroI('\\' . $qname, '{}', sub {
my ($gullet, $value) = @_;
my $orig = '\\ltxml@orig@' . $qname;
LaTeXML::Package::DefMacroI($orig, '{}', $code);
Tokens(T_CS("\\def"), T_CS('\\' . $macroname), T_BEGIN, $value, T_END,
T_CS($orig), T_BEGIN, T_PARAM, $value, T_END); # $value !?!??! Is it a number 1--9 ???
});
return; }
sub defineChoice {
my ($qname, $code, $mismatch, $choices, $normalize, $bin) = @_;
my $norm = ($normalize ? sub { lc $_[0]; } : sub { $_[0]; });
my ($varmacro, $idxmacro) = defined($bin) ? $bin->unlist : (undef, undef);
LaTeXML::Package::DefMacroI('\\' . $qname, '{}', sub {
my ($gullet, $value) = @_;
# Store the normalized value (if applicable)
my $nvalue = &$norm(ToString($value));
LaTeXML::Package::DefMacro($varmacro, sub { Explode($nvalue); }) if defined($varmacro);
# iterate over the possible choices and store them
my $ochoice;
my $index = 0;
my $valid = 0;
foreach my $choice (@{$choices}) {
if (&$norm(ToString($choice)) eq $nvalue) {
$ochoice = $choice;
$valid = 1;
LaTeXML::Package::DefMacro($idxmacro, Explode(ToString($index))) if defined($idxmacro); }
$index += 1; }
# find a name for the original macro to store in
my @tokens = ();
my $orig = '\\ltxml@orig@' . $qname;
# if we have chosen a valid index, run $code
if ($valid) {
if (defined($code)) {
LaTeXML::Package::DefMacroI($orig, '{}', $code);
push(@tokens, T_CS($orig), T_BEGIN, $value, T_END); } }
# else run $mismatch
elsif (defined($mismatch)) {
LaTeXML::Package::DefMacroI($orig, '{}', $mismatch);
push(@tokens, T_CS($orig), T_BEGIN, $value, T_END); }
@tokens; });
return; }
sub defineBoolean {
my ($qname, $code, $mismatch, $macroname) = @_;
LaTeXML::Package::DefConditional(T_CS("\\if$macroname")); # We might need to $scope here
defineChoice($qname, sub {
my ($gullet, $value) = @_;
# set the value to true (if needed)
my @tokens = ();
push(@tokens, T_CS('\\' . $macroname . (((lc ToString($value)) eq 'true') ? 'true' : 'false')));
# Store and invoke the original macro if needed
if ($code) {
my $orig = '\\ltxml@@rig@' . $qname;
LaTeXML::Package::DefMacroI($orig, '{}', $code);
push(@tokens, T_CS($orig), T_BEGIN, $value, T_END); }
@tokens; },
$mismatch, [("true", "false")], 1);
return; }
#======================================================================
1;
__END__
lib/LaTeXML/Package.pm view on Meta::CPAN
use LaTeXML::Util::WWW;
use LaTeXML::Common::XML;
use LaTeXML::Core::Rewrite;
use LaTeXML::Util::Radix;
use File::Which;
use Unicode::Normalize;
use Text::Balanced;
use Text::Unidecode;
use base qw(Exporter);
our @EXPORT = (qw(&DefAutoload &DefExpandable
&DefMacro &DefMacroI
&DefConditional &DefConditionalI &IfCondition &SetCondition
&DefPrimitive &DefPrimitiveI
&DefRegister &DefRegisterI &LookupRegister &AssignRegister &LookupDimension
&DefConstructor &DefConstructorI
&dualize_arglist &createXMRefs
&DefMath &DefMathI &DefEnvironment &DefEnvironmentI
&convertLaTeXArgs),
# Class, Package and File loading.
qw(&Input &InputContent &InputDefinitions &RequirePackage &LoadClass &LoadPool &FindFile
&DeclareOption &PassOptions &ProcessOptions &ExecuteOptions
&AddToMacro &AtBeginDocument &AtEndDocument),
# Counter support
qw(&NewCounter &CounterValue &SetCounter &AddToCounter &StepCounter &RefStepCounter &RefStepID &ResetCounter
&GenerateID &AfterAssignment
&MaybePeekLabel &MaybeNoteLabel),
# Document Model
qw(&Tag &DocType &RelaxNGSchema &RegisterNamespace &RegisterDocumentNamespace),
# Document Rewriting
lib/LaTeXML/Package.pm view on Meta::CPAN
return; }
sub DefColumnType {
my ($proto, $expansion) = @_;
if ($proto =~ s/^(.)//) {
my $char = $1;
$proto =~ s/^\s*//;
# Defer
# $expansion = TokenizeInternal($expansion) unless ref $expansion;
$proto = parseParameters($proto, $char);
DefMacroI(T_CS('\NC@rewrite@' . $char), $proto, $expansion); }
else {
Warn('expected', 'character', undef, "Expected Column specifier"); }
return; }
#======================================================================
# Allocated registers.
# We ASSUME the same set of \count positions used by TeX & LaTeX
# for recording the next available position in \count,\dimen,\skip,\muskip.
our %allocations = (
'\count' => '\count10', '\dimen' => '\count11', '\skip' => '\count12', '\muskip' => '\count13',
lib/LaTeXML/Package.pm view on Meta::CPAN
AssignValue("\\cl\@$unctr" => Tokens(), 'global') unless LookupValue("\\cl\@$unctr");
my $x;
AssignValue("\\cl\@$within" =>
Tokens(T_CS($ctr), T_CS($unctr), (($x = LookupValue("\\cl\@$within")) ? $x->unlist : ())),
'global') if $within;
AssignValue("\\cl\@UN$within" =>
Tokens(T_CS($unctr), (($x = LookupValue("\\cl\@UN$within")) ? $x->unlist : ())),
'global') if $within;
AssignValue('nested_counters_' . $ctr => $options{nested}, 'global') if $options{nested};
# default is equivalent to \arabic{ctr}, but w/o using the LaTeX macro!
DefMacroI(T_CS("\\the$ctr"), undef, sub {
ExplodeText(CounterValue($ctr)->valueOf); },
scope => 'global');
if (!LookupDefinition(T_CS("\\p\@$ctr"))) {
DefMacroI(T_CS("\\p\@$ctr"), undef, Tokens(), scope => 'global'); }
my $prefix = $options{idprefix};
AssignValue('@ID@prefix@' . $ctr => $prefix, 'global') if $prefix;
$prefix = LookupValue('@ID@prefix@' . $ctr) || $ctr unless $prefix;
$prefix = CleanID($prefix);
if (defined $prefix) {
if (my $idwithin = $options{idwithin} || $within) {
DefMacroI(T_CS("\\the$ctr\@ID"), undef,
"\\expandafter\\ifx\\csname the$idwithin\@ID\\endcsname\\\@empty"
. "\\else\\csname the$idwithin\@ID\\endcsname.\\fi"
. " $prefix\\csname \@$ctr\@ID\\endcsname",
scope => 'global'); }
else {
DefMacroI(T_CS("\\the$ctr\@ID"), undef, "$prefix\\csname \@$ctr\@ID\\endcsname",
scope => 'global'); }
DefMacroI(T_CS("\\\@$ctr\@ID"), undef, "0", scope => 'global'); }
return; }
sub CounterValue {
my ($ctr) = @_;
$ctr = ToString(Expand($ctr)) if ref $ctr;
my $value = LookupRegister('\c@' . $ctr);
if (!$value) {
Warn('undefined', $ctr, $STATE->getStomach,
"Counter '$ctr' was not defined; assuming 0");
$value = Number(0); }
lib/LaTeXML/Package.pm view on Meta::CPAN
if (my $after = $STATE->lookupValue('afterAssignment')) {
$STATE->assignValue(afterAssignment => undef, 'global');
$STATE->getStomach->getGullet->unread($after); } # primitive returns boxes, so these need to be digested!
return; }
sub SetCounter {
my ($ctr, $value) = @_;
$ctr = ToString(Expand($ctr)) if ref $ctr;
AssignRegister('\c@' . $ctr => $value, 'global');
AfterAssignment();
DefMacroI(T_CS("\\\@$ctr\@ID"), undef, Tokens(Explode($value->valueOf)), scope => 'global');
return; }
sub AddToCounter {
my ($ctr, $value) = @_;
$ctr = ToString(Expand($ctr)) if ref $ctr;
my $v = CounterValue($ctr)->add($value);
AssignRegister('\c@' . $ctr => $v, 'global');
AfterAssignment();
DefMacroI(T_CS("\\\@$ctr\@ID"), undef, Tokens(Explode($v->valueOf)), scope => 'global');
return; }
sub StepCounter {
my ($ctr, $noreset) = @_;
my $value = CounterValue($ctr);
my $newvalue = $value->add(Number(1));
AssignRegister("\\c\@$ctr" => $newvalue, 'global');
AfterAssignment();
DefMacroI(T_CS("\\\@$ctr\@ID"), undef, Tokens(Explode($newvalue->valueOf)),
scope => 'global');
# and reset any within counters!
if (!$noreset) {
if (my $nested = LookupValue("\\cl\@$ctr")) {
foreach my $c ($nested->unlist) {
ResetCounter(ToString($c)); } } }
# DigestIf(T_CS("\\the$ctr"));
return; }
# HOW can we retract this?
sub RefStepCounter {
my ($type, $noreset) = @_;
my $ctr = LookupMapping('counter_for_type', $type) || $type;
$ctr = ToString(Expand($ctr)) if ref $ctr;
StepCounter($ctr, $noreset);
maybePreemptRefnum($ctr);
my $iddef = $STATE->lookupDefinition(T_CS("\\the$ctr\@ID"));
my $has_id = $iddef && ((!defined $iddef->getParameters) || ($iddef->getParameters->getNumArgs == 0));
DefMacroI(T_CS('\@currentlabel'), undef, T_CS("\\the$ctr"), scope => 'global');
DefMacroI(T_CS('\@currentID'), undef, T_CS("\\the$ctr\@ID"), scope => 'global') if $has_id;
my $id = $has_id && CleanID(ToString(DigestLiteral(T_CS("\\the$ctr\@ID"))));
my $refnum = DigestText(T_CS("\\the$ctr"));
my $tags = Digest(Invocation(T_CS('\lx@make@tags'), $type));
# Any scopes activated for previous value of this counter (& any nested counters) must be removed.
# This may also include scopes activated for \label
deactivateCounterScope($ctr);
# And install the scope (if any) for this reference number.
AssignValue(current_counter => $ctr, 'local');
lib/LaTeXML/Package.pm view on Meta::CPAN
# First, restore the \the<ctr> and \the<ctr>@ID macros to defaults
if (!$norefnum && LookupMeaning($hj_refnum)) {
Let(T_CS('\the' . $ctr), $hj_refnum, 'global'); }
if (LookupMeaning($hj_id)) {
Let(T_CS('\the' . $ctr . '@ID'), $hj_id, 'global'); }
my $label = LookupValue('PEEKED_LABEL');
my ($fixedrefnum, $fixedid) = &$mapper($label, $ctr, $norefnum);
if (!$norefnum && $fixedrefnum) {
if (!LookupMeaning($hj_refnum)) { # Save for later
Let($hj_refnum, T_CS('\the' . $ctr), 'global'); }
DefMacroI('\the' . $ctr, undef, $fixedrefnum, scope => 'global'); }
if ($fixedid) {
if (!LookupMeaning($hj_id)) { # Save for later
Let($hj_id, T_CS('\the' . $ctr . '@ID'), 'global'); }
DefMacroI('\the' . $ctr . '@ID', undef, $fixedid, scope => 'global'); }
AssignValue(PEEKED_LABEL => undef, 'global'); # CONSUME the label
AssignValue(PROCESSED_LABEL => $label, 'global'); # Note that we've consumed the label
}
return; }
# Use to peek for FOLLOWING \label{...} to support label-derived refererence numbers
sub MaybePeekLabel {
if (LookupValue('LABEL_MAPPING_HOOK')) {
my $gullet = $STATE->getStomach->getGullet;
my $peek = $gullet->readNonSpace;
lib/LaTeXML/Package.pm view on Meta::CPAN
deactivateCounterScope($inner_ctr); }
return; }
# For UN-numbered units
sub RefStepID {
my ($type) = @_;
my $ctr = LookupMapping('counter_for_type', $type) || $type;
my $unctr = "UN$ctr";
StepCounter($unctr);
maybePreemptRefnum($ctr, 1);
DefMacroI(T_CS("\\\@$ctr\@ID"), undef,
Tokens(T_OTHER('x'), Explode(LookupValue('\c@' . $unctr)->valueOf)),
scope => 'global');
DefMacroI(T_CS('\@currentID'), undef, T_CS("\\the$ctr\@ID"));
my $id = CleanID(ToString(DigestLiteral(T_CS("\\the$ctr\@ID"))));
return (id => $id); }
sub ResetCounter {
my ($ctr) = @_;
AssignRegister('\c@' . $ctr => Number(0), 'global');
AssignRegister('\c@UN' . $ctr => Number(0), 'global') unless $ctr =~ /^UN/; # but not UNUN
DefMacroI(T_CS("\\\@$ctr\@ID"), undef, Tokens(T_OTHER('0')),
scope => 'global');
# and reset any within counters!
if (my $nested = LookupValue("\\cl\@$ctr")) {
foreach my $c ($nested->unlist) {
ResetCounter(ToString($c)); } }
return; }
#**********************************************************************
# This function computes an xml:id for a node, if it hasn't already got one.
# It is suitable for use in Tag afterOpen as
lib/LaTeXML/Package.pm view on Meta::CPAN
$cs = T_CS($csname) unless ref $cs;
$defnfile =~ s/\.ltxml$//;
if ($defnfile =~ /^(.*?)\.(pool|sty|cls)$/) {
my ($name, $type) = ($1, $2);
# if already loaded, or set, DONT redefine!
if (!(
LookupValue($name . '.' . $type . '_loaded') ||
LookupValue($name . '.' . $type . '.ltxml_loaded') ||
LookupMeaning($cs))) {
AssignMapping('autoload_' . $defnfile, $csname => 1);
DefMacroI($cs, undef, sub {
ClearAutoLoad($defnfile);
if ($type eq 'pool') { LoadPool($name); } # Load appropriate definitions
elsif ($type eq 'cls') { LoadClass($name); }
else { RequirePackage($name); }
($cs); }); } } # Then return the original cs, so that it's be re-tried.
else {
Warning('unexpected', $defnfile, undef, "Don't know how to autoload $csname from $defnfile"); }
return; }
# Undefine ALL autoload triggers for this definition file.
lib/LaTeXML/Package.pm view on Meta::CPAN
# The $replacement should be a LaTeXML::Core::Tokens (the arguments will be
# substituted for any #1,...), or a sub which returns a list of tokens (or just return;).
# Those tokens, if any, will be reinserted into the input.
# There are no options to these definitions.
my $expandable_options = { # [CONSTANT]
scope => 1, locked => 1 };
sub DefExpandable {
my ($proto, $expansion, %options) = @_;
Warn('deprecated', 'DefExpandable', $STATE->getStomach,
"DefExpandable ($proto) is deprecated; use DefMacro");
DefMacro($proto, $expansion, %options);
return; }
# Define a Macro: Essentially an alias for DefExpandable
# For convenience, the $expansion can be a string which will be tokenized.
my $macro_options = { # [CONSTANT]
scope => 1, locked => 1, mathactive => 1,
protected => 1, robust => 1, outer => 1, long => 1,
nopackParameters => 1 };
# Defines $cs as protected call to the mangled name "\cs ", which it returns
sub defRobustCS {
my ($cs, %options) = @_;
my $defcs = T_CS($_[0]->getString . ' ');
$STATE->installDefinition(LaTeXML::Core::Definition::Expandable->new($cs, undef,
Tokens(T_CS('\protect'), $defcs), locked => $options{locked}),
$options{scope}); # should be \x@protect?
return $defcs; }
sub DefMacro {
my ($proto, $expansion, %options) = @_;
CheckOptions("DefMacro ($proto)", $macro_options, %options);
DefMacroI(parsePrototype($proto), $expansion, %options);
return; }
sub DefMacroI {
my ($cs, $paramlist, $expansion, %options) = @_;
if (!defined $expansion) { $expansion = Tokens(); }
# Optimization: Defer till macro actually used
# elsif (!ref $expansion) { $expansion = TokenizeInternal($expansion); }
if ((length($cs) == 1) && $options{mathactive}) {
$STATE->assignMathcode($cs => 0x8000, $options{scope}); }
$cs = coerceCS($cs);
$paramlist = parseParameters($paramlist, $cs) if defined $paramlist && !ref $paramlist;
my $defcs = ($options{robust} ? defRobustCS($cs, %options) : $cs);
$STATE->installDefinition(LaTeXML::Core::Definition::Expandable->new($defcs, $paramlist, $expansion, %options),
lib/LaTeXML/Package.pm view on Meta::CPAN
$STATE->installDefinition(LaTeXML::Core::Definition::Conditional->new($cs, $paramlist, $test,
conditional_type => 'unless', %options),
$options{scope}); }
elsif ($csname =~ /^\\(..)(.*)$/) {
my ($prefix, $name) = ($1, $2);
if ($prefix ne 'if') {
Warn('misdefined', $cs, $STATE->getStomach,
"The conditional " . Stringify($cs) . " is being defined but doesn't start with \\if"); }
if ((defined $name) && ($name ne 'case')
&& (!defined $test)) { # user-defined conditional, like with \newif
DefMacroI(T_CS('\\' . $name . 'true'), undef, Tokens(T_CS('\let'), $cs, T_CS('\iftrue')));
DefMacroI(T_CS('\\' . $name . 'false'), undef, Tokens(T_CS('\let'), $cs, T_CS('\iffalse')));
Let($cs, T_CS('\iffalse')); }
else {
# For \ifcase, the parameter list better be a single Number !!
$paramlist = parseParameters($paramlist, $cs) if defined $paramlist && !ref $paramlist;
$STATE->installDefinition(LaTeXML::Core::Definition::Conditional->new($cs, $paramlist, $test,
conditional_type => 'if', %options),
$options{scope}); }
}
else {
Error('misdefined', $cs, $STATE->getStomach,
lib/LaTeXML/Package.pm view on Meta::CPAN
AssignValue(ToString($cs) . ":locked" => 1) if $options{locked};
return; }
#======================================================================
# Support for XMDual
# Perhaps it would be better to use a label(-like) indirection here,
# so all ID's can stay in the desired format?
sub getXMArgID {
StepCounter('@XMARG');
DefMacroI(T_CS('\@@XMARG@ID'), undef, Tokens(Explode(LookupRegister('\c@@XMARG')->valueOf)),
scope => 'global');
return Expand(T_CS('\the@XMARG@ID')); }
# Given a list of Tokens (to be expanded into mathematical objects)
# return two lists:
# (1) The Tokens' wrapped in an XMAarg, with an ID added
# (2) a corresponding list of Tokens creating XMRef's to those IDs
# Ah, but there are complications!!!
# On the one hand, arguments may be hidden, never appearing on the presentation side
# (all will be passed to the content side); This argues for putting the XMArg's on the content side.
lib/LaTeXML/Package.pm view on Meta::CPAN
my $sizer = inferSizer($options{sizer}, $options{reversion});
$STATE->installDefinition(LaTeXML::Core::Definition::Constructor
->new(T_CS("\\begin{$name}"), $paramlist_skips, $replacement,
beforeDigest => flatten(($options{requireMath} ? (sub { requireMath($name); }) : ()),
($options{forbidMath} ? (sub { forbidMath($name); }) : ()),
sub { $_[0]->bgroup; },
sub { my $b = LookupValue('@environment@' . $name . '@atbegin');
($b ? Digest(@$b) : ()); },
($mode ? (sub { $_[0]->setMode($mode); }) : ()),
sub { AssignValue(current_environment => $name);
DefMacroI('\@currenvir', undef, $name); },
($options{font} ? (sub { MergeFont(%{ $options{font} }); }) : ()),
$options{beforeDigest}),
afterDigest => flatten($options{afterDigestBegin}),
afterDigestBody => flatten($options{afterDigestBody}),
beforeConstruct => flatten(sub { $STATE->pushFrame; }, $options{beforeConstruct}),
# Curiously, it's the \begin whose afterConstruct gets called.
afterConstruct => flatten($options{afterConstruct}, sub { $STATE->popFrame; }),
nargs => $options{nargs},
captureBody => 1,
properties => $options{properties} || {},
lib/LaTeXML/Package.pm view on Meta::CPAN
sub DeclareOption {
my ($option, $code) = @_;
$option = ToString($option) if ref $option;
PushValue('@declaredoptions', $option) if $option;
my $cs = ($option ? '\ds@' . $option : '\default@ds');
Debug("Declaring option: " . ($option ? $option : '<default>')) if $LaTeXML::DEBUG{packageoptions};
if ((!defined $code) || (ref $code eq 'CODE')) {
DefPrimitiveI($cs, undef, $code); }
else {
DefMacroI($cs, undef, $code); }
return; }
# Pass the sequence of @options to the package $name (if $ext is 'sty'),
# or class $name (if $ext is 'cls').
sub PassOptions {
my ($name, $ext, @options) = @_;
PushValue('opt@' . $name . '.' . $ext, map { ToString($_) } @options);
Debug("Passing to $name.$ext options: " . join(', ', @options)) if $LaTeXML::DEBUG{packageoptions};
return; }
lib/LaTeXML/Package.pm view on Meta::CPAN
if ($options{keysets} && ($option =~ /^(.*)=(.*)$/)) {
my ($key, $value) = ($1, $2);
foreach my $keyset (@{ $options{keysets} }) {
my $qname = keyval_qname('KV', $keyset, $key);
if (my $keytype = keyval_get($qname, 'type')) {
Debug("PROCESS KeyVal OPTION $key => $value") if $LaTeXML::DEBUG{packageoptions};
Digest(Tokens(T_CS('\\' . $qname), T_BEGIN, Revert($value), T_END));
return 1; } } }
if ($STATE->lookupDefinition($cs)) {
Debug("PROCESS OPTION $option") if $LaTeXML::DEBUG{packageoptions};
DefMacroI('\CurrentOption', undef, $option);
AssignValue('@unusedoptionlist',
[grep { $_ ne $option } @{ LookupValue('@unusedoptionlist') || [] }]);
Digest($cs);
return 1; }
else {
return; } }
sub executeDefaultOption_internal {
my ($option) = @_;
Debug("PROCESS DEFAULT OPTION $option") if $LaTeXML::DEBUG{packageoptions};
# presumably should NOT remove from @unusedoptionlist ?
DefMacroI('\CurrentOption', undef, $option);
Digest(T_CS('\default@ds'));
return 1; }
sub ExecuteOptions {
my (@options) = @_;
my %unhandled = ();
foreach my $option (@options) {
if (executeOption_internal($option)) { }
else {
$unhandled{$option} = 1; } }
lib/LaTeXML/Package.pm view on Meta::CPAN
"Unexpected options passed to ExecuteOptions '$option'"); }
return; }
sub resetOptions {
AssignValue('@declaredoptions', []);
Let('\default@ds',
(ToString(Expand(T_CS('\@currext'))) eq 'cls'
? '\OptionNotUsed' : '\@unknownoptionerror'));
return; }
sub AddToMacro {
my ($cs, @tokens) = @_;
$cs = T_CS($cs) unless ref $cs;
@tokens = map { (ref $_ ? $_ : TokenizeInternal($_)) } @tokens;
# Needs error checking!
my $defn = $STATE->lookupDefinition($cs);
if (!defined $defn || !$defn->isExpandable) {
Warn('unexpected', $cs, $STATE->getStomach->getGullet,
ToString($cs) . " is not an expandable control sequence", "Ignoring addition"); }
else {
DefMacroI($cs, undef, Tokens(map { $_->unlist }
map { (blessed $_ ? $_ : TokenizeInternal($_)) } ($defn->getExpansion, @tokens)),
nopackParameters => 1, scope => 'global', locked => $$defn{locked}); }
return; }
#======================================================================
my $inputdefinitions_options = { # [CONSTANT]
options => 1, withoptions => 1, handleoptions => 1,
type => 1, as_class => 1, noltxml => 1, notex => 1, noerror => 1, after => 1,
at_letter => 1, searchpaths_only => 1, reloadable => 1 };
# options=>[options...]
lib/LaTeXML/Package.pm view on Meta::CPAN
# OR if it is loaded by such a class, and has withoptions true!!! (yikes)
$options{as_class} = 1 if $options{handleoptions} && $options{withoptions}
&& grep { $prevname eq $_ } @{ LookupValue('@masquerading@as@class') || [] };
$options{raw} = 1 if $options{noltxml}; # so it will be read as raw by Gullet.!L!
my $astype = ($options{as_class} ? 'cls' : $options{type} || 'sty');
if ($astype eq 'cls' and $options{options}) {
PushValue(class_options => @{ $options{options} });
# ? Expand {\zap@space#2 \@empty}%
DefMacroI('\@classoptionslist', undef, join(',', @{ $options{options} })); }
my $filename = $name;
$filename .= '.' . $options{type} if $options{type};
if ($options{options} && scalar(@{ $options{options} })) {
if (my $prevoptions = LookupValue($filename . '_loaded_with_options')) {
my $curroptions = join(',', @{ $options{options} });
Info('unexpected', 'options', $STATE->getStomach->getGullet,
"Option clash for file $filename with options '$curroptions'",
"previously loaded with '$prevoptions'") unless $curroptions eq $prevoptions; } }
if (my $file = FindFile($filename, type => $options{type},
lib/LaTeXML/Package.pm view on Meta::CPAN
if $pushpop;
# For \RequirePackageWithOptions, pass the options from the outer class/style to the inner one.
if (my $passoptions = $options{withoptions} && $prevname
&& LookupValue('opt@' . $prevname . "." . $prevext)) {
# Only pass those class options that are declared by the package!
my @declaredoptions = @{ LookupValue('@declaredoptions') };
my @topass = ();
foreach my $op (@$passoptions) {
push(@topass, $op) if grep { $op eq $_ } @declaredoptions; }
PassOptions($name, $astype, @topass) if @topass; }
DefMacroI('\@currname', undef, Tokens(Explode($name)));
DefMacroI('\@currext', undef, Tokens(Explode($astype)));
# reset options (Note reset & pass were in opposite order in LoadClass ????)
resetOptions();
PassOptions($name, $astype, @{ $options{options} || [] }); # passed explicit options.
# Note which packages are pretending to be classes.
PushValue('@masquerading@as@class', $name) if $options{as_class};
DefMacroI(T_CS('\\' . $name . '.' . $astype . '-h@@k'), undef, $options{after} || '');
DefMacroI(T_CS('\opt@' . $name . '.' . $astype), undef,
Tokens(Explode(join(',', @{ LookupValue('opt@' . $name . "." . $astype) }))));
}
AssignValue($filename . '_loaded_with_options' => join(',', @{ $options{options} }), 'global')
if $options{options};
my ($fdir, $fname, $ftype) = pathname_split($file);
if ($options{handleoptions}) {
# Add an appropriately faked entry into \@filelist
my ($d, $n, $e) = ($fdir, $fname, $ftype); # If ftype is ltxml, reparse to get sty/cls!
($d, $n, $e) = pathname_split(pathname_concat($d, $n)) if $e eq 'ltxml'; # Fake it???
my @p = ($STATE->lookupDefinition(T_CS('\@filelist'))
? Expand(T_CS('\@filelist'))->unlist : ());
my @n = Explode($e ? $n . '.' . $e : $n);
DefMacroI('\@filelist', undef, (@p ? Tokens(@p, T_OTHER(','), @n) : Tokens(@n))); }
if ($ftype eq 'ltxml') {
loadLTXML($filename, $file, reloadable => $options{reloadable}); } # Perl module.
else {
# Special case -- add a default resource if we're loading a raw .cls file as a first choice.
# Raw class interpretations needs _some_ styling as baseline.
if (!$options{noltxml} && ($file =~ /\.cls$/)) {
RelaxNGSchema("LaTeXML");
RequireResource('ltx-article.css'); }
loadTeXDefinitions($filename, $file, %options); }
if ($options{handleoptions}) {
Digest(T_CS('\\' . $name . '.' . $astype . '-h@@k'));
DefMacroI('\@currname', undef, Tokens(Explode($prevname))) if $prevname;
DefMacroI('\@currext', undef, Tokens(Explode($prevext))) if $prevext;
Digest(T_CS('\@popfilename')) if $pushpop;
resetOptions(); } # And reset options afterwards, too.
return $file; }
elsif (!$options{noerror}) {
$STATE->noteStatus(missing => $name . ($options{type} ? '.' . $options{type} : ''));
# We'll only warn about a missing file of definitions: it may be ignorable or never used.
# if there ARE problems, they'll likely produce their own errors!
Warn('missing_file', $name, $STATE->getStomach->getGullet,
"Can't find "
. ($options{notex} ? "binding for " : "")
lib/LaTeXML/Package.pm view on Meta::CPAN
sub AtBeginDocument {
my (@operations) = @_;
AssignValue('@at@begin@document', []) unless LookupValue('@at@begin@document');
foreach my $op (@operations) {
next unless $op;
my $t = ref $op;
if (!$t) { # Presumably String?
$op = TokenizeInternal($op); }
elsif ($t eq 'CODE') {
my $tn = T_CS(ToString($op));
DefMacroI($tn, undef, $op);
$op = $tn; }
PushValue('@at@begin@document', $op->unlist); }
return; }
sub AtEndDocument {
my (@operations) = @_;
AssignValue('@at@end@document', []) unless LookupValue('@at@end@document');
foreach my $op (@operations) {
next unless $op;
my $t = ref $op;
if (!$t) { # Presumably String?
$op = TokenizeInternal($op); }
elsif ($t eq 'CODE') {
my $tn = T_CS(ToString($op));
DefMacroI($tn, undef, $op);
$op = $tn; }
PushValue('@at@end@document', $op->unlist); }
return; }
#======================================================================
#
my $fontmap_options = { # [CONSTANT]
family => 1 };
sub DeclareFontMap {
lib/LaTeXML/Package.pm view on Meta::CPAN
sub DefColor {
my ($name, $color, $scope) = @_;
return unless ref $color;
my ($model, @spec) = @$color;
$scope = 'global' if $STATE->lookupDefinition(T_CS('\ifglobalcolors')) && IfCondition(T_CS('\ifglobalcolors'));
AssignValue('color_' . $name => $color, $scope);
# We could store these pieces separately,or in a list for above,
# so that extract could use them more reasonably?
# This is perhaps too xcolor specific?
DefMacroI('\\\\color@' . $name, undef,
'\relax\relax{' . join(' ', $model, @spec) . '}{' . $model . '}{' . join(',', @spec) . '}',
scope => $scope);
return; }
# Need 3 things for Derived Models:
# derivedfrom : the core model that this model is "derived from"
# convertto : code to convert to the (a) core model
# convertfrom : code to convert from the core model
sub DefColorModel {
my ($model, $coremodel, $tocore, $fromcore) = @_;
lib/LaTeXML/Package.pm view on Meta::CPAN
package LaTeXML::Package::pool; # to put new subs & variables in common pool
use LaTeXML::Package; # to load these definitions
use strict; # good style
use warnings;
#
# Load "anotherpackage"
RequirePackage('anotherpackage');
#
# A simple macro, just like in TeX
DefMacro('\thesection', '\thechapter.\roman{section}');
#
# A constructor defines how a control sequence generates XML:
DefConstructor('\thanks{}', "<ltx:thanks>#1</ltx:thanks>");
#
# And a simple environment ...
DefEnvironment('{abstract}','<abstract>#body</abstract>');
#
# A math symbol \Real to stand for the Reals:
DefMath('\Real', "\x{211D}", role=>'ID');
#
lib/LaTeXML/Package.pm view on Meta::CPAN
be supplied: before processing a TeX source file, eg C<mydoc.tex>, LaTeXML
will automatically include the definitions and settings in C<mydoc.latexml>.
These C<.ltxml> and C<.latexml> files should be placed LaTeXML's searchpaths, where will
find them: either in the current directory or in a directory given to the --path option,
or possibly added to the variable SEARCHPATHS).
Since LaTeXML mimics TeX, a familiarity with TeX's processing model is critical.
LaTeXML models: catcodes and tokens
(See L<LaTeXML::Core::Token>, L<LaTeXML::Core::Tokens>) which are extracted
from the plain source text characters by the L<LaTeXML::Core::Mouth>;
L</Macros>, which are expanded within the L<LaTeXML::Core::Gullet>;
and L</Primitives>, which are digested within the L<LaTeXML::Core::Stomach>
to produce L<LaTeXML::Core::Box>, L<LaTeXML::Core::List>.
A key additional feature is the L</Constructors>:
when digested they generate a L<LaTeXML::Core::Whatsit> which, upon absorption by
L<LaTeXML::Core::Document>, inserts text or XML fragments in the final document tree.
I<Notation:> Many of the following forms take code references as arguments or options.
That is, either a reference to a defined sub, eg. C<\&somesub>, or an
anonymous function C<sub { ... }>. To document these cases, and the
arguments that are passed in each case, we'll use a notation like
C<I<code>($stomach,...)>.
=head2 Control Sequences
Many of the following forms define the behaviour of control sequences.
While in TeX you'll typically only define macros, LaTeXML is effectively redefining TeX itself,
so we define L</Macros> as well as L</Primitives>, L</Registers>,
L</Constructors> and L</Environments>.
These define the behaviour of these control sequences when processed during the various
phases of LaTeX's imitation of TeX's digestive tract.
=head3 Prototypes
LaTeXML uses a more convenient method of specifying parameter patterns for
control sequences. The first argument to each of these defining forms
(C<DefMacro>, C<DefPrimive>, etc) is a I<prototype> consisting of the control
sequence being defined along with the specification of parameters required by the control sequence.
Each parameter describes how to parse tokens following the control sequence into
arguments or how to delimit them. To simplify coding and capture common idioms
in TeX/LaTeX programming, latexml's parameter specifications are more expressive
than TeX's C<\def> or LaTeX's C<\newcommand>. Examples of the prototypes for
familiar TeX or LaTeX control sequences are:
DefConstructor('\usepackage[]{}',...
DefPrimitive('\multiply Variable SkipKeyword:by Number',..
DefPrimitive('\newcommand OptionalMatch:* DefToken[]{}', ...
lib/LaTeXML/Package.pm view on Meta::CPAN
=item C<robust=E<gt>I<boolean>>
Makes a definition "robust", in the sense of LaTeX's C<\DeclareRobustCommand>.
This essentially creates an indirect macro definition which is preceded by C<\protect>.
This inhibits expansion (and argument processing!) under certain circumstances.
It usually only makes sense for macros, but may be useful for Primitives, Constructors
and DefMath in cases where LaTeX would normally have created a macro that needs protection.
=back
=head3 Macros
=over 4
=item C<DefMacro(I<prototype>, I<expansion>, I<%options>);>
X<DefMacro>
Defines the macro expansion for I<prototype>; a macro control sequence that is
expanded during macro expansion time in the L<LaTeXML::Core::Gullet>.
The I<expansion> should be one of I<tokens> | I<string> | I<code>($gullet,@args)>:
a I<string> will be tokenized upon first usage.
Any macro arguments will be substituted for parameter indicators (eg #1)
in the I<tokens> or tokenized I<string> and the result is used as the expansion
of the control sequence. If I<code> is used, it is called at expansion time
and should return a list of tokens as its result.
DefMacro options are
=over 4
=item C<scope=E<gt>I<scope>>,
=item C<locked=E<gt>I<boolean>>
See L</"Common Options">.
=item C<mathactive=E<gt>I<boolean>>
specifies a definition that will only be expanded in math mode;
the control sequence must be a single character.
=back
Examples:
DefMacro('\thefootnote','\arabic{footnote}');
DefMacro('\today',sub { ExplodeText(today()); });
=item C<DefMacroI(I<cs>, I<paramlist>, I<expansion>, I<%options>);>
X<DefMacroI>
Internal form of C<DefMacro> where the control sequence and parameter list
have already been separated; useful for definitions from within code.
Also, slightly more efficient for macros with no arguments (use C<undef> for
I<paramlist>), and useful for obscure cases like defining C<\begin{something*}>
as a Macro.
=back
=head3 Conditionals
=over 4
=item C<DefConditional(I<prototype>, I<test>, I<%options>);>
X<DefConditional>
lib/LaTeXML/Package.pm view on Meta::CPAN
=back
A handy method to use most of the TeX distribution's raw TeX definitions for a package,
but override only a few with LaTeXML bindings is by defining a binding file,
say C<tikz.sty.ltxml>, to contain
InputDefinitions('tikz', type => 'sty', noltxml => 1);
which would find and read in C<tizk.sty>, and then follow it by a couple of strategic
LaTeXML definitions, C<DefMacro>, etc.
=back
=head2 Class and Packages
=over
=item C<RequirePackage(I<package>, I<%options>);>
X<RequirePackage>
lib/LaTeXML/Package/AmSTeX.pool.ltxml view on Meta::CPAN
# indirectly via \input amstex
# (from TeX mode, ie. before and without LaTeX.pool being loaded)
# This should put LaTeXML into "amstex mode"
#
# Since amstex uses \documentstyle, we _must_ define it here to
# keep TeX.pool from anticipating LaTeX mode and loading LaTeX.pool!
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
RequireResource('ltx-amsart.css'); # hopefully close enough...
DefConstructorI('\AmSTeX', undef, 'AMSTeX');
DefMacro('\fmtname', 'AmS-TeX');
DefMacro('\fmtversion', '2.1');
Let('\plainfmtversion', '\fmtversion');
DefPrimitive('\define SkipSpaces Token UntilBrace {}', sub {
my ($stomach, $cs, $params, $body) = @_;
$params = parseDefParameters($cs, $params); # in TeX.pool
if (LookupDefinition($cs)) {
Info('ignore', $cs, $stomach,
"Ignoring redefinition (\\define) of '" . ToString($cs) . "'");
return; }
DefMacroI($cs, $params, $body);
return; });
DefPrimitive('\redefine SkipSpaces Token UntilBrace {}', sub {
my ($stomach, $cs, $params, $body) = @_;
$params = parseDefParameters($cs, $params); # in TeX.pool
DefMacroI($cs, $params, $body);
return; });
DefPrimitive('\predefine Token Token', sub {
Let($_[1], $_[2]); });
DefPrimitive('\undefine Token', sub {
my ($stomach, $cs) = @_;
Let($_[1], '\relax'); });
#======================================================================
lib/LaTeXML/Package/AmSTeX.pool.ltxml view on Meta::CPAN
DefConstructor('\documentstyle Semiverbatim',
"<?latexml class='#1' amstex='true'?>",
afterDigest => sub {
my ($stomach, $whatsit) = @_;
my $style = ToString($whatsit->getArg(1));
# Load the package, but note that we're pretending it's a class (to some extent!)
RequirePackage($style, type => 'sty', notex => 1, as_class => 1)
|| RequirePackage('amsppt');
return; });
DefMacro('\NoPageNumbers', '');
DefMacro('\BlackBoxes', ''); # These control whether overfull boxes show black; Ignorable
DefMacro('\NoBlackBoxes', '');
DefMacro('\TagsAsMath', '');
DefMacro('\TagsAsText', '');
DefMacro('\TagsOnLeft', '');
DefMacro('\TagsOnRight', '');
DefMacro('\CenteredTagsOnSplits', '');
DefMacro('\TopOrBottomTagsOnSplits', '');
DefMacro('\LimitsOnInts', '');
DefMacro('\NoLimitsOnInts', '');
DefMacro('\LimitsOnNames', '');
DefMacro('\NoLimitsOnNames', '');
DefMacro('\LimitsOnSums', '');
DefMacro('\NoLimitsOnSums', '');
# These presumably load fonts (or commands?)
DefMacro('\UseAMSsymbols', '');
DefMacro('\loadbold', '');
DefMacro('\loadeufb', '');
DefMacro('\loadeufm', '');
DefMacro('\loadeurb', '');
DefMacro('\loadeurm', '');
DefMacro('\loadeusb', '');
DefMacro('\loadeusm', '');
DefMacro('\loadmathfont', '');
DefMacro('\loadmsam', '');
DefMacro('\loadmsbm', '');
Let('\font@', '\font'); # Close enough?
DefMacroI('\normalfont', undef, ''); # Close enough?
DefMacro('\boldnotloaded{}', '');
DefMacro('\galleys', '');
DefMacro('\flushpar', '\par\noindent');
DefMacro('\pagewidth{Dimension}', '');
DefMacro('\pageheight{Dimension}', '');
DefMacro('\hcorrection{Dimension}', '');
DefMacro('\vcorrection{Dimension}', '');
#======================================================================
# The Document
DefConstructor('\document', "<ltx:document>",
afterDigest => sub { AssignValue(inPreamble => 0); });
DefConstructor('\enddocument', "</ltx:document>",
beforeDigest => sub {
$_[0]->getGullet->flush;
return; });
#======================================================================
# Front Matter
DefMacro('\topmatter', '');
DefMacro('\endtopmatter', '');
DefMacro('\title Until:\endtitle', '\@add@frontmatter{ltx:title}{#1}');
DefConstructor('\@personname{}', "<ltx:personname>#1</ltx:personname>",
bounded => 1, mode => 'text');
DefMacro('\author Until:\endauthor', '\@add@frontmatter{ltx:creator}[role=author]{\@personname{#1}}');
DefConstructor('\@institute{}', "<ltx:contact role='institute'>#1</ltx:contact>", bounded => 1);
DefMacro('\thanks Until:\endthanks', '\@add@to@frontmatter{ltx:creator}{\@institute{#1}}');
DefMacro('\abstract Until:\endabstract', '\@add@frontmatter{ltx:abstract}{#1}');
#======================================================================
# Document structure
# See amsppt.sty or ...
DefMacro('\nofrills', '');
DefPrimitive('\comment', sub {
my ($stomach, $line) = @_;
my $gullet = $stomach->getGullet;
$gullet->readRawLine; # IGNORE 1st line (after the \begin{$name} !!!
while (defined($line = $gullet->readRawLine) && ($line ne '\endcomment')) {
}
return; });
Let('\plainproclaim', '\proclaim');
Let('\plainfootnote', '\footnote');
RawTeX('\newbox\tocbox@');
#======================================================================
# Text level stuff
DefMacro('\newline', "\n");
DefPrimitiveI('\textfonti', undef, '',
font => { family => 'serif', series => 'medium', shape => 'upright' });
DefPrimitiveI('\textfontii', undef, '',
font => { family => 'serif', series => 'medium', shape => 'upright', size => 9 });
DefConstructor('\spreadlines {Dimension}', '');
DefPrimitive('\pagebreak', undef);
DefPrimitive('\nopagebreak', undef);
lib/LaTeXML/Package/AmSTeX.pool.ltxml view on Meta::CPAN
DefPrimitive('\allowlinebreak', undef);
DefPrimitive('\allowmathbreak', undef);
DefPrimitive('\linebreak', undef);
DefPrimitive('\nolinebreak', undef);
DefPrimitive('\mathbreak', undef);
DefPrimitive('\nomathbreak', undef);
DefPrimitive('\allowdisplaybreaks', undef);
DefPrimitive('\allowdisplaybreak', undef);
DefMacro('\tie', '\unskip\nobreak\ ');
Let('\graveaccent', "\\`");
Let('\acuteaccent', "\\'");
Let('\tildeaccent', "\\~");
Let('\hataccent', "\\^");
Let('\underscore', "\\_");
Let('\B', "\\=");
Let('\D', "\\.");
DefMacro('\.', '. ');
# instead of adding taylor's diagram.tex
# for now warn that we are aware of those diagrams, but they are not supported
# and avoid the sea of otherwise inevitable errors during drawing
DefMacro('\diagram Until:\enddiagram', sub {
Warn('missing', 'support', 'The \diagram mechanism of diagram.tex is not currently supported, output is degraded.');
return Tokenize("missing diagram")->unlist(); },
locked => 1);
#======================================================================
# Math stuff.
# We'd like to be able to leverage the ams (LaTeX) packages we've already written.
# However, they were written in the context of LaTeX, and assume LaTeX.pool was loaded.
# We either need to duplicate them, or alter them to be aware of LaTeX vs AMSTeX mode!
lib/LaTeXML/Package/AmSTeX.pool.ltxml view on Meta::CPAN
Let('\tsize', '\textstyle');
Let('\ssize', '\scriptstyle');
Let('\sssize', '\scriptscriptstyle');
Let('\tag', '\eqno');
DefMath('\and', '\&', role => 'ADDOP', meaning => 'and');
DefConstructor("\\\\",
"?#isMath(<ltx:XMHint name='newline'/>)(<ltx:break/>)",
reversion => Tokens(T_CS("\\\\"), T_CR));
# This is an analog to \align's template, but hopefully we can just ignore it???
DefMacro("\\format Until:\\\\", '');
DefConstructor('\text {}',
"<ltx:text _noautoclose='1'>#1</ltx:text>", mode => 'text');
DefConstructor('\overset Until:\to {}',
"<ltx:XMApp>"
. "<ltx:XMWrap role='OVERACCENT'>#1</ltx:XMWrap>"
. "<ltx:XMArg>#2</ltx:XMArg>"
. "</ltx:XMApp>");
DefConstructor('\underset Until:\to {}',
"<ltx:XMApp>"
. "<ltx:XMWrap role='UNDERACCENT'>#1</ltx:XMWrap>"
. "<ltx:XMArg>#2</ltx:XMArg>"
. "</ltx:XMApp>");
DefMacro('\oversetbrace Until:\to {}', '\overbrace{#2}^{#1}');
DefMacro('\undersetbrace Until:\to {}', '\underbrace{#2}^{#1}');
Let('\overarrow', '\overrightarrow');
Let('\underarrow', '\underrightarrow');
DefConstructor('\frac InFractionStyle InFractionStyle',
"<ltx:XMApp>"
. "<ltx:XMTok meaning='divide' role='FRACOP' mathstyle='#mathstyle'/>"
. "<ltx:XMArg>#1</ltx:XMArg><ltx:XMArg>#2</ltx:XMArg>"
. "</ltx:XMApp>",
sizer => sub { fracSizer($_[0]->getArg(1), $_[0]->getArg(2)); },
lib/LaTeXML/Package/AmSTeX.pool.ltxml view on Meta::CPAN
DefConstructor('\roman{}', '#1', bounded => 1, requireMath => 1,
font => { family => 'serif', series => 'medium', shape => 'upright' });
DefConstructor('\italic{}', '#1', bounded => 1, requireMath => 1,
font => { shape => 'italic', series => 'medium', shape => 'upright' });
DefConstructor('\slanted{}', '#1', bounded => 1, requireMath => 1,
font => { shape => 'slanted', series => 'medium', shape => 'upright' });
DefConstructor('\boldkey{}', '#1', bounded => 1, requireMath => 1,
font => { series => 'bold', family => 'typewriter', series => 'medium', shape => 'upright' });
# holy cow...
DefMacro('\thickfrac', sub {
($_[0]->ifNext('\thickness') ? T_CS('\@thickfrac') : T_CS('\frac')); });
DefMacro('\@thickfrac Token Number {}{}', '\genfrac{}{}{#2}{}{#3}{#4}');
DefMacro('\thickfracwithdelims{}{}', sub {
(($_[0]->ifNext('\thickness') ? T_CS('\@thickfracwithdelims') : T_CS('\fracwithdelims')), $_[1], $_[2]); });
DefMacro('\@thickfracwithdelims {}{} Token Number {}{}', '\genfrac{#1}{#2}{#4}{}{#5}{#6}');
DefMacro('\spcheck', '^{\vee}');
DefMacro('\sptilde', '^{\sim}');
DefMacro('\spacute', "^{'}");
DefMacro('\spgrave', "^{`}");
DefMacro('\spdot', "^{.}");
DefMacro('\spddot', "^{..}");
DefMacro('\spdddot', "^{...}");
DefMacro('\spddddot', "^{....}");
DefMacro('\spbreve', "^{\\hbox{\\u{}}}");
DefMacro('\spbar', "^{-}");
DefMacro('\spvec', "^{\\rightarrow}");
# \boldsymbol{}
# Note this is really messed up. \boldsymbol doesn't necessarily just expand,
# it recognizes certain arguments specially. Among other things this allows perversities like:
# \redefine\cdot{\boldsymbol\cdot}
DefMathI('\lx@ams@boldsymbol@cdot', undef, "\x{22C5}", role => 'MULOP',
bounded => 1, font => { forcebold => 1 });
DefMathI('\lx@ams@boldsymbol@prime', undef, "\x{2032}", role => 'SUPOP', locked => 1,
bounded => 1, font => { forcebold => 1 });
DefMathI('\lx@ams@boldsymbol@lbrack', undef, '[', role => 'OPEN', stretchy => 'false',
lib/LaTeXML/Package/AmSTeX.pool.ltxml view on Meta::CPAN
DefMathI('\lx@ams@boldsymbol@P', undef, UTF(0xB6),
bounded => 1, font => { forcebold => 1 });
DefMathI('\lx@ams@boldsymbol@dag', undef, "\x{2020}",
bounded => 1, font => { forcebold => 1 });
DefMathI('\lx@ams@boldsymbol@ddag', undef, "\x{2021}",
bounded => 1, font => { forcebold => 1 });
DefConstructor('\lx@ams@boldsymbol@{}', '#1',
bounded => 1, requireMath => 1, font => { forcebold => 1 });
DefMacro('\boldsymbol DefToken', sub {
my ($gullet, $token) = @_;
my $name = ToString($token); $name =~ s/^\\//;
my $btoken = T_CS('\lx@ams@boldsymbol@' . $name);
return (IsDefined($btoken) ? ($btoken) : (T_CS('\lx@ams@boldsymbol@'), $token)); });
# Ignore these?
DefRegister('\buffer' => Dimension(0));
DefMacro('\ChangeBuffer Dimension', '\buffer#2\relax');
DefMacro('\ResetBuffer', '');
DefMacro('\shave{}', '#1');
DefMacro('\botshave{}', '#1');
DefMacro('\topshave{}', '#1');
DefMacro('\minCDarrowwidth Dimension', '');
DefMacro('\pretend Until:\haswidth {}', '#1');
DefMacro('\snug', '');
DefConstructor('\topsmash{}', "#1");
DefConstructor('\botsmash{}', "#1");
DefConstructor('\spreadmatrixlines Dimension', '');
DefMacro('\MultlineGap Dimension', '');
DefMacro('\multlinegap Dimension', '');
DefMacro('\nomultlinegap', '');
DefMacro('\innerhdotsfor Number Match:\after {}', sub {
(map { '\hdots' } 1 .. $_[1]->valueOf); });
DefMacro('\spacehdots Number Match:\for Number', sub {
(map { '\hdots' } 1 .. $_[1]->valueOf); });
DefMacro('\spaceinnerhdots Number Match:\for Number Match:\after {}', sub {
(map { '\hdots' } 1 .. $_[1]->valueOf); });
DefMacro('\foldedtext', sub {
my ($gullet) = @_;
if ($gullet->ifNext('\foldedwidth')) {
$gullet->readToken; $gullet->readDimension; } # ignore?
T_CS('\text'); });
Let('\topfoldedtext', '\foldedtext');
Let('\botfoldedtext', '\foldedtext');
# Maybe? Nope! Closer to \over
#DefMacro('\Sb Until:\endSb', '_{\substack{#1}}');
#DefMacro('\Sp Until:\endSp', '^{\substack{#1}}');
# see use in arXiv:cond-mat/0003158
DefMacro('\Sb', '\lx@generalized@over{\Sb}{meaning=substack}');
DefMacro('\Sp', '\lx@generalized@over{\Sp}{meaning=superstack}');
Let('\endSb', '\relax');
Let('\endSp', '\relax');
DefMacro('\thetag', sub { T_OTHER(LookupValue('EQUATIONROW_NUMBER')); }); # ?
DefMacro('\topaligned', '\aligned[t]');
Let('\endtopaligned', '\endaligned');
DefMacro('\botaligned', '\aligned[b]');
Let('\endbotaligned', '\endaligned');
# close enough?
DefMacro('\accentedsymbol{}{}', '\def#1{#2}');
# Tricky:
# \cfrac, \lcfrac, \endcfrac
DefConstructor('\cfrac', '',
afterDigest => sub {
my ($stomach) = @_;
$stomach->bgroup;
Let(T_CS("\\\\"), T_CS('\lx@cfrac')); });
DefConstructor('\endcfrac', '',
afterDigest => sub {
my ($stomach) = @_;
$stomach->egroup; });
# These really need a way to pass denomalign=left|right to the MathML!
Let('\lcfrac', '\cfrac');
Let('\rcfrac', '\cfrac');
DefMacro('\lx@cfrac',
'\lx@generalized@over{\\\\}{meaning=continued-fraction,role=MULOP}\displaystyle');
#======================================================================
# Bibliography
# See amsppt.sty
#======================================================================
# Dubious
RawTeX(<<'EoTeX');
\def\vspace@{\def\vspace##1{\crcr\noalign{\vskip##1\relax}}}
lib/LaTeXML/Package/AmSTeX.pool.ltxml view on Meta::CPAN
\newdimen\ltwidth@
\newdimen\rtwidth@
\newdimen\accentdimen@
\newdimen\minaw@
\newdimen\minCDaw@
\newdimen\bigaw@
\newdimen\pmbraise@
\newtoks\hashtoks@
EoTeX
DefMacro('\printoptions', '');
DefMacro('\showallocations', '');
DefMacro('\syntax', '');
1;
lib/LaTeXML/Package/BibTeX.pool.ltxml view on Meta::CPAN
# the given field, or you may use it to test for the presence
# of some other field.
# BUT: be careful, it looks up from a hash, and so doesn't work
# correctly when there are multiple values for a given field!!!
# [This may need to be revisited]
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Build a sequence of commands that will process the
# entry and its fields, depending on what sorts of
# aliases and commands have been defined.
DefMacro('\ProcessBibTeXEntry Semiverbatim',
'\bibentry@prepare{#1}\bibentry@create{#1}');
DefPrimitive('\bibentry@prepare Semiverbatim', sub {
my ($stomach, $key) = @_;
$key = NormalizeBibKey($key);
my $entry = LookupValue('BIBENTRY@' . $key);
my $origtype = $entry->getType;
my $type = $origtype;
my $alias_defn = T_CS('\bib@entry@' . $type . '@alias');
lib/LaTeXML/Package/BibTeX.pool.ltxml view on Meta::CPAN
'bib@entry@default@complete') {
push(@tex, join('', '\csname ', $completer, '\endcsname')); }
my $tex = join("\n", @tex, '\end{bib@entry}');
$stomach->getGullet->openMouth(LaTeXML::Core::Mouth->new($tex));
(); });
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Processing Entries
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Math ID's within the bibliography.
DefMacro('\the@XMARG@ID', '\thebibliography@ID.XM\arabic{@XMARG}');
DefEnvironment('{bibtex@bibliography}',
"<ltx:bibliography xml:id='#id' "
. "bibstyle='#bibstyle' citestyle='#citestyle' sort='#sort'>"
. "<ltx:title font='#titlefont' _force_font='1'>#title</ltx:title>"
. "<ltx:biblist>#body</ltx:biblist>"
. "</ltx:bibliography>",
beforeDigest => sub {
beforeDigestBibliography(); },
afterDigestBegin => sub { beginBibliography($_[1]); });
lib/LaTeXML/Package/BibTeX.pool.ltxml view on Meta::CPAN
sub currentBibEntryField {
my ($field) = @_;
return currentBibEntry()->getField($field); }
sub currentBibEntryRawField {
my ($field) = @_;
return currentBibEntry()->getRawField($field); }
#======================================================================
DefMacro('\bib@entry@default@prepare', sub {
copyCrossrefFields(qw(date year month day)); });
DefMacro('\bib@entry@default@complete',
'\bib@synthesize@mr\bib@synthesize@zbl\bib@@origbibentry');
sub copyCrossrefFields {
my (@fields) = @_;
my $entry = currentBibEntry();
if (my $xref = $entry->getField('crossref')) {
if (my $xentry = LookupValue('BIBENTRY@' . NormalizeBibKey($xref))) {
foreach my $field (@fields) {
if (!defined $entry->getField($field)) {
if (my $value = $xentry->getField($field)) {
lib/LaTeXML/Package/BibTeX.pool.ltxml view on Meta::CPAN
} } }
return; }
#======================================================================
# Supporters
DefConstructor('\bib@@field {} OptionalKeyVals Digested', sub {
my ($document, $tag, $attr, $content) = @_;
$document->insertElement(ToString($tag), $content, ($attr ? $attr->getHash : ())); });
# Hmm, should this be something like an "add default field value"?
DefMacro('\bib@addtype{}', sub {
my ($gullet, $type) = @_;
if (currentBibEntryField('type')) {
(); }
else {
Invocation(T_CS('\bib@field@default@type'), $type)->unlist; } });
sub bibAddToContainer {
my ($document, $tag, $data, %attr) = @_;
my $currentnode = $document->getNode;
my $entry = $document->findnode('ancestor-or-self::ltx:bibentry | ancestor-or-self::ltx:bib-related',
lib/LaTeXML/Package/BibTeX.pool.ltxml view on Meta::CPAN
DefConstructor('\bib@addto@related {}{} Digested', sub {
my ($document, $type, $role, $data) = @_;
bibAddToContainer($document, 'ltx:bib-related', $data, type => $type, role => $role); });
# author : The name(s) of the author(s); this gets NameList treatment
DefConstructor('\bib@@@name{}{}',
"<ltx:bib-name role='#1'>#2</ltx:bib-name>");
# This contructor merely serves to collect a set of names into one Whatsit
# so that \bib@addto@related can capture it.
DefConstructor('\bib@@@names{}', "#1");
DefMacro('\bib@@names{}{}', sub {
## my ($gullet, $field, $ignore) = @_;
my ($gullet, $field, $names) = @_;
(T_CS('\bib@@@names'), T_BEGIN,
(map { Invocation(T_CS('\bib@@@name'), $field, $_) }
## processBibNameList(currentBibEntryField(ToString($field)))),
processBibNameList(UnTeX($names))),
T_END); });
# Now, we define
# \bib@@title
lib/LaTeXML/Package/BibTeX.pool.ltxml view on Meta::CPAN
# Setting BibTeX_title_case to one of the following chooses.
# (the default, like most BibTeX styles, is capitalize1)
# Cases:
# * asis : leave title as is
# * capitalize1 : downcase all, then Capitalize 1st word only
# * capitalize : downcase, then capitalize ALL words (?)
# (but really would ignore articles, prepositions...?)
# * uppercase : convert to uppercase.
# * lowercase : convert to lowercase.
DefMacro('\bib@@title{}{}{}', sub {
my ($gullet, $field, $tag, $ignoretitle) = @_;
my $title = currentBibEntryField(ToString($field)); # Get it in raw string form.
my $mode = LookupValue('BibTeX_title_case') || 'capitalize1';
my $recap = '';
my ($wb, $wc) = (1, 0);
while ($title ne "") {
if ($title =~ s/^(\s+)//) {
$recap .= $1; $wb = 1; }
elsif ($title =~ s/^((?:\w|\\(?:\w+|.))+)//) {
if ($mode eq 'asis') {
lib/LaTeXML/Package/BibTeX.pool.ltxml view on Meta::CPAN
if (!defined $t) {
Error('expected', '$', $gullet, "Expected balancing \$ in bibliographic title");
$title =~ s/^\$//; }
else {
$recap .= $t; $wb = 0; } }
elsif ($title =~ s/^(.)//) {
$recap .= $1; $wb = 1; } }
Invocation(T_CS('\bib@@field'), $tag, undef, Tokenize($recap)); });
# I'd thought booktitle were treated like title, but I think I was mistaken.
#DefMacro('\bib@@booktitle{}{}', '\bib@@title{booktitle}{#1}{#2}');
DefMacro('\bib@@booktitle{}{}', '\bib@@field{#1}{#2}');
#======================================================================
# Default field handlers
# This ignores the field.
DefMacro('\bib@field@@ignore Verbatim Verbatim', '');
# By default, we'll copy unrecognized fields to bib-data,
DefMacro('\bib@field@default@default Verbatim Verbatim', '\bib@field@unknownasdata{#1}'); # IGNORE the tokenized data.
DefConstructor('\bib@field@unknownasdata Verbatim',
"<ltx:bib-data role='#1'>#rawdata</ltx:bib-data>",
afterDigest => sub {
my $field = ToString($_[1]->getArg(1));
$_[1]->setProperty(rawdata => currentBibEntryField($field)); });
# OTOH, if you'd like to simply ignore them, do this:
# Let('\bib@field@default@default','\bib@field@@ignore');
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# The Standard BibTeX Entries
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#======================================================================
# Article
# required: author,title,journal, year
# optional: volume,number,pages,month,note
# An article gets a related item for the Journal.
DefMacro('\bib@entry@article@prepare', sub { copyCrossrefFields(qw(author title journal)); });
# journal : the journal that an article is part of
DefMacro('\bib@field@article@journal',
'\bib@addto@related{journal}{host}\bib@@field{ltx:bib-title}');
#======================================================================
# Book
# required: author or editor, title, publisher, year
# optional: volume or number, series, address, edition, month, note
DefMacro('\bib@entry@book@prepare', sub { copyCrossrefFields(qw(author editor title publisher)); });
#======================================================================
# Booklet
# required: title
# optional: author, howpublished, address, month, year, note
DefMacro('\bib@entry@booklet@prepare', sub { copyCrossrefFields(qw(title)); });
#======================================================================
# conference
DefMacro('\bib@entry@conference@alias', 'inproceedings');
#======================================================================
# inbook
# required: author or editor, title, chapter and/or pages, publisher, year
# optional: volume or number, series, type, address, edition, month, note
# inbook gets a related item for the book, with fields:
# editor, publisher, booktitle, volume or number, series, address, edition.
DefMacro('\bib@entry@inbook@prepare', sub {
copyCrossrefFields(qw(author editor title chapter pages publisher)); });
DefMacro('\bib@field@inbook@booktitle',
'\bib@addto@related{book}{host}\bib@@booktitle{ltx:bib-title}');
DefMacro('\bib@field@inbook@editor',
'\bib@addto@related{book}{host}\bib@@names{editor}');
DefMacro('\bib@field@inbook@publisher',
'\bib@addto@related{book}{host}\bib@@field{ltx:bib-publisher}');
DefMacro('\bib@field@inbook@number',
'\bib@addto@related{book}{host}\bib@@field{ltx:bib-part}[role=number]');
DefMacro('\bib@field@inbook@volume',
'\bib@addto@related{book}{host}\bib@@field{ltx:bib-part}[role=volume]');
DefMacro('\bib@field@inbook@series',
'\bib@addto@related{book}{host}\bib@@field{ltx:bib-part}[role=series]');
DefMacro('\bib@field@inbook@address',
'\bib@addto@related{book}{host}\bib@@field{ltx:bib-place}');
DefMacro('\bib@field@inbook@edition',
'\bib@addto@related{book}{host}\bib@@field{ltx:bib-edition}');
#======================================================================
# incollection
# required: author, title, booktitle, publisher, year
# optional: editor, volume or number, series, type, chapter, pages,
# address, edition, month, note.
# incollection gets a related item book, with fields:
# booktitle, publisher, editor, volume or number, series, address, edition
DefMacro('\bib@entry@incollection@prepare', sub {
copyCrossrefFields(qw(author title booktitle publisher)); });
DefMacro('\bib@field@incollection@booktitle',
'\bib@addto@related{book}{host}\bib@@booktitle{ltx:bib-title}');
DefMacro('\bib@field@incollection@editor',
'\bib@addto@related{book}{host}\bib@@names{editor}');
DefMacro('\bib@field@incollection@publisher',
'\bib@addto@related{book}{host}\bib@@field{ltx:bib-publisher}');
DefMacro('\bib@field@incollection@number',
'\bib@addto@related{book}{host}\bib@@field{ltx:bib-part}[role=number]');
DefMacro('\bib@field@incollection@volume',
'\bib@addto@related{book}{host}\bib@@field{ltx:bib-part}[role=volume]');
DefMacro('\bib@field@incollection@series',
'\bib@addto@related{book}{host}\bib@@field{ltx:bib-part}[role=series]');
DefMacro('\bib@field@incollection@address',
'\bib@addto@related{book}{host}\bib@@field{ltx:bib-place}');
DefMacro('\bib@field@incollection@edition',
'\bib@addto@related{book}{host}\bib@@field{ltx:bib-edition}');
#======================================================================
# inproceedings
# required: author, title, booktitle, year
# optional: editor, volume or number, series, pages, address, month,
# organization, publisher, note.
# inproceedings gets a related item proceedings, with fields:
# booktitle, editor,volume or number, series, address, organization, publisher
DefMacro('\bib@entry@inproceedings@prepare', sub {
copyCrossrefFields(qw(author title booktitle publisher)); });
DefMacro('\bib@field@inproceedings@booktitle',
'\bib@addto@related{proceedings}{host}\bib@@booktitle{ltx:bib-title}');
DefMacro('\bib@field@inproceedings@editor',
'\bib@addto@related{proceedings}{host}\bib@@names{editor}');
DefMacro('\bib@field@inproceedings@number',
'\bib@addto@related{proceedings}{host}\bib@@field{ltx:bib-part}[role=number]');
DefMacro('\bib@field@inproceedings@volume',
'\bib@addto@related{proceedings}{host}\bib@@field{ltx:bib-part}[role=volume]');
DefMacro('\bib@field@inproceedings@series',
'\bib@addto@related{proceedings}{host}\bib@@field{ltx:bib-part}[role=series]');
DefMacro('\bib@field@inproceedings@organization',
'\bib@addto@related{proceedings}{host}\bib@@field{ltx:bib-organization}');
DefMacro('\bib@field@inproceedings@publisher',
'\bib@addto@related{proceedings}{host}\bib@@field{ltx:bib-publisher}');
DefMacro('\bib@field@inproceedings@conference',
'\bib@addto@related{conference}{event}\bib@@field{ltx:bib-title}');
DefMacro('\bib@field@inproceedings@meeting',
'\bib@addto@related{conference}{event}\bib@@field{ltx:bib-title}');
DefMacro('\bib@field@inproceedings@location',
'\bib@addto@related{conference}{event}\bib@@field{ltx:bib-place}');
DefMacro('\bib@field@inproceedings@place',
'\bib@addto@related{conference}{event}\bib@@field{ltx:bib-place}');
#======================================================================
# manual
# required: title,
# optional: author, organization, address, edition, month, yeaer, note.
DefMacro('\bib@entry@manual@prepare', sub { copyCrossrefFields(qw(title)); });
#======================================================================
# mastersthesis
# required: author, title, school, year,
# optional: type, address, month, note
DefMacro('\bib@entry@thesis@prepare', sub { copyCrossrefFields(qw(author title school)); });
DefMacro('\bib@entry@mastersthesis@alias', 'thesis');
DefMacro('\bib@entry@mastersthesis@complete', '\bib@addtype{Master\'s Thesis}');
#======================================================================
# misc
# required: none
# optional: author, title, howpublished, month, year, note
#======================================================================
# phdthesis
# required: author, title, school, year,
# optional: type, address, month, note.
DefMacro('\bib@entry@phdthesis@alias', 'thesis');
DefMacro('\bib@entry@phdthesis@complete', '\bib@addtype{Ph.D. Thesis}');
#======================================================================
# proceedings
# required: title, year
# optional: editor, volume or number, series, address, month,
# organization, publisher, note
DefMacro('\bib@entry@proceedings@prepare', sub { copyCrossrefFields(qw(title)); });
DefMacro('\bib@field@proceedings@booktitle', sub {
my ($gullet) = @_;
if (currentBibEntryField('title')) { # Already have a title.
$gullet->readArg;
(); }
else { # Else use this as the title.
(TokenizeInternal('\bib@@field{ltx:bib-title}')->unlist); } });
#======================================================================
# techreport
# required: author, title, institution, year
# optional: type, number, address, month, note.
DefMacro('\bib@entry@techreport@alias', 'report');
DefMacro('\bib@entry@report@prepare', sub { copyCrossrefFields(qw(author title institution)); });
DefMacro('\bib@entry@techreport@complete', '\bib@addtype{Technical report}');
#======================================================================
# unpublished
# required: author, title, note
# optional: month, year
DefMacro('\bib@entry@unpublished@prepare', sub { copyCrossrefFields(qw(author title)); });
#======================================================================
# Common non-standard entry types.
DefMacro('\bib@entry@online@alias', 'website');
DefMacro('\bib@entry@electronic@alias', 'website');
DefMacro('\bib@entry@www@alias', 'website');
DefMacro('\bib@entry@webpage@alias', 'website');
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Processing Fields
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Default handlers
#======================================================================
# Agents...
# author : The name(s) of the author(s); this gets NameList treatment
DefMacro('\bib@field@default@author',
'\bib@@names{author}');
# editor : The name(s) of the editor(s); this gets NameList treatment
DefMacro('\bib@field@default@editor',
'\bib@@names{editor}');
# translator : The names(s) of any translator(s); this gets NameList treatment
DefMacro('\bib@field@default@translator',
'\bib@@names{translator}');
#======================================================================
# Titles
# title : the title of the work.
DefMacro('\bib@field@default@title',
'\bib@@title{title}{ltx:bib-title}');
DefMacro('\bib@field@default@subtitle',
'\bib@@field{ltx:bib-subtitle}');
#======================================================================
# Origin info.
# date : iso formatted yyy-mm-dd
# year (& month, day) fields can generate this element, as well.
DefMacro('\bib@field@default@date',
'\bib@@field{ltx:bib-date}[role=publication]');
# edition : the edition of a book
DefMacro('\bib@field@default@edition',
'\bib@@field{ltx:bib-edition}');
# address : Publisher's address
DefMacro('\bib@field@default@address',
'\bib@@field{ltx:bib-place}');
# publisher : the name of the publisher
DefMacro('\bib@field@default@publisher',
'\bib@@field{ltx:bib-publisher}');
# institution : an institution involved in publishing, (distinct from publisher?)
DefMacro('\bib@field@default@institution',
'\bib@@field{ltx:bib-organization}');
# organization : a conference sponsor
DefMacro('\bib@field@default@organization',
'\bib@@field{ltx:bib-organization}');
# school : The school where a thesis was written; analogous to institution
DefMacro('\bib@field@default@school',
'\bib@@field{ltx:bib-organization}');
DefMacro('\bib@field@default@status',
'\bib@@field{ltx:bib-status}');
# year : the year of publication.
# Try to synthesize an ISO date, if at all possible.
# Note that the raw month may be a standard abbreviation which is most safely translated to the number,
# otherwise the field may end up
# Note that month and day do not directly contribute entries;
# year incorporates them if found.
our %months = ( # Standard abbreviations (usually would appear in raw form of month field).
jan => "1", feb => "2", mar => "3", apr => "4", may => "5", jun => "6",
jul => "7", aug => "8", sep => "9", oct => "10", nov => "11", dec => "12",
# English month names, perhaps in expanded form of month field
january => "1", february => "2", march => "3", april => "4", may => "5", june => "6",
july => "7", august => "8", september => "9", october => "10", november => "11", december => "12");
# Is there any sane way of looking up month names from other languages; maybe something from babel?
DefMacro('\bib@field@default@year {}', sub {
if (currentBibEntryField('date')) {
(); } # Ignore this, if we've already been given a date field.
else {
my $date = currentBibEntryField('year');
my $x;
my $month;
if (($x = currentBibEntryRawField('month')) && ($x = $months{ lc($x) })) { $month = $x; }
elsif ($x = currentBibEntryField('month')) { $month = $months{ lc($x) } || $x; }
my $day = currentBibEntryField('day');
# What if month or day is given, but not year ???
if (defined $month) {
$date .= '-' . ($month =~ /^\d$/ ? '0' . $month : $month);
if (defined $day) {
$date .= '-' . ($day =~ /^\d$/ ? '0' . $day : $day); } }
(T_CS('\bib@field@default@date'), T_BEGIN, Tokenize($date)->unlist, T_END); } });
# howpublished : if something non-standard
DefMacro('\bib@field@default@howpublished',
'\bib@@field{ltx:bib-note}[role=publication]');
#======================================================================
# Part info.
# chapter : the chapter number (of a book, presumably inbook or similar)
DefMacro('\bib@field@default@chapter',
'\bib@@field{ltx:bib-part}[role=chapter]');
# number : the number of a journal, magazine, or whatever
DefMacro('\bib@field@default@number',
'\bib@@field{ltx:bib-part}[role=number]');
# volume : the volume of a journal or multi-volume work
DefMacro('\bib@field@default@volume',
'\bib@@field{ltx:bib-part}[role=volume]');
DefMacro('\bib@field@default@part',
'\bib@@field{ltx:bib-part}[role=part]');
# series : the series of books a book was published in.
DefMacro('\bib@field@default@series',
'\bib@@field{ltx:bib-part}[role=series]');
# pages : the page or page range
DefMacro('\bib@field@default@pages',
'\bib@@field{ltx:bib-part}[role=pages]\bib@@pages');
DefConstructor('\bib@@pages{}', "#pages",
afterDigest => sub {
my $pages = currentBibEntryField('pages');
$pages =~ s/-+/--/g; # Force - to -- (ligature will turn into endash
$_[1]->setProperty(pages => Digest(Tokenize($pages))); });
#======================================================================
# The Standard BibTeX Fields
# annote : annotations; I'll assume annote is equivalent to note.
DefMacro('\bib@field@default@annote',
'\bib@@field{ltx:bib-note}[role=annotation]');
# crossref : the key of a cross-referenced entry
DefConstructor('\bib@field@default@crossref Semiverbatim', sub {
my ($document, $key) = @_;
bibAddToContainer($document, 'ltx:bib-related', undef, role => 'host', bibrefs => CleanBibKey($key)); });
# key : a normally hidden field for ordering
DefConstructor('\bib@field@default@key Digested',
"<ltx:bib-key>#1</ltx:bib-key>");
# note : miscellaneous annotation
DefMacro('\bib@field@default@note',
'\bib@@field{ltx:bib-note}[role=annotation]');
# type : the type of a report
DefConstructor('\bib@field@default@type Digested',
"<ltx:bib-type>#1</ltx:bib-type>");
#======================================================================
# Non-Standard but Common (?) fields.
# affiliation : the author's affiliation
# IMPLEMENT THIS!
# Seems like this should be tucked into author (or editor...)?
# abstract : a copy of the abstract
DefMacro('\bib@field@default@abstract',
'\bib@@field{ltx:bib-extract}[role=abstract]');
# archive : specifies where this is archived (URL?)
DefMacro('\bib@field@default@archive',
'\bib@@field{ltx:bib-links}'); # add text? or role?
# contents : a table of contents
DefMacro('\bib@field@default@contents',
'\bib@@field{ltx:bib-extract}[role=contents]');
# copyright : copyright information
DefMacro('\bib@field@default@copyright',
'\bib@@field{ltx:bib-date}[role=copyright]');
# eprint : specifies an electronic publication; Is this a URL?
DefMacro('\bib@field@default@eprint',
'\bib@@field{ltx:bib-links}'); # add text? or role?
# preprint : specifies an electronic publication (not a URL).
DefMacro('\bib@field@default@preprint',
'\bib@@field{ltx:bib-links}'); # add text? or role?
# keywords : a list of subject keywords
DefMacro('\bib@field@default@keywords',
'\bib@@field{ltx:bib-extract}[role=keywords]');
# language : the language a document is in.
DefMacro('\bib@field@default@language',
'\bib@@field{ltx:bib-language}');
# url : specifies a URL where the work can be found.
DefConstructor('\bib@field@default@url Verbatim',
"<ltx:bib-url href='#1'>Link</ltx:bib-url>");
# enote : miscellaneous annotation
DefMacro('\bib@field@default@enote',
'\bib@@field{ltx:bib-note}[role=electronic-annotation]');
#======================================================================
# Interesting Identifiers
# doi : Document Object Identifier
DefConstructor('\bib@field@default@doi Semiverbatim',
"<ltx:bib-identifier scheme='doi' id='#1' href='#href'>Document</ltx:bib-identifier>",
properties => sub {
my $id = processIdentifier($_[1]);
# doi's can have all sorts of screwy characters which must be encoded in urls
lib/LaTeXML/Package/BibTeX.pool.ltxml view on Meta::CPAN
DefConstructor('\bib@field@default@review Digested',
"<ltx:bib-review>Review #1</ltx:bib-review>");
# mrnumber is a common non-standard field
# mrreviewer isn't
# zblno, zblreviewer are analogous, but not common.
#
# I'm synthesize 1 field from mrrnumber & mrreviewer (as done in DLMF)
# Similarly for zblno & zblreviewer.
DefMacro('\bib@synthesize@mr', sub {
my $mrnumber = currentBibEntryField('mrnumber');
my $mrreviewer = currentBibEntryField('mrreviewer');
if ($mrnumber || $mrreviewer) {
Invocation(T_CS('\bib@@mr'), Tokenize($mrnumber),
($mrreviewer ? Tokenize($mrreviewer) : Tokens())); }
else {
(); } });
DefConstructor('\bib@@mr {}{}',
"?#isreview"
lib/LaTeXML/Package/BibTeX.pool.ltxml view on Meta::CPAN
properties => sub {
my $id = ToString($_[1]);
$id =~ s/^\s+//; $id =~ s/\s+$//;
my $reviewer = $_[2];
my $isreview = ToString($reviewer) ne '';
if ($id =~ /^\s*(?:MR)?(\d+)\s+\(.*\)\s*$/) { # If extra number, there's a review
$id = $1; $isreview = 1; }
my $href = "https://www.ams.org/mathscinet-getitem?mr=" . $id;
(isreview => $isreview, id => $id, href => $href, reviewer => $reviewer); });
DefMacro('\bib@synthesize@zbl', sub {
my $zblno = currentBibEntryField('zblno');
my $zblreviewer = currentBibEntryField('zblreviewer');
if ($zblno || $zblreviewer) {
Invocation(T_CS('\bib@@zbl'), Tokenize($zblno),
($zblreviewer ? Tokenize($zblreviewer) : Tokens())); }
else {
(); } });
DefConstructor('\bib@@zbl {}{}',
"?#reviewer"
lib/LaTeXML/Package/IEEEtran.cls.ltxml view on Meta::CPAN
DeclareOption(undef, sub {
PassOptions('article', 'cls', ToString(Expand(T_CS('\CurrentOption')))); });
ProcessOptions();
LoadClass('article');
#RequirePackage('multicol');
#RequirePackage('inst_support');
# This seems to be just to save stuff so that \maketitle can format it?
DefMacro('\IEEEtitleabstractindextext{}', '#1');
DefMacro('\IEEEdisplaynontitleabstractindextext', '');
DefMacro('\IEEEdisplaynotcompsoctitleabstractindextext', '');
DefMacro('\IEEEcompsoctitleabstractindextext', '');
Let('\IEEEpeerreviewmaketitle', '\maketitle');
DefMacro('\IEEEoverridecommandlockouts', '');
# V1.7 and later no longer supports \overrideIEEEmargins
DefMacro('\overrideIEEEmargins', '');
DefMacro('\IEEEaftertitletext{}', ''); # ?
DefMacro('\IEEEspecialpapernotice{}', ''); # ?
DefMacro('\IEEEmembership{}', ''); # nothing for now.
DefMacro('\IEEEauthorblockN{}', '#1'); # author
DefConstructor('\@@@affiliation{}', "^ <ltx:contact role='affiliation'>#1</ltx:contact>");
DefMacro('\IEEEauthorblockA{}', '\@add@to@frontmatter{ltx:creator}{\@@@affiliation{#1}}');
DefMacro(T_CS('\begin{IEEEkeywords}'), '\@IEEEkeywords');
DefMacro(T_CS('\end{IEEEkeywords}'), '\@endIEEEkeywords');
Let('\@endIEEEkeywords', '\relax'); # stub
DefMacro('\@IEEEkeywords XUntil:\@endIEEEkeywords', '\@add@frontmatter{ltx:keywords}[name={\IEEEkeywordsname}]{#1}');
DefMacro('\IEEEraisesectionheading{}', '#1');
DefMacro('\IEEEPARstart{}{}', '#1#2'); # Eventually, dropcap?
DefMacro('\IEEEcompsocitemizethanks{}', '\thanks{#1}');
DefMacro('\IEEEcompsocthanksitem[]', '');
DefMacro('\IEEEauthorrefmark', '');
DefMacro('\IEEEtriggeratref{}', '');
DefMacro('\IEEEpubid{}', '\@add@frontmatter{ltx:note}[role=publicationid]{pubid: #1}');
DefMacro('\IEEEpubidadjcol', '');
RawTeX(<<'EoTeX');
\ifCLASSOPTIONcompsoc
% compsoc is all arabic
\def\thesection{\arabic{section}}
\def\thesubsection{\thesection.\arabic{subsection}}
\def\thesubsubsection{\thesubsection.\arabic{subsubsection}}
\def\theparagraph{\thesubsubsection.\arabic{paragraph}}
\else
\def\thesection{\Roman{section}} % I
lib/LaTeXML/Package/IEEEtran.cls.ltxml view on Meta::CPAN
% V1.7 use I-A1 format used by the IEEE rather than I-A.1
\def\thesubsubsection{\thesubsection\arabic{subsubsection}} % I-A1
\def\theparagraph{\thesubsubsection\alph{paragraph}} % I-A1a
\fi
EoTeX
DefPrimitiveI('\ltx@ieeetran@it', undef, undef,
font => { shape => 'italic', family => 'serif', series => 'medium' }, locked => 1);
DefPrimitiveI('\ltx@ieeetran@sc', undef, undef,
font => { shape => 'smallcaps', family => 'serif', series => 'medium' }, locked => 1);
DefMacro('\format@title@font@section', '\ltx@ieeetran@sc');
DefMacro('\format@title@font@subsection', '\ltx@ieeetran@it');
DefMacro('\figurename', 'Fig.');
DefMacro('\tablename', 'TABLE');
DefMacro('\thetable', '\Roman{table}');
DefConstructor('\IEEEQEDclosed',
"?#isMath(<ltx:XMTok role='PUNCT'>\x{220E}</ltx:XMTok>)(\x{220E})");
Let('\IEEEQEDopen', '\IEEEQEDclosed');
Let('\IEEEQED', '\IEEEQEDclosed');
DefMacro('\IEEEQEDhere', sub {
my $t = PopValue('QED@stack');
PushValue('QED@stack', Tokens());
$t || (); });
# Apparently no title...
DefEnvironment('{IEEEproof} OptionalUndigested',
"<ltx:proof class='#class'>"
. "<ltx:title font='#titlefont' _force_font='true' class='#titleclass'>#title</ltx:title>"
. "#body",
# beforeDigest => sub {
lib/LaTeXML/Package/IEEEtran.cls.ltxml view on Meta::CPAN
my $tags = LookupValue('EQUATIONROW_TAGS');
if ($_[1]) {
$$numbering{counter} = 'equation'; }
else {
$$tags{counter} = 'equation'; }
return; });
# TODO: The argument is a column specification, like rCl
# We really should parse that and set up the column spec apppropriately,
# but it's different from the standard set of specs!
DefMacroI(T_CS('\IEEEeqnarray'), '{}', '\eqnarray');
Let(T_CS('\endIEEEeqnarray'), T_CS('\endeqnarray'));
DefMacroI(T_CS('\IEEEeqnarray*'), '{}', T_CS('\eqnarray*'));
Let(T_CS('\endIEEEeqnarray*'), T_CS('\endeqnarray*'));
# Let's try to treat \IEEEeqnarraybox as a variant of \array
# Note that the documentation suggests that IEEEeqnarraybox can be used INSIDE math for
# things like cases statements! Argh!!!
DefColumnType('L', sub {
$LaTeXML::BUILD_TEMPLATE->addColumn(after => Tokens(T_CS('\hfil'))); return; });
DefColumnType('C', sub {
$LaTeXML::BUILD_TEMPLATE->addColumn(before => Tokens(T_CS('\hfil')),
after => Tokens(T_CS('\hfil'))); return; });
DefColumnType('R', sub {
$LaTeXML::BUILD_TEMPLATE->addColumn(before => Tokens(T_CS('\hfil'))); return; });
DefMacro('\IEEEeqnarraybox',
'\ifmmode\def\@tempa{\let\endIEEEeqnarraybox\endIEEEeqnarrayboxm\IEEEeqnarrayboxm}'
. '\else\def\@tempa{\let\endIEEEeqnarraybox\endIEEEeqnarrayboxt\IEEEeqnarrayboxt}\fi'
. '\@tempa');
DefMacro('\IEEEeqnarrayboxm OptionalMatch:* {}',
'\@array@bindings{#2}\@@IEEE@array{#2}\@start@alignment');
DefMacroI('\endIEEEeqnarrayboxm', undef,
'\@finish@alignment\@end@array');
DefMacro('\IEEEeqnarrayboxt OptionalMatch:* {}',
'\@@BEGININLINEMATH\@array@bindings{#2}\@@IEEE@array{#2}\@start@alignment');
DefMacroI('\endIEEEeqnarrayboxt', undef,
'\@finish@alignment\@end@array\@@ENDINLINEMATH');
DefConstructor('\@@IEEE@array[] Undigested DigestedBody',
'#3',
beforeDigest => sub { $_[0]->bgroup; },
reversion => '\begin{IEEEeqnarraybox}[#1]{#2}#3\end{IEEEeqnarraybox}');
DefMacro('\IEEEeqnarraynumspace', '');
Let(T_CS('\appendices'), T_CS('\appendix'));
$$LaTeXML::Package::Pool::BIBSTYLES{IEEEtran} = { citestyle => 'numbers', sort => 'true' };
DefMacro('\IEEEsetlabelwidth{}', '\settowidth{\labelwidth}{#1}');
DefMacro('\IEEEusemathlabelsep', '');
DefMacro('\IEEEtriggercmd{}', '');
DefMacro('\IEEElabelindent', '');
DefMacro('\IEEEcalcleftmargin{}', '');
DefMacro('\IEEEiedlabeljustifyc', '');
DefMacro('\IEEEiedlabeljustifyl', '');
DefMacro('\IEEEiedlabeljustifyr', '');
# TODO: Use the optional argument.
# also, we skip the internal @-named variants for now.
DefEnvironment('{IEEEitemize}[]',
"<ltx:itemize xml:id='#id'>#body</ltx:itemize>",
properties => sub { beginItemize('itemize', '@item'); },
beforeDigestEnd => sub { Digest('\par'); },
locked => 1, mode => 'text');
DefEnvironment('{IEEEenumerate}[]',
"<ltx:enumerate xml:id='#id'>#body</ltx:enumerate>",
lib/LaTeXML/Package/IEEEtran.cls.ltxml view on Meta::CPAN
Let('\description', '\IEEEdescription');
Let('\enddescription', '\endIEEEdescription');
Let(T_CS('\begin{itemize}'), '\IEEEitemize');
Let(T_CS('\end{itemize}'), '\endIEEEitemize');
Let(T_CS('\begin{enumerate}'), '\IEEEenumerate');
Let(T_CS('\end{enumerate}'), '\endIEEEenumerate');
Let(T_CS('\begin{description}'), '\IEEEdescription');
Let(T_CS('\end{description}'), '\endIEEEdescription');
# V1.7 provide string macros as article.cls does
DefMacro('\contentsname', 'Contents');
DefMacro('\listfigurename', 'List of Figures');
DefMacro('\listtablename', 'List of Tables');
DefMacro('\refname', 'References');
DefMacro('\indexname', 'Index');
DefMacro('\figurename', 'Fig.');
DefMacro('\tablename', 'TABLE');
DefMacro('\figurename', 'Figure');
DefMacro('\partname', 'Part');
DefMacro('\appendixname', 'Appendix');
DefMacro('\abstractname', 'Abstract');
DefMacro('\IEEEkeywordsname', 'Index Terms');
DefMacro('\IEEEproofname', 'Proof');
# V1.8a no more support for these legacy commands
Let('\authorblockA', '\IEEEauthorblockA');
Let('\authorblockN', '\IEEEauthorblockN');
Let('\authorrefmark', '\IEEEauthorrefmark');
Let('\PARstart', '\IEEEPARstart');
Let('\pubid', '\IEEEpubid');
Let('\pubidadjcol', '\IEEEpubidadjcol');
Let('\specialpapernotice', '\IEEEspecialpapernotice');
# and environments
DefMacro(T_CS('\begin{keywords}'), '\@IEEEkeywords');
DefMacro(T_CS('\end{keywords}'), '\@endIEEEkeywords');
DefMacro('\keywords', sub {
my ($gullet) = @_;
($gullet->ifNext(T_BEGIN)
? (T_CS('\keywords@onearg'))
: T_CS('\@IEEEkeywords')); },
locked => 1);
DefMacro('\keywords@onearg{}', '\@IEEEkeywords #1 \@endIEEEkeywords');
# V1.8 no more support for legacy IED list commands
Let('\labelindent', '\IEEElabelindent');
Let('\calcleftmargin', '\IEEEcalcleftmargin');
Let('\setlabelwidth', '\IEEEsetlabelwidth');
Let('\usemathlabelsep', '\IEEEusemathlabelsep');
Let('\iedlabeljustifyc', '\IEEEiedlabeljustifyc');
Let('\iedlabeljustifyl', '\IEEEiedlabeljustifyl');
Let('\iedlabeljustifyr', '\IEEEiedlabeljustifyr');
# V1.8 no more support for QED and proof stuff
Let('\QED', '\IEEEQED');
Let('\QEDclosed', '\IEEEQEDclosed');
Let('\QEDopen', '\IEEEQEDopen');
DefMacro('\qed', '\ltx@qed');
DefConstructor('\ltx@qed',
"?#isMath(<ltx:XMTok role='PUNCT'>\x{220E}</ltx:XMTok>)(\x{220E})",
reversion => '\qed');
Let('\proof', '\IEEEproof');
Let('\endproof', '\endIEEEproof');
# V1.8 no longer support biography or biographynophoto
Let('\biography', '\IEEEbiography');
Let('\biographynophoto', '\IEEEbiographynophoto');
Let('\endbiography', '\endIEEEbiography');
Let('\endbiographynophoto', '\endIEEEbiographynophoto');
# The \bstctlcite command
# which is used to invoke a BibTeX style control bibliography entry that can alter the formatting of .bst files that support it (such as IEEEtran.bst).
# see docs at http://www.michaelshell.org/tex/ieeetran/tools/
# TODO: Maybe once we can emulate ".bst" files natively this comes into play?
DefMacro('\bstctlcite[]{}', Tokens());
#======================================================================
1;
lib/LaTeXML/Package/JHEP.cls.ltxml view on Meta::CPAN
PassOptions('article', 'cls', ToString(Expand(T_CS('\CurrentOption')))); });
ProcessOptions();
LoadClass('article');
RequirePackage('amssymb');
RequirePackage('floatflt');
#======================================================================
# Frontmatter
DefMacro('\speaker{}', '\@add@frontmatter{ltx:creator}[role=speaker]{\@personname{#1}}');
DefConstructor('\@@@abstract{}', "^ <ltx:abstract name='#name'>#1</ltx:abstract>",
properties => sub { (name => Digest(T_CS('\abstractname'))); });
DefMacro('\abstract{}', '\@add@to@frontmatter{ltx:abstract}{\@@@abstract{#1}}');
DefConstructor('\@@@email{}', "^ <ltx:contact role='email'>#1</ltx:contact>");
DefMacro('\email Semiverbatim', '\@add@to@frontmatter{ltx:creator}{\@@@email{#1}}');
DefMacro('\received{}', '\@add@frontmatter{ltx:date}[role=received,name={\receivedname}]{#1}');
DefMacro('\revised{}', '\@add@frontmatter{ltx:date}[role=revised,name={\revisedname}]{#1}');
DefMacro('\accepted{}', '\@add@frontmatter{ltx:date}[role=accepted,name={\acceptedname}]{#1}');
DefMacro('\JHEPcopydate{}', '\@add@frontmatter{ltx:date}[role=copydate]{#1}');
DefMacro('\dedicated{}', '\@add@frontmatter{ltx:note}[role=dedicated]{#1}');
DefMacro('\conference{}', '\@add@frontmatter{ltx:note}[role=conference]{#1}');
DefMacro('\preprint{}', '\@add@frontmatter{ltx:note}[role=preprint]{#1}');
DefMacro('\keywords{}', '\@add@frontmatter{ltx:keywords}{#1}');
# There's no explicit "end of acknowledgements"
DefConstructor('\acknowledgments', "<ltx:acknowledgements name='#name'>",
properties => sub { (name => Digest(T_CS('\acknowlname'))); });
DefConstructor('\endacknowledgments', "</ltx:acknowledgements>");
Tag("ltx:acknowledgements", autoClose => 1);
#======================================================================
DefPrimitiveI('\hash', undef, '#');
DefMacro('\secstyle', '\bfseries');
DefMacro('\militarytime', '\time'); # !
Let('\textref', '\ref'); # ?
DefMacro('\tocsecs', '');
DefMacro('\logo', 'JHEP');
DefMacro('\JHEP{}', ''); # ?
DefMacro('\PrHEP{}', ''); # ?
DefMacro('\Proof', '\emph{Proof.}\ ');
#======================================================================
# Are these close enough?
DefMacro('\FIGURE[]{}', '\begin{floatingfigure}[#1]#2\end{floatingfigure}');
DefMacro('\TABLE[]{}', '\begin{floatingtable}[#1]#2\end{floatingtable}');
DefMacro('\EPSFIGURE[]{}{}', '\begin{floatingfigure}[#1]\epsfig{file=#2}\caption{#3}\end{floatingfigure}');
DefMacro('\TABULAR[]{}{}{}', '\begin{floatingtable}[#1]\begin{tabular}{#2}#3\end{tabular}\caption{#4}\end{floatingtable}');
DefMacro('\DOUBLEFIGURE[]{}{}{}{}',
'\begin{figure}[#1]'
. '\begin{@half@doublefigure}\epsfig{file=#2}\caption{#4}\end{@half@doublefigure}'
. '\begin{@half@doublefigure}\epsfig{file=#3}\caption{#5}\end{@half@doublefigure}'
. '\end{figure}');
DefEnvironment('{@half@doublefigure}',
"<ltx:figure xml:id='#id' inlist='#inlist' width='0.45%'>#body</ltx:figure>"
. "#tags",
beforeDigest => sub { beforeFloat('figure'); },
afterDigest => sub { afterFloat($_[1]); });
DefMacro('\DOUBLETABLE[]{}{}{}{}',
'\begin{table}[#1]'
. '\begin{@half@doubletable}#2\caption{#4}\end{@half@doubletable}'
. '\begin{@half@doubletable}#3\caption{#5}\end{@half@doubletable}'
. '\end{table}');
DefEnvironment('{@half@doubletable}',
"<ltx:table xml:id='#id' inlist='#inlist' width='0.45%'>#body</ltx:table>"
. "#tags",
beforeDigest => sub { beforeFloat('table'); },
afterDigest => sub { afterFloat($_[1]); });
lib/LaTeXML/Package/JHEP.cls.ltxml view on Meta::CPAN
(float => (ToString($_[1] || LookupValue('floatfltpos')) =~ /^(v|r)/ ? 'right' : 'left')); });
#======================================================================
# Hyperrefing stuff
# \href{url}{text}
DefConstructor('\href Semiverbatim Semiverbatim',
"<ltx:ref href='#href'>#2</ltx:ref>",
properties => sub { (href => ComposeURL((LookupValue('BASE_URL') || ''), $_[1])); });
DefMacro('\JHEPspecialurl Semiverbatim', ''); # ???
DefMacro('\base Semiverbatim', '');
DefMacro('\name Semiverbatim', '');
#======================================================================
# Journal references (w/links to an online database)
DefMacro('\@spires{}', '\href{http://www-spires.slac.stanford.edu/spires/find/hep/www?j=#1}');
DefMacro('\apa{}{}{}', '\@spires{APASA\%2C#1\%2C#3}{{\it Acta Phys.\ Austriaca }{\bf #1} (#2) #3}');
DefMacro('\apas{}{}{}', '\@spires{APAUA\%2C#1\%2C#3}{{\it Acta Phys.\ Austriaca, Suppl.\ }{\bf #1} (#2) #3}');
DefMacro('\appol{}{}{}', '\@spires{APPOA\%2C#1\%2C#3}{{\it Acta Phys.\ Polon.\ }{\bf #1} (#2) #3}');
DefMacro('\advm{}{}{}', '\@spires{ADMTA\%2C#1\%2C#3}{{\it Adv.\ Math.\ }{\bf #1} (#2) #3}');
DefMacro('\adnp{}{}{}', '\@spires{ANUPB\%2C#1\%2C#3}{{\it Adv.\ Nucl.\ Phys.\ }{\bf #1} (#2) #3}');
DefMacro('\adp{}{}{}', '\@spires{ADPHA\%2C#1\%2C#3}{{\it Adv.\ Phys.\ }{\bf #1} (#2) #3}');
DefMacro('\atmp{}{}{}', '\@spires{00203\%2C#1\%2C#3}{{\it Adv.\ Theor.\ Math.\ Phys.\ }{\bf #1} (#2) #3}');
DefMacro('\am{}{}{}', '\@spires{ANMAA\%2C#1\%2C#3}{{\it Ann.\ Math.\ }{\bf #1} (#2) #3}');
DefMacro('\ap{}{}{}', '\@spires{APNYA\%2C#1\%2C#3}{{\it Ann.\ Phys.\ (NY) }{\bf #1} (#2) #3}');
DefMacro('\araa{}{}{}', '\@spires{ARAAA\%2C#1\%2C#3}{{\it Ann.\ Rev.\ Astron.\ \& Astrophys.\ }{\bf #1} (#2) #3}');
DefMacro('\arnps{}{}{}', '\@spires{ARNUA\%2C#1\%2C#3}{{\it Ann.\ Rev.\ Nucl.\ Part.\ Sci.\ }{\bf #1} (#2) #3}');
DefMacro('\asas{}{}{}', '\@spires{AAEJA\%2C#1\%2C#3}{{\it Astron.\ Astrophys.\ }{\bf #1} (#2) #3}');
DefMacro('\asj{}{}{}', '\@spires{ANJOA\%2C#1\%2C#3}{{\it Astron.\ J.\ }{\bf #1} (#2) #3}');
DefMacro('\app{}{}{}', '\@spires{APHYE\%2C#1\%2C#3}{{\it Astropart.\ Phys.\ }{\bf #1} (#2) #3}');
DefMacro('\apj{}{}{}', '\@spires{ASJOA\%2C#1\%2C#3}{{\it Astrophys.\ J. }{\bf #1} (#2) #3}');
DefMacro('\baas{}{}{}', '\@spires{AASBA\%2C#1\%2C#3}{{\it Bull.\ Am.\ Astron.\ Soc.\ }{\bf #1} (#2) #3}');
DefMacro('\bams{}{}{}', '\@spires{BAMOA\%2C#1\%2C#3}{{\it Bull.\ Am.\ Math.\ Soc.\ }{\bf #1} (#2) #3}');
DefMacro('\blms{}{}{}', '\@spires{LMSBB\%2C#1\%2C#3}{{\it Bull.\ London Math.\ Soc.\ }{\bf #1} (#2) #3}');
DefMacro('\cjm{}{}{}', '\@spires{CJMAA\%2C#1\%2C#3}{{\it Can.\ J.\ Math.\ }{\bf #1} (#2) #3}');
DefMacro('\cqg{}{}{}', '\@spires{CQGRD\%2C#1\%2C#3}{{\it Class.\ and Quant.\ Grav.\ }{\bf #1} (#2) #3}');
DefMacro('\cmp{}{}{}', '\@spires{CMPHA\%2C#1\%2C#3}{{\it Commun.\ Math.\ Phys.\ }{\bf #1} (#2) #3}');
DefMacro('\ctp{}{}{}', '\@spires{CTPMD\%2C#1\%2C#3}{{\it Commun.\ Theor.\ Phys.\ }{\bf #1} (#2) #3}');
DefMacro('\cag{}{}{}', '\@spires{00142\%2C#1\%2C#3}{{\it Commun.\ Anal.\ Geom.\ }{\bf #1} (#2) #3}');
DefMacro('\cpam{}{}{}', '\@spires{CPAMA\%2C#1\%2C#3}{{\it Commun.\ Pure Appl.\ Math.\ }{\bf #1} (#2) #3}');
DefMacro('\cpc{}{}{}', '\@spires{CPHCB\%2C#1\%2C#3}{{\it Comput.\ Phys.\ Commun.\ }{\bf #1} (#2) #3}');
DefMacro('\dmj{}{}{}', '\@spires{DUMJA\%2C#1\%2C#3}{{\it Duke Math.\ J. }{\bf #1} (#2) #3}');
DefMacro('\epjc{}{}{}', '\@spires{EPHJA\%2CC#1\%2C#3}{{\it Eur.\ Phys.\ J. }{\bf C #1} (#2) #3}');
DefMacro('\epjd{}{}{}', '\@spires{EPHJD\%2CC#1\%2C#3}{{\it Eur.\ Phys.\ J. Direct.\ }{\bf C #1} (#2) #3}');
DefMacro('\epl{}{}{}', '\@spires{EULEE\%2C#1\%2C#3}{{\it Europhys.\ Lett. }{\bf #1} (#2) #3}');
DefMacro('\forp{}{}{}', '\@spires{FPYKA\%2C#1\%2C#3}{{\it Fortschr.\ Phys.\ }{\bf #1} (#2) #3}');
DefMacro('\faa{}{}{}', '\@spires{FAAPB\%2C#1\%2C#3}{{\it Funct.\ Anal.\ Appl.\ }{\bf #1} (#2) #3}');
DefMacro('\grg{}{}{}', '\@spires{GRGVA\%2C#1\%2C#3}{{\it Gen.\ Rel.\ Grav.\ }{\bf #1} (#2) #3}');
DefMacro('\hpa{}{}{}', '\@spires{HPACA\%2C#1\%2C#3}{{\it Helv.\ Phys.\ Acta }{\bf #1} (#2) #3}');
DefMacro('\ijmpa{}{}{}', '\@spires{IMPAE\%2CA#1\%2C#3}{{\it Int.\ J.\ Mod.\ Phys.\ }{\bf A #1} (#2) #3}');
DefMacro('\ijmpb{}{}{}', '\@spires{IMPAE\%2CB#1\%2C#3}{{\it Int.\ J.\ Mod.\ Phys.\ }{\bf B #1} (#2) #3}');
DefMacro('\ijmpc{}{}{}', '\@spires{IMPAE\%2CC#1\%2C#3}{{\it Int.\ J.\ Mod.\ Phys.\ }{\bf C #1} (#2) #3}');
DefMacro('\ijmpd{}{}{}', '\@spires{IMPAE\%2CD#1\%2C#3}{{\it Int.\ J.\ Mod.\ Phys.\ }{\bf D #1} (#2) #3}');
DefMacro('\ijtp{}{}{}', '\@spires{IJTPB\%2CB#1\%2C#3}{{\it Int.\ J.\ Theor.\ Phys.\ }{\bf #1} (#2) #3}');
DefMacro('\invm{}{}{}', '\@spires{INVMB\%2C#1\%2C#3}{{\it Invent.\ Math.\ }{\bf #1} (#2) #3}');
DefMacro('\jag{}{}{}', '\@spires{00124\%2C#1\%2C#3}{{\it J.\ Alg.\ Geom.\ }{\bf #1} (#2) #3}');
DefMacro('\jams{}{}{}', '\@spires{00052\%2C#1\%2C#3}{{\it J.\ Am.\ Math.\ Soc.\ }{\bf #1} (#2) #3}');
DefMacro('\jap{}{}{}', '\@spires{JAPIA\%2C#1\%2C#3}{{\it J.\ Appl.\ Phys.\ }{\bf #1} (#2) #3}');
DefMacro('\jdg{}{}{}', '\@spires{JDGEA\%2C#1\%2C#3}{{\it J.\ Diff.\ Geom.\ }{\bf #1} (#2) #3}');
DefMacro('\jgp{}{}{}', '\@spires{JGPHE\%2C#1\%2C#3}{{\it J.\ Geom.\ Phys.\ }{\bf #1} (#2) #3}');
DefMacro('\jhep{}{}{}', '\href{http://jhep.sissa.it/stdsearch?paper=#1\%28#2\%29#3}{{\it J. High Energy Phys.\ }{\bf #1} (#2) #3}');
DefMacro('\jmp{}{}{}', '\@spires{JMAPA\%2C#1\%2C#3}{{\it J.\ Math.\ Phys.\ }{\bf #1} (#2) #3}');
DefMacro('\joth{}{}{}', '\@spires{JOTHE\%2C#1\%2C#3}{{\it J.\ Operator Theory }{\bf #1} (#2) #3}');
DefMacro('\jpha{}{}{}', '\@spires{JPAGB\%2CA#1\%2C#3}{{\it J. Phys.\ }{\bf A #1} (#2) #3}');
DefMacro('\jphc{}{}{}', '\@spires{JPAGB\%2CC#1\%2C#3}{{\it J. Phys.\ }{\bf C #1} (#2) #3}');
DefMacro('\jphg{}{}{}', '\@spires{JPAGB\%2CG#1\%2C#3}{{\it J. Phys.\ }{\bf G #1} (#2) #3}');
DefMacro('\lmp{}{}{}', '\@spires{LMPHD\%2CA#1\%2C#3}{{\it Lett.\ Math.\ Phys.\ }{\bf #1} (#2) #3}');
DefMacro('\ncl{}{}{}', '\@spires{NCLTA\%2C#1\%2C#3}{{\it Lett.\ Nuovo Cim.\ }{\bf #1} (#2) #3}');
DefMacro('\matan{}{}{}', '\@spires{MAANA\%2CA#1\%2C#3}{{\it Math.\ Ann.\ }{\bf #1} (#2) #3}');
DefMacro('\mussr{}{}{}', '\@spires{MUSIA\%2CA#1\%2C#3}{{\it Math.\ USSR Izv.\ }{\bf #1} (#2) #3}');
DefMacro('\mams{}{}{}', '\@spires{MAMCA\%2CA#1\%2C#3}{{\it Mem.\ Am.\ Math.\ Soc.\ }{\bf #1} (#2) #3}');
DefMacro('\mpla{}{}{}', '\@spires{MPLAE\%2CA#1\%2C#3}{{\it Mod.\ Phys.\ Lett.\ }{\bf A #1} (#2) #3}');
DefMacro('\mplb{}{}{}', '\@spires{MPLAE\%2CB#1\%2C#3}{{\it Mod.\ Phys.\ Lett.\ }{\bf B #1} (#2) #3}');
DefMacro('\nature{}{}{}', '\@spires{NATUA\%2C#1\%2C#3}{{\it Nature }{\bf #1} (#2) #3}');
DefMacro('\nim{}{}{}', '\@spires{NUIMA\%2C#1\%2C#3}{{\it Nucl.\ Instrum.\ Meth.\ }{\bf #1} (#2) #3}');
DefMacro('\npa{}{}{}', '\@spires{NUPHA\%2CA#1\%2C#3}{{\it Nucl.\ Phys.\ }{\bf A #1} (#2) #3}');
DefMacro('\npb{}{}{}', '\@spires{NUPHA\%2CB#1\%2C#3}{{\it Nucl.\ Phys.\ }{\bf B #1} (#2) #3}');
DefMacro('\npps{}{}{}', '\@spires{NUPHZ\%2C#1\%2C#3}{{\it Nucl.\ Phys.\ }{\bf #1} {\it(Proc.\ Suppl.)} (#2) #3}');
DefMacro('\nc{}{}{}', '\@spires{NUCIA\%2C#1\%2C#3}{{\it Nuovo Cim.\ }{\bf #1} (#2) #3}');
DefMacro('\ncs{}{}{}', '\@spires{NUCUA\%2C#1\%2C#3}{{\it Nuovo Cim.\ Suppl.\ }{\bf #1} (#2) #3}');
DefMacro('\pan{}{}{}', '\@spires{PANUE\%2C#1\%2C#3}{{\it Phys.\ Atom.\ Nucl.\ }{\bf #1} (#2) #3}');
DefMacro('\pla{}{}{}', '\@spires{PHLTA\%2CA#1\%2C#3}{{\it Phys.\ Lett.\ }{\bf A #1} (#2) #3}');
DefMacro('\plb{}{}{}', '\@spires{PHLTA\%2CB#1\%2C#3}{{\it Phys.\ Lett.\ }{\bf B #1} (#2) #3}');
DefMacro('\pr{}{}{}', '\@spires{PHRVA\%2C#1\%2C#3}{{\it Phys.\ Rev.\ }{\bf #1} (#2) #3}');
DefMacro('\pra{}{}{}', '\@spires{PHRVA\%2CA#1\%2C#3}{{\it Phys.\ Rev.\ }{\bf A #1} (#2) #3}');
DefMacro('\prb{}{}{}', '\@spires{PHRVA\%2CB#1\%2C#3}{{\it Phys.\ Rev.\ }{\bf B #1} (#2) #3}');
DefMacro('\prc{}{}{}', '\@spires{PHRVA\%2CC#1\%2C#3}{{\it Phys.\ Rev.\ }{\bf C #1} (#2) #3}');
DefMacro('\prd{}{}{}', '\@spires{PHRVA\%2CD#1\%2C#3}{{\it Phys.\ Rev.\ }{\bf D #1} (#2) #3}');
DefMacro('\pre{}{}{}', '\@spires{PHRVA\%2CE#1\%2C#3}{{\it Phys.\ Rev.\ }{\bf E #1} (#2) #3}');
DefMacro('\prep{}{}{}', '\@spires{PRPLC\%2C#1\%2C#3}{{\it Phys.\ Rept.\ }{\bf #1} (#2) #3}');
DefMacro('\prl{}{}{}', '\@spires{PRLTA\%2C#1\%2C#3}{{\it Phys.\ Rev.\ Lett.\ }{\bf #1} (#2) #3}');
DefMacro('\phys{}{}{}', '\@spires{PHYSA\%2CA#1\%2C#3}{{\it Physica }{\bf #1} (#2) #3}');
DefMacro('\plms{}{}{}', '\@spires{PHLTA\%2CB#1\%2C#3}{{\it Proc.\ London Math.\ Soc.\ }{\bf B #1} (#2) #3}');
DefMacro('\pnas{}{}{}', '\@spires{PNASA\%2C#1\%2C#3}{{\it Proc.\ Nat.\ Acad.\ Sci.\ }{\bf #1} (#2) #3}');
DefMacro('\ppnp{}{}{}', '\@spires{PPNPD\%2C#1\%2C#3}{{\it Prog.\ Part.\ Nucl.\ Phys.\ }{\bf #1} (#2) #3}');
DefMacro('\ptp{}{}{}', '\@spires{PTPKA\%2C#1\%2C#3}{{\it Prog.\ Theor.\ Phys.\ }{\bf #1} (#2) #3}');
DefMacro('\ptps{}{}{}', '\@spires{PTPSA\%2C#1\%2C#3}{{\it Prog.\ Theor.\ Phys.\ Suppl.\ }{\bf #1} (#2) #3}');
DefMacro('\rmp{}{}{}', '\@spires{RMPHA\%2C#1\%2C#3}{{\it Rev.\ Mod.\ Phys.\ }{\bf #1} (#2) #3}');
DefMacro('\sjnp{}{}{}', '\@spires{SJNCA\%2C#1\%2C#3}{{\it Sov.\ J.\ Nucl.\ Phys.\ }{\bf #1} (#2) #3}');
DefMacro('\sjpn{}{}{}', '\@spires{SJPNA\%2C#1\%2C#3}{{\it Sov.\ J.\ Part.\ Nucl.\ }{\bf #1} (#2) #3}');
DefMacro('\jetp{}{}{}', '\@spires{SPHJA\%2C#1\%2C#3}{{\it Sov.\ Phys.\ JETP\/ }{\bf #1} (#2) #3}');
DefMacro('\jetpl{}{}{}', '\@spires{JTPLA\%2C#1\%2C#3}{{\it Sov.\ Phys.\ JETP Lett.\ }{\bf #1} (#2) #3}');
DefMacro('\spu{}{}{}', '\@spires{SOPUA\%2C#1\%2C#3}{{\it Sov.\ Phys.\ Usp.\ }{\bf #1} (#2) #3}');
DefMacro('\tmf{}{}{}', '\@spires{TMFZA\%2C#1\%2C#3}{{\it Teor.\ Mat.\ Fiz.\ }{\bf #1} (#2) #3}');
DefMacro('\tmp{}{}{}', '\@spires{TMPHA\%2C#1\%2C#3}{{\it Theor.\ Math.\ Phys.\ }{\bf #1} (#2) #3}');
DefMacro('\ufn{}{}{}', '\@spires{UFNAA\%2C#1\%2C#3}{{\it Usp.\ Fiz.\ Nauk.\ }{\bf #1} (#2) #3}');
DefMacro('\ujp{}{}{}', '\@spires{00267\%2C#1\%2C#3}{{\it Ukr.\ J.\ Phys.\ }{\bf #1} (#2) #3}');
DefMacro('\yf{}{}{}', '\@spires{YAFIA\%2C#1\%2C#3}{{\it Yad.\ Fiz.\ }{\bf #1} (#2) #3}');
DefMacro('\zpc{}{}{}', '\@spires{ZEPYA\%2CC#1\%2C#3}{{\it Z.\ Physik }{\bf C #1} (#2) #3}');
DefMacro('\zetf{}{}{}', '\@spires{ZETFA\%2C#1\%2C#3}{{\it Zh.\ Eksp.\ Teor.\ Fiz.\ }{\bf #1} (#2) #3}');
DefMacro('\newjournal{}{}{}{}{}', '\@spires{#2\%2C#3\%2C#5}{{\it #1 }{\bf #3} (#4) #5}}');
DefMacro('\ibid{}{}{}', '{\it ibid.\ }{\bf #1} (#2) #3');
DefMacro('\hepth{}', '\href{http://xxx.lanl.gov/abs/hep-th/#1}{\tt hep-th/#1}');
DefMacro('\hepph{}', '\href{http://xxx.lanl.gov/abs/hep-ph/#1}{\tt hep-ph/#1}');
DefMacro('\heplat{}', '\href{http://xxx.lanl.gov/abs/hep-lat/#1}{\tt hep-lat/#1}');
DefMacro('\hepex{}', '\href{http://xxx.lanl.gov/abs/hep-ex/#1}{\tt hep-ex/#1}');
DefMacro('\nuclth{}', '\href{http://xxx.lanl.gov/abs/nucl-th/#1}{\tt nucl-th/#1}');
DefMacro('\nuclex{}', '\href{http://xxx.lanl.gov/abs/nucl-ex/#1}{\tt nucl-ex/#1}');
DefMacro('\grqc{}', '\href{http://xxx.lanl.gov/abs/gr-qc/#1}{\tt gr-qc/#1}');
DefMacro('\qalg{}', '\href{http://xxx.lanl.gov/abs/q-alg/#1}{\tt q-alg/#1}');
DefMacro('\accphys{}', '\href{http://xxx.lanl.gov/abs/accphys/#1}{\tt accphys/#1}');
DefMacro('\alggeom{}', '\href{http://xxx.lanl.gov/abs/alg-geom/#1}{\tt alg-geom/#1}');
DefMacro('\astroph{}', '\href{http://xxx.lanl.gov/abs/astro-ph/#1}{\tt astro-ph/#1}');
DefMacro('\chaodyn{}', '\href{http://xxx.lanl.gov/abs/chao-dyn/#1}{\tt chao-dyn/#1}');
DefMacro('\condmat{}', '\href{http://xxx.lanl.gov/abs/cond-mat/#1}{\tt cond-mat/#1}');
DefMacro('\nlinsys{}', '\href{http://xxx.lanl.gov/abs/nlin-sys/#1}{\tt nlin-sys/#1}');
DefMacro('\quantph{}', '\href{http://xxx.lanl.gov/abs/quant-ph/#1}{\tt quant-ph/#1}');
DefMacro('\solvint{}', '\href{http://xxx.lanl.gov/abs/solv-int/#1}{\tt solv-int/#1}');
DefMacro('\suprcon{}', '\href{http://xxx.lanl.gov/abs/supr-con/#1}{\tt supr-con/#1}');
#DefMacro('\mathph{}','\href{http://xxx.lanl.gov/abs/math-ph/#1}{\tt math-ph/#1}');
#DefMacro('\physics{}','\href{http://xxx.lanl.gov/abs/physics/#1}{\tt physics/#1}');
DefMacro('\Math{}{}', '\href{http://xxx.lanl.gov/abs/math.#1/#2}{\tt math.#1/#2}');
#======================================================================
RawTeX(<<'EoTeX');
\newif\if@preprint\@preprinttrue % DEFAULT IS PREPRINT!
\newif\if@draft \@draftfalse % DEFAULT IS NOT DRAFT
\newif\if@hyper \@hypertrue % DEFAULT IS HYPER
\newif\if@proc \@procfalse % DEFAULT IS NOT PROC
%\newif\if@title\@titlefalse %
lib/LaTeXML/Package/JHEP.cls.ltxml view on Meta::CPAN
\newif\if@conf\@conffalse %
\newif\if@Jspecialurl\@Jspecialurlfalse
\newif\if@speaker\@speakerfalse
\newif\if@dblspeak\@dblspeakfalse
\newif\if@twothms\@twothmsfalse
\newtoks\outputpretest
EoTeX
DefMacro('\contentsname', 'Contents');
DefMacro('\listfigurename', 'List of figures');
DefMacro('\listtablename', 'List of tables');
DefMacro('\refname', 'References');
DefMacro('\indexname', 'Index');
DefMacro('\figurename', 'Figure');
DefMacro('\tablename', 'Table');
DefMacro('\partname', 'Part');
DefMacro('\appendixname', 'Appendix');
DefMacro('\abstractname', 'Abstract:');
DefMacro('\keywordsname', 'Keywords:');
DefMacro('\receivedname', 'Received:');
DefMacro('\revisedname', 'Revised:');
DefMacro('\acceptedname', 'Accepted:');
DefMacro('\acknowlname', 'Acknowledgments');
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1;
__END__
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
LoadPool('TeX');
# Apparently LaTeX does NOT define \magnification,
# and babel uses that to determine whether we're runing LaTeX!!!
Let('\magnification', '\@undefined');
#**********************************************************************
# Basic \documentclass & \documentstyle
#AssignValue('2.09_COMPATIBILITY'=>0);
DefConditionalI('\if@compatibility', undef, sub { LookupValue('2.09_COMPATIBILITY'); });
DefMacro('\@compatibilitytrue', '');
DefMacro('\@compatibilityfalse', '');
Let('\@currentlabel', '\@empty');
DefMacro('\@currdir', './');
# Let's try just starting with this set (since we've loaded LaTeX)
AssignValue(inPreamble => 1); # \begin{document} will clear this.
DefConstructor('\documentclass OptionalSemiverbatim SkipSpaces Semiverbatim []',
"<?latexml class='#2' ?#1(options='#1')?>",
beforeDigest => sub { onlyPreamble('\documentclass'); },
afterDigest => sub {
my ($stomach, $whatsit) = @_;
my $options = $whatsit->getArg(1);
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
# In fact, the \env & \endenv don't have to have been created by
# \newenvironment; And in fact \endenv doesn't even have to be defined!
# [it is created by \csname, and equiv to \relax if no previous defn]
# We need to respect these usages here, but we also want to be able
# to define environment constructors that `capture' the body so that
# it can be processed specially, if needed. These are the magic
# '\begin{env}', '\end{env}' control sequences created by DefEnvironment.
AssignValue(current_environment => '', 'global');
DefMacro('\@currenvir', '');
DefPrimitive('\lx@setcurrenvir{}', sub {
DefMacroI('\@currenvir', undef, $_[1]);
AssignValue(current_environment => ToString($_[1])); });
DefMacro('\@checkend{}', '\def\reserved@a{#1}\ifx\reserved@a\@currenvir \else\@badend{#1}\fi}');
Let('\@currenvline', '\@empty');
DefMacro('\begin{}', sub {
my ($gullet, $env) = @_;
my $name = $env && ToString(Expand($env));
my $before = LookupValue('@environment@' . $name . '@beforebegin');
my $after = LookupValue('@environment@' . $name . '@atbegin');
if (IsDefined("\\begin{$name}")) {
(($before ? @$before : ()),
T_CS("\\begin{$name}")); } # Magic cs!
else {
my $token = T_CS("\\$name");
if (!IsDefined($token)) {
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
Error('undefined', $undef, $gullet, "The environment " . $undef . " is not defined.");
$STATE->installDefinition(LaTeXML::Core::Definition::Constructor->new($token, undef,
sub { $_[0]->makeError('undefined', $undef); })); }
(($before ? @$before : ()),
T_CS('\begingroup'),
($after ? @$after : ()),
Invocation(T_CS('\lx@setcurrenvir'), $env),
$token,); } });
# robust => 1); # Not yet working well enough
DefMacro('\end{}', sub {
my ($gullet, $env) = @_;
my $name = $env && ToString(Expand($env));
my $before = LookupValue('@environment@' . $name . '@atend');
my $after = LookupValue('@environment@' . $name . '@afterend');
my $t;
if (IsDefined($t = T_CS("\\end{$name}"))) {
($t,
($after ? @$after : ())); } # Magic CS!
else {
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
DefConstructor('\newline',
"?#isMath(<ltx:XMHint name='newline'/>)(<ltx:break/>)",
reversion => Tokens(T_CS('\newline'), T_CR),
properties => { isBreak => 1 });
Let('\@normalcr', "\\\\");
Let('\@normalnewline', '\newline');
##PushValue(TEXT_MODE_BINDINGS => [
## T_CS("\\\\"), T_CS('\@normalcr'), T_CS('\newline'), T_CS('\@normalnewline')]);
DefMacro('\@nolnerr', '');
DefMacro('\@centercr', '\ifhmode\unskip\else\@nolnerr\fi'
. '\par\@ifstar{\nobreak\@xcentercr}\@xcentercr');
DefMacro('\@xcentercr', '\addvspace{-\parskip}\@ifnextchar[\@icentercr\ignorespaces');
DefMacro('\@icentercr[]', '\vskip #1\ignorespaces');
#**********************************************************************
# C.2. The Structure of the Document
#**********************************************************************
# prepended files (using filecontents environment)
# preamble (starting with \documentclass)
# \begin{document}
# text
# \end{document}
DefMacro('\AtBeginDocument{}', sub {
PushValue('@at@begin@document', $_[1]->unlist); });
DefMacro('\AtEndDocument{}', sub {
PushValue('@at@end@document', $_[1]->unlist); });
# Like "<ltx:document xml:id='#id'>#body</ltx:document>",
# But more complicated due to id, at begin/end document and so forth.
# AND, lower-level so that we can cope with common errors at document end.
DefConstructorI(T_CS('\begin{document}'), undef, sub {
my ($document, %props) = @_;
my $id = ToString($props{id});
if (my $docel = $document->findnode('/ltx:document')) { # Already (auto) created?
$document->setAttribute($docel, 'xml:id' => $id) if $id; }
else {
$document->openElement('ltx:document', 'xml:id' => $id); } },
afterDigest => sub {
my ($stomach, $whatsit) = @_;
$stomach->beginMode('text');
DefMacroI('\@currenvir', undef, 'document');
AssignValue(current_environment => 'document');
$_[1]->setProperty(id => Expand(T_CS('\thedocument@ID')));
my @boxes = ();
if (my $ops = LookupValue('@document@preamble@atend')) {
push(@boxes, $stomach->digest(Tokens(@$ops))); }
if (my $ops = LookupValue('@at@begin@document')) {
push(@boxes, $stomach->digest(Tokens(@$ops))); }
AssignValue(inPreamble => 0); # atbegin is still (sorta) preamble
if (my $ops = LookupValue('@document@preamble@afterend')) {
push(@boxes, $stomach->digest(Tokens(@$ops))); }
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
"<ltx:text class='ltx_LaTeX_logo' cssstyle='letter-spacing:-0.2em; margin-right:0.1em'>"
. "L"
. "<ltx:text cssstyle='font-variant:small-caps;' yoffset='0.4ex'>a</ltx:text>"
. "T"
. "<ltx:text cssstyle='font-variant:small-caps;font-size:120%' yoffset='-0.2ex'>e</ltx:text>"
. "X"
. "\x{2002}2<ltx:text cssstyle='font-style:italic' yoffset='-0.3ex'>\x{03B5}</ltx:text>"
. "</ltx:text>",
sizer => sub { (Dimension('3.7em'), Dimension('1.6ex'), Dimension('0.5ex')); });
DefMacroI('\fmtname', undef, 'LaTeX2e');
DefMacroI('\fmtversion', undef, '2018/12/01');
DefMacroI('\today', undef, sub { ExplodeText(today()); });
# Use fonts (w/ special flag) to propogate emphasis as a font change,
# but preserve it's "emph"-ness.
# Use ltx:emph in text, but use ltx:text within math, since it may collapse within XMText
# (and minimize html within math, which causes MathJax problems)
DefConstructor('\emph{}', sub {
my ($document, $body, %props) = @_;
my $tag = ($document->findnodes('ancestor::ltx:Math', $document->getNode) ? 'ltx:text' : 'ltx:emph');
$document->openElement($tag, _force_font => 1, %props);
$document->absorb($body);
$document->maybeCloseElement($tag); },
mode => 'text', bounded => 1, font => { emph => 1 }, alias => '\emph',
beforeDigest => sub {
DefMacroI('\f@shape', undef,
(ToString(Tokens(Expand(T_CS('\f@shape')))) eq 'it' ? 'n' : 'it')); });
Tag('ltx:emph', autoClose => 1);
#======================================================================
# C.3.2 Making Paragraphs
#======================================================================
# \noindent, \indent, \par in TeX.pool.ltxml
Let('\@@par', '\par');
DefMacro('\@par', '\let\par\@@par\par');
DefMacro('\@restorepar', '\def\par{\@par}');
# Style parameters
# \parindent, \baselineskip, \parskip alreadin in TeX.pool.ltxml
DefPrimitive('\linespread{}', undef);
# ?
DefMacro('\@noligs', '');
DefConditional('\if@endpe');
DefMacro('\@doendpe', '');
DefMacro('\@bsphack', '\relax'); # what else?
DefMacro('\@esphack', '\relax');
DefMacro('\@Esphack', '\relax');
#======================================================================
# C.3.3 Footnotes
#======================================================================
NewCounter('footnote');
DefMacroI('\thefootnote', undef, '\arabic{footnote}');
NewCounter('mpfootnote');
DefMacroI('\thempfn', undef, '\thefootnote');
DefMacroI('\thempfootnote', undef, '\arabic{mpfootnote}');
DefMacroI('\footnotetyperefname', undef, 'footnote');
sub makeNoteTags {
my ($counter, $mark, $tag) = @_;
if ($tag) {
return (
RefStepID($counter),
mark => $mark || $tag,
tags => Digest(T_BEGIN,
T_CS('\def'), T_CS('\the' . $counter), T_BEGIN, Revert($tag), T_END,
T_CS('\def'), T_CS('\typerefnum@' . $counter),
T_BEGIN, T_CS('\\' . $counter . 'typerefname'), T_SPACE, Revert($tag), T_END,
Invocation(T_CS('\lx@make@tags'), T_OTHER($counter)),
T_END)); }
else {
return (RefStepCounter($counter),
mark => $mark || DigestText(T_CS('\the' . $counter))); } }
DefMacroI('\ext@footnote', undef, undef);
DefConstructor('\lx@note[]{}[]{}',
"^<ltx:note role='#role' mark='#mark' xml:id='#id' inlist='#list'>"
. "#tags"
. "#4"
. "</ltx:note>",
mode => 'text', bounded => 1,
sizer => '#mark',
beforeDigest => sub { reenterTextMode(1); neutralizeFont(); },
properties => sub {
my $type = ToString($_[2]);
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
makeNoteTags($type, $_[1], $_[3])); },
reversion => '');
DefConstructor('\lx@notetext[]{}[]{}',
"^<ltx:note role='#role' mark='#mark' xml:id='#id'>#4</ltx:note>",
mode => 'text',
properties => sub {
my $type = ToString($_[2]);
(role => $type . 'text', makeNoteTags($type, $_[1], $_[3] || Digest(T_CS('\the' . $type)))); },
reversion => '');
DefMacro('\footnote', '\lx@note{footnote}', locked => 1);
DefMacro('\footnotemark', '\lx@notemark{footnote}', locked => 1);
DefMacro('\footnotetext', '\lx@notetext{footnote}', locked => 1);
DefMacro('\@footnotetext', '\lx@notetext{footnote}', locked => 1);
# we don't implement the internals directly, so lock them to the latexml variant
Let('\@thefnmark', '\lx@notemark{footnote}', locked => 1);
Tag('ltx:note', afterClose => \&relocateFootnote);
# Find any pairs of footnotemark & footnotetext;
# Move the contents of the text to the mark, removing the text node.
sub relocateFootnote {
my ($document, $node) = @_;
if (($node->getAttribute('role') || '') =~ /^(\w+?)text$/) {
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
# Also, we're adding an id to each, that is parallel to the refnum, but
# valid as an ID. You can tune the representation by defining, eg. \thesection@ID
# A little more messy than seems necessary:
# We don't know whether to step the counter and update \@currentlabel until we see the '*',
# but we have to know it before we digest the title, since \label can be there!
# These are defined in terms of \@startsection so that
# casual user redefinitions work, too.
DefMacroI('\chapter', undef, '\@startsection{chapter}{0}{}{}{}{}', locked => 1);
DefMacroI('\part', undef, '\@startsection{part}{-1}{}{}{}{}'); # not locked since sometimes redefined as partition?
DefMacroI('\section', undef, '\@startsection{section}{1}{}{}{}{}', locked => 1);
DefMacroI('\subsection', undef, '\@startsection{subsection}{2}{}{}{}{}', locked => 1);
DefMacroI('\subsubsection', undef, '\@startsection{subsubsection}{3}{}{}{}{}', locked => 1);
DefMacroI('\paragraph', undef, '\@startsection{paragraph}{4}{}{}{}{}', locked => 1);
DefMacroI('\subparagraph', undef, '\@startsection{subparagraph}{5}{}{}{}{}', locked => 1);
map { Tag("ltx:$_", autoClose => 1) }
qw(part chapter section subsection subsubsection paragraph subparagraph);
DefMacro('\secdef {}{} OptionalMatch:*', sub { ($_[3] ? ($_[2]) : ($_[1])); });
DefMacroI('\@startsection@hook', undef, Tokens());
NewCounter('secnumdepth');
SetCounter('secnumdepth', Number(3));
DefMacro('\@startsection{}{}{}{}{}{} OptionalMatch:*', sub {
my ($gullet, $type, $level, $ignore3, $ignore4, $ignore5, $ignore6, $flag) = @_;
### Aside: Guard mode
# Never start sections in math mode -- this is a good recovery point for broken documents
if ($STATE->lookupValue('IN_MATH')) {
my $mode = $STATE->lookupValue('MODE');
if ($mode =~ /math/) { # double-check we're really in math
$STATE->getStomach->endMode($mode); }
else { # otherwise, just unset the flag?
$STATE->assignValue('IN_MATH' => 0, 'global'); } }
### Main logic
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
Invocation(T_CS('\lx@format@title@font@@'), $type), $title, T_CS('\@hidden@egroup'));
$props{toctitle} = $toctitle
&& Digest(T_CS('\@hidden@bgroup'), Invocation(T_CS('\lx@format@toctitle@font@@'), $type),
$toctitle, T_CS('\@hidden@egroup'));
return %props; });
#======================================================================
# C.4.2 The Appendix
#======================================================================
# Handled in article,report or book.
DefMacroI('\appendixname', undef, 'Appendix');
DefMacroI('\appendixesname', undef, 'Appendixes');
# Class files should define \@appendix to call this as startAppendices('section') or chapter...
# counter is also the element name!
sub startAppendices { beginAppendices(@_); return; }
sub beginAppendices {
my ($counter) = @_;
Let('\lx@save@theappendex', '\the' . $counter, 'global');
Let('\lx@save@theappendex@ID', '\the' . $counter . '@ID', 'global');
Let('\lx@save@appendix', T_CS('\\' . $counter), 'global');
Let('\lx@save@@appendix', T_CS('\@appendix'), 'global');
AssignMapping('BACKMATTER_ELEMENT', 'ltx:appendix' => 'ltx:' . $counter);
if (LookupDefinition(T_CS('\c@chapter')) # Has \chapter defined
&& ($counter ne 'chapter')) { # And appendices are below the chapter level.
NewCounter($counter, 'chapter', idprefix => 'A');
DefMacroI('\the' . $counter, undef, '\thechapter.\Alph{' . $counter . '}', scope => 'global'); }
else {
NewCounter($counter, 'document', idprefix => 'A');
DefMacroI('\the' . $counter, undef, '\Alph{' . $counter . '}', scope => 'global'); }
AssignMapping('counter_for_type', appendix => $counter);
Let(T_CS('\\' . $counter), T_CS('\@@appendix'), 'global');
Let(T_CS('\@appendix'), T_CS('\relax'), 'global');
return; }
sub endAppendices {
if (my $counter = LookupMapping('BACKMATTER_ELEMENT', 'ltx:appendix')) {
$counter =~ s/^ltx://;
Let('\the' . $counter, '\lx@save@theappendex', 'global');
Let('\the' . $counter . '@ID', '\lx@save@theappendex@ID', 'global');
Let(T_CS('\\' . $counter), '\lx@save@appendix', 'global');
Let(T_CS('\@appendix'), '\lx@save@@appendix', 'global'); }
return; }
DefMacroI('\\@@appendix', undef, '\@startsection{appendix}{0}{}{}{}{}');
#======================================================================
# C.4.3 Table of Contents
#======================================================================
# Insert stubs that will be filled in during post processing.
DefMacroI('\contentsname', undef, 'Contents');
DefConstructorI('\tableofcontents', undef,
"<ltx:TOC lists='toc' scope='global' select='#select'><ltx:title>#name</ltx:title></ltx:TOC>",
properties => sub {
my $td = CounterValue('tocdepth')->valueOf + 1;
my @s = (qw(ltx:part ltx:chapter ltx:section ltx:subsection ltx:subsubsection
ltx:paragraph ltx:subparagraph));
$td = $#s if $#s < $td;
@s = map { $s[$_] } 0 .. $td;
push(@s, (qw(ltx:appendix ltx:index ltx:bibliography))) if @s;
(select => join(' | ', @s),
name => Digest(T_CS('\contentsname'))); });
DefMacroI('\listfigurename', undef, 'List of Figures');
DefConstructorI('\listoffigures', undef,
"<ltx:TOC lists='lof' scope='global'><ltx:title>#name</ltx:title></ltx:TOC>",
properties => sub { (name => Digest(T_CS('\listfigurename'))); });
DefMacroI('\listtablename', undef, 'List of Tables');
DefConstructorI('\listoftables', undef,
"<ltx:TOC lists='lot' scope='global'><ltx:title>#name</ltx:title></ltx:TOC>",
properties => sub { (name => Digest(T_CS('\listtablename'))); });
DefPrimitive('\numberline{}{}', undef);
DefPrimitive('\addtocontents{}{}', undef);
DefConstructor('\addcontentsline{}{}{}', sub {
my ($document, $inlist, $type, $title) = @_;
# Note that the node can be inlist $inlist.
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
#======================================================================
# C.5.2 Packages
#======================================================================
# We'll prefer to load package.pm, but will try package.sty or
# package.tex (the latter being unlikely to work, but....)
# See Stomach.pm for details
# Ignorable packages ??
# pre-defined packages??
DefMacroI('\@clsextension', undef, 'cls');
DefMacroI('\@pkgextension', undef, 'sty');
Let('\@currext', '\@empty');
Let('\@currname', '\@empty');
Let('\@classoptionslist', '\relax');
Let('\@raw@classoptionslist', '\relax');
# Note that there are variables used in Package.pm for these,
# but they are NOT tied to these macros. Do they need to be?
DefMacroI('\@declaredoptions', undef, Tokens());
DefMacroI('\@curroptions', undef, undef);
DefMacroI('\@unusedoptionlist', undef, Tokens());
DefConstructor('\usepackage OptionalSemiverbatim Semiverbatim []',
"<?latexml package='#2' ?#1(options='#1')?>",
beforeDigest => sub { onlyPreamble('\usepackage'); },
afterDigest => sub { my ($stomach, $whatsit) = @_;
my $options = $whatsit->getArg(1);
my $packages = $whatsit->getArg(2);
$options = [($options ? split(/\s*,\s*/, (ToString($options))) : ())];
for my $pkg (split(',', ToString($packages))) {
$pkg =~ s/\s+//g;
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
afterDigest => sub { my ($stomach, $whatsit) = @_;
my $options = $whatsit->getArg(1);
my $class = ToString($whatsit->getArg(2));
$class =~ s/\s+//g;
$options = [($options ? split(/\s*,\s*/, (ToString($options))) : ())];
LoadClass($class, options => $options);
return; });
# Related internal macros for package definition
# Internals used in Packages
DefMacro('\NeedsTeXFormat{}[]', Tokens());
DefPrimitive('\ProvidesClass{}[]', sub {
my ($stomach, $class, $version) = @_;
DefMacroI("\\ver@" . ToString($class) . ".cls", undef, $version || Tokens(), scope => 'global');
return; });
# Note that these, like LaTeX, define macros like \var@mypkg.sty to give the version info.
DefMacro('\ProvidesPackage{}[]', sub {
my ($stomach, $package, $version) = @_;
DefMacroI("\\ver@" . ToString($package) . ".sty", undef, $version || Tokens(), scope => 'global');
return; });
DefMacro('\ProvidesFile{}[]', sub {
my ($stomach, $file, $version) = @_;
DefMacroI("\\ver@" . ToString($file), undef, $version || Tokens(), scope => 'global');
return; });
#\DeclareRelease{v4.46}{2020-03-19}{glossaries-2020-03-19.sty}
DefMacro('\DeclareRelease{}{}{}', sub {
my ($stomach, $version, $date, $name) = @_;
# anything useful?
return (); });
#\DeclareCurrentRelease{v4.49}{2021-11-01}
DefMacro('\DeclareCurrentRelease{}{}', sub {
my ($stomach, $version, $date) = @_;
# anything useful?
return (); });
DefMacro('\IncludeInRelease{}{}{} Until:\EndIncludeInRelease', sub {
# anything useful?
return (); });
DefMacro('\NewModuleRelease{}{}{} Until:\EndModuleRelease', sub {
# anything useful?
return (); });
DefPrimitive('\DeclareOption{}{}', sub {
my ($stomach, $option, $code) = @_;
((ToString($option) eq '*') ?
DeclareOption(undef, $code) :
DeclareOption(ToString($option), $code)); });
DefPrimitive('\PassOptionsToPackage{}{}', sub {
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
my $class = ToString($whatsit->getArg(1));
$class =~ s/\s+//g;
LoadClass($class, withoptions => 1);
return; });
DefPrimitive('\@onefilewithoptions {} [][] {}', sub {
my ($stomach, $name, $option1, $option2, $ext) = @_;
InputDefinitions(ToString(Expand($name)), type => ToString(Expand($ext)), options => $option1);
return; });
DefMacroI('\CurrentOption', undef, Tokens());
DefPrimitiveI('\OptionNotUsed', undef, sub {
if (my $option = ToString(Expand(T_CS('\CurrentOption')))) {
my $type = ToString(Expand(T_CS('\@currext')));
if ($type eq 'cls') {
PushValue('@unusedoptionlist', $option); } }
return; });
DefPrimitiveI('\@unknownoptionerror', undef, sub {
if (my $option = ToString(Expand(T_CS('\CurrentOption')))) {
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
Info('unexpected', $option, $_[0], "Unexpected option '$option' passed to $name.$type"); }
return; });
DefPrimitive('\ExecuteOptions{}', sub {
my ($gullet, $options) = @_;
ExecuteOptions(split(/\s*,\s*/, ToString(Expand($options)))); });
DefPrimitive('\ProcessOptions OptionalMatch:*', sub {
my ($stomach, $star) = @_;
ProcessOptions(($star ? (inorder => 1) : ())); });
DefMacro('\@options', '\ProcessOptions*');
Let('\@enddocumenthook', '\@empty');
DefMacro('\AtEndOfPackage{}', sub {
my ($gullet, $code) = @_;
my $name = ToString(Expand(T_CS('\@currname')));
my $type = ToString(Expand(T_CS('\@currext')));
AddToMacro(T_CS('\\' . $name . '.' . $type . '-h@@k'), $code); });
DefMacro('\@ifpackageloaded', '\@ifl@aded\@pkgextension');
Let('\ltx@ifpackageloaded', '\@ifpackageloaded');
DefMacro('\@ifclassloaded', '\@ifl@aded\@clsextension');
Let('\ltx@ifclassloaded', '\@ifclassloaded');
DefMacro('\@ifl@aded{}{}', sub {
my ($gullet, $ext, $name) = @_;
my $path = ToString(Expand($name)) . '.' . ToString(Expand($ext));
# If EITHER the raw TeX or ltxml version of this file was loaded.
if (LookupValue($path . '_loaded') || LookupValue($path . '.ltxml_loaded')) {
T_CS('\@firstoftwo'); }
else {
T_CS('\@secondoftwo'); } });
DefMacro('\@ifpackagewith', '\@if@ptions\@pkgextension');
DefMacro('\@ifclasswith', '\@if@ptions\@clsextension');
DefMacro('\@if@ptions{}{}{}', sub {
my ($gullet, $ext, $name, $option) = @_;
$option = ToString(Expand($option));
my $values = LookupValue('opt@' . ToString(Expand($name)) . '.' . ToString(Expand($ext)));
if (grep { $option eq $_ } @$values) {
T_CS('\@firstoftwo'); }
else {
T_CS('\@secondoftwo'); } });
DefMacro('\@ptionlist {}', '\@ifundefined{opt@#1}\@empty{\csname opt@#1\endcsname}');
DefMacro('\g@addto@macro DefToken {}', sub { AddToMacro($_[1], $_[2]); });
DefMacro('\addto@hook DefToken {}', '#1\expandafter{\the#1#2}');
# Alas, we're not tracking versions, so we'll assume it's "later" & cross fingers....
DefMacro('\@ifpackagelater{}{}{}{}', '#3');
DefMacro('\@ifclasslater{}{}{}{}', '#3');
Let('\AtEndOfClass', '\AtEndOfPackage');
DefMacro('\AtBeginDvi {}', Tokens());
RawTeX(<<'EoTeX');
\def\@ifl@t@r#1#2{%
\ifnum\expandafter\@parse@version@#1//00\@nil<%
\expandafter\@parse@version@#2//00\@nil
\expandafter\@secondoftwo
\else
\expandafter\@firstoftwo
\fi}
\def\@parse@version@#1{\@parse@version0#1}
\def\@parse@version#1/#2/#3#4#5\@nil{%
\@parse@version@dash#1-#2-#3#4\@nil
}
\def\@parse@version@dash#1-#2-#3#4#5\@nil{%
\if\relax#2\relax\else#1\fi#2#3#4 }
EoTeX
#======================================================================
# Somewhat related I/O stuff
DefMacro('\filename@parse{}', sub {
my ($gullet, $pathname) = @_;
my ($dir, $name, $ext) = pathname_split(ToString(Expand($pathname)));
$dir .= '/' if $dir;
DefMacroI('\filename@area', undef, Tokens(ExplodeText($dir)));
DefMacroI('\filename@base', undef, Tokens(ExplodeText($name)));
DefMacroI('\filename@ext', undef, ($ext ? Tokens(ExplodeText($ext)) : T_CS('\relax'))); });
DefMacroI('\@filelist', undef, Tokens());
DefMacro('\@addtofilelist{}', sub {
DefMacroI('\@filelist', undef,
Expand(T_CS('\@filelist'), T_OTHER(','), $_[1]->unlist)); });
#======================================================================
# C.5.3 Page Styles
#======================================================================
# Ignored
NewCounter('page');
DefPrimitive('\pagestyle{}', undef);
DefPrimitive('\thispagestyle{}', undef);
DefPrimitive('\markright{}', undef);
DefPrimitive('\markboth{}{}', undef);
DefPrimitiveI('\leftmark', undef, undef);
DefPrimitiveI('\rightmark', undef, undef);
DefPrimitive('\pagenumbering{}', undef);
DefMacro('\@mkboth', '\@gobbletwo'); # default, just in case
DefMacro('\ps@empty',
'\let\@mkboth\@gobbletwo\let\@oddhead\@empty\let\@oddfoot\@empty' .
'\let\@evenhead\@empty\let\@evenfoot\@empty');
DefMacro('\ps@plain', '\let\@mkboth\@gobbletwo' .
'\let\@oddhead\@empty\def\@oddfoot{\reset@font\hfil\thepage' .
'\hfil}\let\@evenhead\@empty\let\@evenfoot\@oddfoot');
Let(T_CS('\@leftmark'), T_CS('\@firstoftwo'));
Let(T_CS('\@rightmark'), T_CS('\@secondoftwo'));
# In normal latex, these should \clearpage; at least we want new paragraph?
# Optional arg is sortof a heading, but w/o any particular styling(?)
DefMacro('\twocolumn[]', '\ifx.#1.\else\par\noindent#1\fi\par');
DefMacro('\onecolumn', '\par');
DefMacro('\@onecolumna', '', locked => 1); # this is trouble in arXiv:cond-mat/0002147
DefMacro('\@twocolumna', '', locked => 1); # this is trouble in arXiv:cond-mat/0002147
# some bits mentioned as "from ltoutput.dtx" in latex.ltx
DefMacro('\@topnewpage{}', '#1');
DefMacro('\@next{}{}{}{}', '\ifx#2\@empty #4\else\expandafter\@xnext #2\@@#1#2#3\fi');
RawTeX('\def\@xnext \@elt #1#2\@@#3#4{\def#3{#1}\gdef#4{#2}}');
Let('\@elt', '\relax'); # ?
DefMacro('\@freelist', ''); # ?
DefMacro('\@currbox', '');
DefMacro('\@toplist', '');
DefMacro('\@botlist', '');
DefMacro('\@midlist', '');
DefMacro('\@currlist', '');
DefMacro('\@deferlist', '');
DefMacro('\@dbltoplist', '');
DefMacro('\@dbldeferlist', '');
DefMacro('\@startcolumn', '');
# Style parameters from Fig. C.3, p.182
DefRegister('\paperheight' => Dimension('11in'));
DefRegister('\paperwidth' => Dimension('8.5in'));
DefRegister('\textheight' => Dimension('7in'));
DefRegister('\textwidth' => Dimension('6in'));
DefRegister('\topmargin' => Dimension(0));
DefRegister('\headheight' => Dimension(0));
DefRegister('\headsep' => Dimension(0));
DefRegister('\footskip' => Dimension(0));
DefRegister('\footheight' => Dimension(0));
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
DefRegister('\columnwidth' => Dimension('6in'));
DefRegister('\linewidth' => Dimension('6in'));
DefRegister('\baselinestretch' => Dimension(0));
#======================================================================
# C.5.4 The Title Page and Abstract
#======================================================================
# See frontmatter support in TeX.ltxml
Let('\@title', '\@empty');
DefMacro('\title[]{}', '\if.#1.\else\def\shorttitle{#1}\@add@frontmatter{ltx:toctitle}{#1}\fi'
. '\def\@title{#2}\@add@frontmatter{ltx:title}{#2}', locked => 1);
DefMacro('\@date', '\@empty');
DefMacro('\date{}',
'\def\@date{#1}'
. '\@add@frontmatter{ltx:date}[role=creation,'
. 'name={\@ifundefined{datename}{}{\datename}}]{#1}');
DefConstructor('\person@thanks{}', "^ <ltx:contact role='thanks'>#1</ltx:contact>",
alias => '\thanks', mode => 'text');
DefConstructor('\@personname{}', "<ltx:personname>#1</ltx:personname>",
beforeDigest => sub { Let('\thanks', '\person@thanks'); },
bounded => 1, mode => 'text');
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
$new_text =~ s/[^\w)(}{\]\[]+$//;
if ($last_text ne $new_text) {
$last->setData($new_text); } } }
return; });
DefConstructorI('\and', undef, " and ");
AssignValue(NUMBER_OF_AUTHORS => 0);
DefPrimitive('\lx@count@author', sub {
AssignValue(NUMBER_OF_AUTHORS => LookupValue('NUMBER_OF_AUTHORS') + 1, 'global') });
DefMacro('\lx@author{}',
'\lx@count@author'
. '\@add@frontmatter{ltx:creator}[role=author]{\lx@author@prefix\@personname{#1}}');
DefConstructor('\lx@@@contact{}{}', "^ <ltx:contact role='#1'>#2</ltx:contact>");
DefMacro('\lx@contact{}{}',
'\@add@to@frontmatter{ltx:creator}{\lx@@@contact{#1}{#2}}');
DefMacro('\lx@author@sep', '\qquad');
DefMacro('\lx@author@conj', '\qquad');
DefConstructor('\lx@author@prefix', sub {
my ($document) = @_;
my $node = $document->getElement;
my $nauthors = LookupValue('NUMBER_OF_AUTHORS');
my $i = scalar(@{ $document->findnodes('//ltx:creator[@role="author"]') });
if ($i <= 1) { }
elsif ($i == $nauthors) {
$document->setAttribute($node, before => ToString(Digest(T_CS('\lx@author@conj')))); }
else {
$document->setAttribute($node, before => ToString(Digest(T_CS('\lx@author@sep')))); }
});
DefMacro('\@author', '\@empty');
DefMacro('\author[]{}', '\def\@author{#2}\lx@make@authors@anded{#2}', locked => 1);
DefMacro('\lx@make@authors@anded{}', sub { andSplit(T_CS('\lx@author'), $_[1]); });
DefPrimitive('\ltx@authors@oneline', sub {
AssignMapping('DOCUMENT_CLASSES', ltx_authors_1line => 1);
return; });
DefPrimitive('\ltx@authors@multiline', sub {
AssignMapping('DOCUMENT_CLASSES', ltx_authors_multiline => 1);
return; });
DefMacro('\@add@conversion@date', '\@add@frontmatter{ltx:date}[role=creation]{\today}');
# Doesn't produce anything (we're already inserting frontmatter),
# But, it does make the various frontmatter macros into no-ops.
DefMacroI('\maketitle', undef,
'\lx@frontmatterhere'
. '\@startsection@hook'
. '\global\let\thanks\relax'
. '\global\let\maketitle\relax'
. '\global\let\@maketitle\relax'
. '\global\let\@thanks\@empty'
. '\global\let\@author\@empty'
. '\global\let\@date\@empty'
. '\global\let\@title\@empty'
. '\global\let\title\relax'
. '\global\let\author\relax'
. '\global\let\date\relax'
. '\global\let\and\relax', locked => 1);
DefMacro('\@thanks', '\@empty');
# make a throwaway optional argument available for OmniBus use
DefMacro('\thanks[]{}', '\def\@thanks{#2}\lx@make@thanks{#2}');
DefConstructor('\lx@make@thanks{}', "<ltx:note role='thanks'>#1</ltx:note>");
# Abstract SHOULD have been so simple, but seems to be a magnet for abuse.
# For one thing, we'd like to just write
# DefEnvironment('{abstract}','<ltx:abstract>#body</ltx:abstract>');
# However, we don't want to place the <ltx:abstract> environment directly where
# we found it, but we want to add it to frontmatter. This requires capturing the
# recently digested list and storing it in the frontmatter structure.
# The really messy stuff comes from the way authors -- and style designers -- misuse it.
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
DefEnvironment('{abstract}', '',
afterDigestBegin => sub {
AssignValue(inPreamble => 0); },
afterDigest => sub {
my $frontmatter = LookupValue('frontmatter');
push(@{ $$frontmatter{'ltx:abstract'} },
['ltx:abstract',
{ name => Digest(Tokens(T_CS('\format@title@abstract'),
T_BEGIN, T_CS('\abstractname'), T_END)) },
@LaTeXML::LIST]);
DefMacroI('\maybe@end@abstract', undef, Tokens(), scope => 'global');
return; },
afterConstruct => sub { insertFrontMatter(@_); }, # HERE if not already done.
locked => 1, mode => 'text');
# If we get a plain \abstract, instead of an environment, look for \abstract{the abstract}
AssignValue('\abstract:locked' => 0); # REDEFINE the above locked definition!
DefMacro('\abstract', sub {
my ($gullet) = @_;
($gullet->ifNext(T_BEGIN)
? (T_CS('\abstract@onearg'))
: (T_CS('\g@addto@macro'), T_CS('\@startsection@hook'), T_CS('\maybe@end@abstract'),
T_CS('\begin{abstract}'))); },
locked => 1);
DefMacro('\abstract@onearg{}', '\begin{abstract}#1\end{abstract}\let\endabstract\relax');
DefMacroI('\maybe@end@abstract', undef, '\endabstract');
DefMacroI('\abstractname', undef, 'Abstract');
DefMacro('\format@title@abstract{}', '#1');
# Hmm, titlepage is likely to be hairy, low-level markup,
# without even title, author, etc, specified as such!
# Hmm, should this even redefine author, title, etc so that they
# are simply output?
# This is horrible hackery; What we really need, I think, is the
# ability to bind some sort of "Do <this> when we create a text box"...
# ON Second Thought...
# For the time being, ignore titlepage!
# Maybe we could do some of this if there is no title/author
# otherwise defined? Ugh!
#DefEnvironment('{titlepage}','');
# Or perhaps it's better just to ignore the markers?
#DefMacro('\titlepage','');
#DefMacro('\endtitlepage','');
# Or perhaps not....
# There's a title and other stuff in here, but how could we guess?
# Well, there's likely to be a sequence of <p><text font="xx" fontsize="yy">...</text></p>
# Presumably the earlier, larger one is title, rest are authors/affiliations...
# Particularly, if they start with a pseudo superscript or other "marker", they're probably affil!
# For now, we just give an info message
DefEnvironment('{titlepage}', '<ltx:titlepage>#body',
beforeDigest => sub { Let('\centering', '\relax');
AssignValue(frontmatter_deferred => 1, 'global');
AddToMacro(T_CS('\maketitle'), T_CS('\unwind@titlepage'));
DefEnvironmentI('abstract', undef,
'<ltx:abstract>#body</ltx:abstract>');
Info('unexpected', 'titlepage', $_[0],
"When using titlepage, Frontmatter will not be well-structured");
return; },
beforeDigestEnd => sub { Digest(T_CS('\maybe@end@titlepage')); },
afterConstruct => sub { insertFrontMatter($_[0]); },
locked => 1, mode => 'text');
Tag('ltx:titlepage', autoClose => 1);
DefConstructorI('\maybe@end@titlepage', undef, sub {
my ($document) = @_;
$document->maybeCloseElement('ltx:titlepage'); });
DefConstructorI('\unwind@titlepage', undef, sub {
my ($document) = @_;
if (my $titlepage = $document->maybeCloseElement('ltx:titlepage')) {
$document->unwrapNodes($titlepage);
}
});
DefMacro('\sectionmark{}', Tokens());
DefMacro('\subsectionmark{}', Tokens());
DefMacro('\subsubsectionmark{}', Tokens());
DefMacro('\paragraphmark{}', Tokens());
DefMacro('\subparagraphmark{}', Tokens());
DefMacroI('\@oddfoot', undef, Tokens());
DefMacroI('\@oddhed', undef, Tokens());
DefMacroI('\@evenfoot', undef, Tokens());
DefMacroI('\@evenfoot', undef, Tokens());
#**********************************************************************
# C.6 Displayed Paragraphs
#**********************************************************************
DefEnvironment('{center}', sub {
$_[0]->maybeCloseElement('ltx:p'); # this starts a new vertical block
aligningEnvironment('center', 'ltx_centering', @_); }); # aligning will take care of \\\\ "rows"
# HOWEVER, define a plain \center to act like \centering (?)
DefMacroI('\center', undef, '\centering');
DefMacroI('\endcenter', undef, '');
DefEnvironment('{flushleft}', sub {
$_[0]->maybeCloseElement('ltx:p'); # this starts a new vertical block
aligningEnvironment('left', 'ltx_align_left', @_); });
DefEnvironment('{flushright}', sub {
$_[0]->maybeCloseElement('ltx:p'); # this starts a new vertical block
aligningEnvironment('right', 'ltx_align_right', @_); });
# These add an operation to be carried out on the current node & following siblings, when the current group ends.
# These operators will add alignment (class) attributes to each "line" in the current block.
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
# These are for the (not quite legit) case where \item appears outside
# of an itemize, enumerate, etc, environment.
# DefConstructor('\item[]',
# "<ltx:item>?&defined(#1)(<ltx:tags><ltx:tag>#1</ltx:tag></ltx:tags>)");
# DefConstructor('\subitem[]',
# "<ltx:item>?&defined(#1)(<ltx:tags><ltx:tag>#1</ltx:tag></ltx:tags>)");
# DefConstructor('\subsubitem[]',
# "<ltx:item>?&defined(#1)(<ltx:tags><ltx:tag>#1</ltx:tag></ltx:tags>)");
# Or maybe best just to do \par ?
DefMacro('\item[]', '\par');
DefMacro('\subitem[]', '\par');
DefMacro('\subsubitem[]', '\par');
AssignValue('@itemlevel' => 0, 'global');
AssignValue('enumlevel' => 0, 'global');
AssignValue('@desclevel' => 0, 'global');
# protection against lower-level code...
DefConditional('\if@noitemarg');
DefMacro('\@item', '\item'); # Hopefully no circles...
DefMacro('\@itemlabel', ''); # Maybe needs to be same as \item will be using?
# Prepare for an list (itemize/enumerate/description/etc)
# by determining the right counter (level)
# and binding the right \item ( \$type@item, if $type is defined)
sub beginItemize {
my ($type, $counter, %options) = @_;
# The list-type and level of the *containing* list (if any!)
my $outercounter = LookupValue('itemcounter');
my $outerlevel = $outercounter && (LookupValue($outercounter . 'level') || 0);
$counter = '@item' unless $counter;
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
$level++ unless $options{nolevel};
AssignRegister('\itemsep' => LookupDimension('\lx@default@itemsep'));
AssignValue('itemization_level' => $listlevel);
AssignValue($counter . 'level' => $level);
AssignValue(itemization_items => 0);
my $listpostfix = ToString(Tokens(roman($listlevel)));
my $postfix = ToString(Tokens(roman($level)));
my $usecounter = ($options{nolevel} ? $counter : $counter . $postfix);
Let('\item' => "\\" . $type . '@item') if defined $type;
Let('\par', '\normal@par'); # In case within odd environment.
DefMacroI('\@listctr', undef, Tokens(Explode($usecounter)));
# Now arrange that this list's id's are relative to the current (outer) item (if any)
# And that the items within this list's id's are relative to this (new) list.
## if(! LookupDefinition(T_CS('\@listcontext'))){
## Let(T_CS('\@listcontext'), T_CS('\@currentlabel')); }
AssignValue(itemcounter => $usecounter);
my $listcounter = '@itemize' . $listpostfix;
if (!LookupDefinition(T_CS('\c@' . $listcounter))) { # Create new list counters as needed
NewCounter($listcounter); } #, $outercounter.ToString(Tokens(roman($outerlevel))),
if ($outercounter) { # Make this list's ID relative to outer list's ID
my $outerusecounter = $outercounter . ToString(Tokens(roman($outerlevel)));
DefMacroI('\the' . $listcounter . '@ID', undef,
'\the' . $outerusecounter . '@ID.I' . '\arabic{' . $listcounter . '}');
# AND reset this list's counter when the outer item is stepped
my $x;
AssignValue("\\cl\@$outerusecounter" =>
Tokens(T_CS($listcounter), (($x = LookupValue('\cl@' . $outerusecounter)) ? $x->unlist : ())),
'global');
}
# format the id of \item's relative to the id of this list
DefMacroI(T_CS('\the' . $usecounter . '@ID'), undef,
Tokens(T_CS('\the' . $listcounter . '@ID'), T_OTHER('.i'), T_CS('\@' . $usecounter . '@ID')));
my $series;
if ($series = $options{series}) {
$series = ToString($series); }
if (my $start = $options{start}) {
SetCounter($usecounter, $start);
AddToCounter($usecounter, Number(-1)); }
elsif (my $s = $options{resume} || $options{'resume*'}) {
if (($s = ToString($s)) ne 'noseries') {
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
# This isn't really satisfactory.
# We should record the marker used for the item,
# but it really should NOT be #refnum (which should be quasi unique)
# and is not \theenumi.. (which should be a counter value)
sub setItemizationStyle {
my ($stuff, $level) = @_;
if (defined $stuff) {
$level = LookupValue('@itemlevel') || 0 unless defined $level;
$level = ToString(Tokens(roman($level)));
DefMacroI('\labelitem' . $level, undef, $stuff); }
return; }
sub setEnumerationStyle {
my ($stuff, $level) = @_;
if (defined $stuff) {
$level = LookupValue('enumlevel') || 0 unless defined $level;
$level = ToString(Tokens(roman($level)));
my @in = $stuff->unlist;
my @out = ();
my $ctr = T_OTHER('enum' . $level);
while (my $t = shift(@in)) {
if (Equals($t, T_BEGIN)) {
push(@out, $t);
my $brlevel = 1;
while ($brlevel && ($t = shift(@in))) {
if (Equals($t, T_BEGIN)) { $brlevel++; }
elsif (Equals($t, T_END)) { $brlevel--; }
push(@out, $t); } }
elsif (Equals($t, T_LETTER('A'))) {
DefMacroI('\theenum' . $level, undef, Invocation(T_CS('\Alph'), $ctr));
push(@out, T_CS('\theenum' . $level)); }
elsif (Equals($t, T_LETTER('a'))) {
DefMacroI('\theenum' . $level, undef, Invocation(T_CS('\alph'), $ctr));
push(@out, T_CS('\theenum' . $level)); }
elsif (Equals($t, T_LETTER('I'))) {
DefMacroI('\theenum' . $level, undef, Invocation(T_CS('\Roman'), $ctr));
push(@out, T_CS('\theenum' . $level)); }
elsif (Equals($t, T_LETTER('i'))) {
DefMacroI('\theenum' . $level, undef, Invocation(T_CS('\roman'), $ctr));
push(@out, T_CS('\theenum' . $level)); }
elsif (Equals($t, T_OTHER('1'))) {
DefMacroI('\theenum' . $level, undef, Invocation(T_CS('\arabic'), $ctr));
push(@out, T_CS('\theenum' . $level)); }
else {
push(@out, $t); } }
DefMacroI('\labelenum' . $level, undef, Tokens(T_BEGIN, @out, T_END)); }
return; }
# End paragraphs, like \par, but only if within an item's text
DefConstructorI('\preitem@par', undef, sub {
my ($document, %props) = @_;
if (!$props{inPreamble} && !$document->getNodeQName($document->getElement(), 'ltx:itemize')) {
$document->maybeCloseElement('ltx:p');
$document->maybeCloseElement('ltx:para'); } },
alias => '\par');
# id, but NO refnum (et.al) attributes on itemize \item ...
# unless the optional tag argument was given!
# We'll make the <ltx:tag> from either the optional arg, or from \labelitemi..
DefMacro('\itemize@item', '\preitem@par\itemize@item@');
DefConstructor('\itemize@item@ OptionalUndigested',
"<ltx:item xml:id='#id' itemsep='#itemsep'>#tags",
properties => sub { RefStepItemCounter($_[1]); });
DefConstructor('\inline@itemize@item OptionalUndigested',
"<ltx:inline-item xml:id='#id'>#tags",
properties => sub { RefStepItemCounter($_[1]); });
DefMacro('\enumerate@item', '\preitem@par\enumerate@item@');
DefConstructor('\enumerate@item@ OptionalUndigested',
"<ltx:item xml:id='#id' itemsep='#itemsep'>#tags",
properties => sub { RefStepItemCounter($_[1]); });
DefConstructor('\inline@enumerate@item OptionalUndigested',
"<ltx:inline-item xml:id='#id'>#tags",
properties => sub { RefStepItemCounter($_[1]); });
DefMacro('\description@item', '\preitem@par\description@item@');
DefConstructor('\description@item@ OptionalUndigested',
"<ltx:item xml:id='#id' itemsep='#itemsep'>#tags",
properties => sub { RefStepItemCounter($_[1]); });
DefConstructor('\inline@description@item OptionalUndigested',
"<ltx:inline-item xml:id='#id'>#tags",
properties => sub { RefStepItemCounter($_[1]); });
DefEnvironment('{itemize}',
"<ltx:itemize xml:id='#id'>#body</ltx:itemize>",
properties => sub { beginItemize('itemize', '@item'); },
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
properties => sub { beginItemize('enumerate', 'enum'); },
beforeDigestEnd => sub { Digest('\par'); },
locked => 1, mode => 'text');
DefEnvironment('{description}',
"<ltx:description xml:id='#id'>#body</ltx:description>",
beforeDigest => sub { Let('\makelabel', '\descriptionlabel'); },
properties => sub { beginItemize('description', '@desc'); },
beforeDigestEnd => sub { Digest('\par'); },
locked => 1, mode => 'text');
DefMacro('\makelabel{}', '#1');
DefMacro('\@mklab{}', '\hfil #1');
#----------------------------------------------------------------------
# Basic itemize bits
# Fake counter for itemize to give id's to ltx:item.
NewCounter('@itemi', undef, idwithin => '@itemizei', idprefix => 'i');
NewCounter('@itemii', undef, idwithin => '@itemi', idprefix => 'i');
NewCounter('@itemiii', undef, idwithin => '@itemii', idprefix => 'i');
NewCounter('@itemiv', undef, idwithin => '@itemiii', idprefix => 'i');
NewCounter('@itemv', undef, idwithin => '@itemiv', idprefix => 'i');
NewCounter('@itemvi', undef, idwithin => '@itemv', idprefix => 'i');
# These are empty to make the 'refnum' go away.
DefMacroI('\the@itemi', undef, '');
DefMacroI('\the@itemii', undef, '');
DefMacroI('\the@itemiii', undef, '');
DefMacroI('\the@itemiv', undef, '');
DefMacroI('\the@itemv', undef, '');
DefMacroI('\the@itemvi', undef, '');
# Formatted item tags.
# Really should be in the class file, but already was here.
DefMacroI('\labelitemi', undef, '\textbullet');
DefMacroI('\labelitemii', undef, '\normalfont\bfseries \textendash');
DefMacroI('\labelitemiii', undef, '\textasteriskcentered');
DefMacroI('\labelitemiv', undef, '\textperiodcentered');
# Make the fake counters point to the real labels
DefMacroI('\label@itemi', undef, '\labelitemi');
DefMacroI('\label@itemii', undef, '\labelitemii');
DefMacroI('\label@itemiii', undef, '\labelitemiii');
DefMacroI('\label@itemiv', undef, '\labelitemiv');
# These hookup latexml's tagging to normal latex's \labelitemi...
DefMacroI('\fnum@@itemi', undef, '{\makelabel{\label@itemi}}');
DefMacroI('\fnum@@itemii', undef, '{\makelabel{\label@itemii}}');
DefMacroI('\fnum@@itemiii', undef, '{\makelabel{\label@itemiii}}');
DefMacroI('\fnum@@itemiv', undef, '{\makelabel{\label@itemiv}}');
# These define the typerefnum form, for out-of-context \ref's
# Better would language sensitive!
my @pm_ordinal_suffices = ('th', 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th');
DefMacro('\lx@poormans@ordinal{}', sub {
my ($gullet, $ctr) = @_;
my $n = CounterValue($ctr)->valueOf;
my $string = "$n";
if ($string =~ /.*?(\d)$/) {
$string .= $pm_ordinal_suffices[$1]; }
T_OTHER($string); });
DefMacroI('\itemtyperefname', undef, 'item');
DefMacroI('\itemcontext', undef, '\space in \@listcontext');
DefMacroI('\itemcontext', undef, '');
# Probably would help to give a bit more context for the ii & higher?
DefMacroI('\typerefnum@@itemi', undef, '\lx@poormans@ordinal{@itemi} \itemtyperefname \itemcontext');
DefMacroI('\typerefnum@@itemii', undef, '\lx@poormans@ordinal{@itemii} \itemtyperefname \itemcontext');
DefMacroI('\typerefnum@@itemiii', undef, '\lx@poormans@ordinal{@itemiii} \itemtyperefname \itemcontext');
DefMacroI('\typerefnum@@itemiv', undef, '\lx@poormans@ordinal{@itemiv} \itemtyperefname \itemcontext');
#----------------------------------------------------------------------
# Basic enumeration bits
# Class file normally would have
# NewCounter for enumi,...,
# define \labelenumi,... and probably \p@enumii...
NewCounter('enumi', undef, idwithin => '@itemizei', idprefix => 'i');
NewCounter('enumii', undef, idwithin => 'enumi', idprefix => 'i');
NewCounter('enumiii', undef, idwithin => 'enumii', idprefix => 'i');
NewCounter('enumiv', undef, idwithin => 'enumiii', idprefix => 'i');
NewCounter('enumv', undef, idwithin => 'enumiv', idprefix => 'i'); # A couple of extra
NewCounter('enumvi', undef, idwithin => 'enumv', idprefix => 'i');
# How the refnums look... (probably should be in class file, but already here)
DefMacroI('\p@enumii', undef, '\theenumi');
DefMacroI('\p@enumiii', undef, '\theenumi(\theenumii)');
DefMacroI('\p@enumiv', undef, '\p@enumii\theenumiii');
# Formatting of item tags (probably should be in the class file, but already here)
DefMacroI('\labelenumi', undef, '\theenumi.');
DefMacroI('\labelenumii', undef, '(\theenumii)');
DefMacroI('\labelenumiii', undef, '\theenumiii.');
DefMacroI('\labelenumiv', undef, '\theenumiv.');
# These hookup latexml's tagging to normal latex's \labelenummi...
DefMacroI('\fnum@enumi', undef, '{\makelabel{\labelenumi}}');
DefMacroI('\fnum@enumii', undef, '{\makelabel{\labelenumii}}');
DefMacroI('\fnum@enumiii', undef, '{\makelabel{\labelenumiii}}');
DefMacroI('\fnum@enumiv', undef, '{\makelabel{\labelenumiv}}');
# These define the typerefnum form, for out-of-context \ref's
DefMacroI('\enumtyperefname', undef, 'item');
DefMacroI('\typerefnum@enumi', undef, '\enumtyperefname~\p@enumi\theenumi \itemcontext');
DefMacroI('\typerefnum@enumii', undef, '\enumtyperefname~\p@enumii\theenumii \itemcontext');
DefMacroI('\typerefnum@enumiii', undef, '\enumtyperefname~\p@enumiii\theenumiii \itemcontext');
DefMacroI('\typerefnum@enumiv', undef, '\enumtyperefname~\p@enumiv\theenumiv \itemcontext');
#DefMacroI('\typerefnum@enumi', undef, '\enumtyperefname~\p@enumi\labelenumi \itemcontext');
#DefMacroI('\typerefnum@enumii', undef, '\enumtyperefname~\p@enumii\labelenumii \itemcontext');
#DefMacroI('\typerefnum@enumiii', undef, '\enumtyperefname~\p@enumiii\labelenumiii \itemcontext');
#DefMacroI('\typerefnum@enumiv', undef, '\enumtyperefname~\p@enumiv\labelenumiv \itemcontext');
#----------------------------------------------------------------------
# Basic description list bits
# Fake counter for itemize to give id's to ltx:item.
NewCounter('@desci', undef, idwithin => '@itemizei', idprefix => 'i');
NewCounter('@descii', undef, idwithin => '@desci', idprefix => 'i');
NewCounter('@desciii', undef, idwithin => '@descii', idprefix => 'i');
NewCounter('@desciv', undef, idwithin => '@desciii', idprefix => 'i');
NewCounter('@descv', undef, idwithin => '@desciv', idprefix => 'i');
NewCounter('@descvi', undef, idwithin => '@descv', idprefix => 'i');
# No refnum's here, either
DefMacroI('\the@desci', undef, '');
DefMacroI('\the@descii', undef, '');
DefMacroI('\the@desciii', undef, '');
DefMacroI('\the@desciv', undef, '');
DefMacroI('\the@descv', undef, '');
DefMacroI('\the@descvi', undef, '');
# These hookup latexml's numbering to normal latex's
# Umm.... but they're not normally used, since \item usually gets an argument!
DefMacro('\descriptionlabel{}', '\normalfont\bfseries #1');
DefMacroI('\fnum@@desci', undef, '{\descriptionlabel{}}');
DefMacroI('\fnum@@descii', undef, '{\descriptionlabel{}}');
DefMacroI('\fnum@@desciii', undef, '{\descriptionlabel{}}');
DefMacroI('\fnum@@desciv', undef, '{\descriptionlabel{}}');
DefMacroI('\desctyperefname', undef, 'item');
# Blech
map { DefMacroI(T_CS('\\' . $_ . 'name'), undef, '\itemtyperefname'); }
qw(@itemi @itemii @itemiii @itemiv @itemv @itemvi);
map { DefMacroI(T_CS('\\' . $_ . 'name'), undef, '\enumtyperefname'); }
qw(enumi enumii enumiii enumiv);
map { DefMacroI(T_CS('\\' . $_ . 'name'), undef, '\desctyperefname'); }
qw(@desci @descii @desciii @desciv @descv @descvi);
#======================================================================
# C.6.3 The list and trivlist environments.
#======================================================================
# Generic lists are given a way to format the item label, and presumably
# a counter.
DefConditional('\if@nmbrlist');
DefMacro('\@listctr', '');
DefPrimitive('\usecounter{}', sub {
my ($stomach, $counter) = @_;
$counter = ToString(Expand($counter));
beginItemize('list', $counter, ($counter ? (nolevel => 1) : ()));
return; });
DefMacro('\list{}{}',
'\let\@listctr\@empty#2\ifx\@listctr\@empty\usecounter{}\fi\expandafter\def\csname fnum@\@listctr\endcsname{#1}\lx@list');
DefMacro('\endlist', '\endlx@list');
# Start an anonymous list (often misused)
DefConstructor('\lx@list',
"<ltx:itemize>",
beforeDigest => sub { $_[0]->bgroup; });
# Close the anonymous list if we're still within one.
DefConstructor('\endlx@list', sub {
$_[0]->maybeCloseElement('ltx:itemize'); },
beforeDigest => sub { $_[0]->egroup; });
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
# This isn't quite right, although it seems right for deep, internal uses with a single \item.
# Perhaps we need to check trivlist's afterwards and if they are just a single item,
# reduce it to an ltx:p ??
DefConstructor('\trivlist',
"<ltx:itemize _autoclose='1'>",
properties => sub { beginItemize('trivlist'); });
DefConstructor('\endtrivlist', sub {
$_[0]->maybeCloseElement('ltx:itemize'); },
beforeDigest => sub { Digest('\par'); });
DefMacro('\trivlist@item', '\preitem@par\trivlist@item@');
DefConstructor('\trivlist@item@ OptionalUndigested',
"<ltx:item xml:id='#id' itemsep='#itemsep'>"
. "<ltx:tags><ltx:tag>#tag</ltx:tag></ltx:tags>", # At least an empty tag! ?
properties => sub { ($_[1] ? (tag => Digest(Expand($_[1]))) : ()); });
DefMacro('\@trivlist', '\relax', locked => 1);
DefRegister('\topsep' => Glue(0));
DefRegister('\partopsep' => Glue(0));
DefRegister('\lx@default@itemsep' => Glue(0));
DefRegister('\itemsep' => Glue(0));
DefRegister('\parsep' => Glue(0));
DefRegister('\@topsep' => Glue(0));
DefRegister('\@topsepadd' => Glue(0));
DefRegister('\@outerparskip' => Glue(0));
DefRegister('\leftmargin' => Dimension(0));
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
DefRegister('\@itemdepth' => Number(0));
#======================================================================
# C.6.4 Verbatim
#======================================================================
# NOTE: how's the best way to get verbatim material through?
#DefEnvironment('{verbatim}', '<ltx:verbatim>#body</ltx:verbatim>');
#DefEnvironment('{verbatim*}', '<ltx:verbatim>#body</ltx:verbatim>');
DefMacroI('\@verbatim', undef,
'\par\aftergroup\lx@end@verbatim\lx@@verbatim'); # Close enough?
DefConstructorI('\lx@@verbatim', undef,
"<ltx:verbatim font='#font'>",
beforeDigest => sub {
my ($stomach) = @_;
StartSemiverbatim('%', '\\', '{', '}');
MergeFont(family => 'typewriter', series => 'medium', shape => 'upright');
$STATE->assignCatcode(' ', CC_ACTIVE); # Do NOT (necessarily) skip spaces after \verb!!!
Let(T_ACTIVE(' '), T_SPACE); });
DefConstructorI('\lx@end@verbatim', undef,
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
afterDigest => [sub { afterDigestVerbatim(1, @_); }],
beforeConstruct => sub { $_[0]->maybeCloseElement('ltx:p'); });
sub beforeDigestVerbatim {
my ($starred, $stomach) = @_;
$stomach->bgroup;
my @stuff = ();
if (my $b = LookupValue('@environment@verbatim@atbegin')) {
push(@stuff, Digest(@$b)); }
AssignValue(current_environment => 'verbatim');
DefMacroI('\@currenvir', undef, 'verbatim');
MergeFont(family => 'typewriter');
# Digest(T_CS('\par')); # NO! See beforeConstruct!
return @stuff; }
sub afterDigestVerbatim {
my ($starred, $stomach, $whatsit) = @_;
# $stomach->egroup;
my $font = $whatsit->getFont;
my $loc = $whatsit->getLocator;
my $end = $starred ? '\end{verbatim*}' : '\end{verbatim}';
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
if (my $b = LookupValue('@environment@verbatim@atend')) {
push(@lines, ToString(Digest(@$b))); }
$stomach->egroup;
$whatsit->setBody(map { Box($_, $font, $loc, T_OTHER($_)) } @lines, $end);
return; }
DefPrimitiveI('\@vobeyspaces', undef, sub {
AssignCatcode(" " => 13);
Let(T_ACTIVE(" "), '\nobreakspace');
return });
DefMacro('\@xobeysp', '\nobreakspace');
# WARNING: Need to be careful about what catcodes are active here
# And clearly separate expansion from digestion
DefMacroI('\verb', undef, sub {
my ($gullet) = @_;
StartSemiverbatim('%', '\\', '{', '}');
$STATE->assignCatcode(' ', CC_ACTIVE);
my $init;
my $skippedSpace = 0;
# As of texlive 2021, DO skip spaces before delimiter (even tho we've changed catcodes)
# but if we do skip spaces, * can be the delimiter
do { $init = $gullet->readToken();
$skippedSpace = 1 if (defined $init && $init->getString eq ' ');
} while (defined $init && $init->getString eq ' ');
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
Tokens($init), $body),
T_CS('\@hidden@egroup'))->unlist; });
DefPrimitive('\lx@use@visiblespace', sub {
my ($stomach, $star) = @_;
$STATE->assignCatcode(' ', CC_ACTIVE); # Do NOT (necessarily) skip spaces after \verb!!!
Let(T_ACTIVE(' '), T_OTHER("\x{2423}")); # Visible space
});
# Arrange to digest the body in text mode, to keep (eg) "_" from turning to "\_"
DefMacro('\@internal@verb{}{}{}', '\ifmmode\@internal@math@verb{#1}{#2}{#3}\else\@internal@text@verb{#1}{#2}{#3}\fi');
DefConstructor('\@internal@math@verb{} Undigested {}',
"<ltx:XMTok font='#font'>#3</ltx:XMTok>",
mode => 'text',
font => { family => 'typewriter', series => 'medium', shape => 'upright' },
reversion => '\verb#1#2#3#2');
DefConstructor('\@internal@text@verb{} Undigested {}',
"<ltx:verbatim font='#font'>#3</ltx:verbatim>",
font => { family => 'typewriter', series => 'medium', shape => 'upright' },
beforeConstruct => sub {
my ($doc, $whatsit) = @_;
$doc->canContain($doc->getElement, '#PCDATA') || $doc->openElement('ltx:p'); },
reversion => '\verb#1#2#3#2');
# This is defined by the alltt package.
# Environment('alltt', ?);
# Actually, latex sets catcode to 13 ... is this close enough?
DefPrimitiveI('\obeycr', undef, sub { AssignValue('PRESERVE_NEWLINES' => 1); });
DefPrimitiveI('\restorecr', undef, sub { AssignValue('PRESERVE_NEWLINES' => 0); });
DefMacroI('\normalsfcodes', undef, Tokens());
#**********************************************************************
# C.7 Mathematical Formulas
#**********************************************************************
#======================================================================
# C.7.1 Math Mode Environments
#======================================================================
DefMacroI('\@eqnnum', undef, '(\theequation)', locked => 1);
DefMacro('\fnum@equation', '\@eqnnum');
# Redefined from TeX.pool, since with LaTeX we presumably have a more complete numbering system
DefConstructorI('\@@BEGINDISPLAYMATH', undef,
"<ltx:equation xml:id='#id'>"
. "<ltx:Math mode='display'>"
. "<ltx:XMath>"
. "#body"
. "</ltx:XMath>"
. "</ltx:Math>"
. "</ltx:equation>",
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
mode => 'inline_math',
);
Let('\curr@math@size', '\@empty');
# Equation Numbering turns out to be rather convoluted!
# numbered equations & friends want to IMMEDIATELY increment the equation counter
# (you can see by \theequation)
# However, \nonumber, \tag, set a different number and RETRACT stepping the counter!
NewCounter('subequation', 'equation', idprefix => 'E', idwithin => 'equation');
DefMacro('\thesubequation', '\theequation\alph{subequation}');
DefMacro('\fnum@subequation', '(\thesubequation)');
# This provides {equation} with the capabilities for tags, nonumber, etc
# even though stock LaTeX provides no means to override them.
# preset => boolean
# postset => boolean
# deferretract=>boolean
sub prepareEquationCounter {
my (%options) = @_;
AssignValue(EQUATION_NUMBERING => {%options}, 'global');
return; }
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
# Note peculiar usages of \[,\],$$ WITHIN displayed math, like {equation}.
# Authors sometimes use \begin{equation} math \] some text \[ more math \end{equation}
# to create a cheap intertext. And, the refnum appears on the SECOND equation!
# But in redefining these, note that a "valid" \[ math \] might be used within some
# sort of text insertion (eg \footnote)!
# So, we've got to dance around with redefinitions!!
# SIDE NOTE: \[,\] are really just $$ w/ appropriate error checking!
Let('\lx@saved@BEGINDISPLAYMATH', '\@@BEGINDISPLAYMATH');
Let('\lx@saved@ENDDISPLAYMATH', '\@@ENDDISPLAYMATH');
DefMacro('\lx@bDM@in@equation', '\lx@saved@BEGINDISPLAYMATH\let\@@ENDDISPLAYMATH\lx@saved@ENDDISPLAYMATH');
DefMacro('\lx@eDM@in@equation',
'\lx@retract@eqnno\lx@begin@fake@intertext'
. '\let\lx@saved@BEGINDISPLAYMATH\@@BEGINDISPLAYMATH\let\lx@saved@bdm\['
. '\let\@@BEGINDISPLAYMATH\lx@end@fake@intertext'
. '\let\[\lx@end@fake@intertext');
DefMacro('\lx@begin@fake@intertext', '\end{equation}');
DefMacro('\lx@end@fake@intertext',
'\let\@@BEGINDISPLAYMATH\lx@saved@BEGINDISPLAYMATH\let\[\lx@saved@bdm' .
'\begin{equation}');
DefPrimitive('\lx@retract@eqnno', sub { retractEquation(); });
sub retractEquation {
my $numbering = LookupValue('EQUATION_NUMBERING');
# What about scopes? Is that handled automagically?
# What about \@currentID....
my $tags = LookupValue('EQUATIONROW_TAGS');
my $ctr = $$tags{counter} || $$numbering{counter} || 'equation';
if ($$tags{preset}) { # ONLY if the number was preset!
# counter (or ID counter) was stepped, so decrement it.
AddToCounter(($$numbering{numbered} ? $ctr : 'UN' . $ctr), Number(-1)); }
AssignValue(EQUATIONROW_TAGS => { RefStepID($ctr), reset => 1 }, 'global');
return; }
# Disable this equation's number
# Ahhhh, but in eqnarray, this isn't effected until \\ !!!!!
DefMacroI('\nonumber', undef, '\lx@equation@nonumber');
DefPrimitiveI('\lx@equation@nonumber', undef, sub {
my $numbering = LookupValue('EQUATION_NUMBERING');
if ($$numbering{in_equation}) {
if ($$numbering{deferretract}) {
my $tags = LookupValue('EQUATIONROW_TAGS');
$$tags{retract} = 1; }
else {
retractEquation(); } }
return; });
Let('\@LTX@nonumber', '\lx@equation@nonumber');
# Set this equation's number explicitly (eg ams's \tag)
DefMacroI('\lx@equation@settag', undef, '\lx@equation@retract\lx@equation@settag@');
DefPrimitiveI('\lx@equation@retract', undef, sub { retractEquation(); });
DefPrimitive('\lx@equation@settag@ Digested', sub {
my $tags = LookupValue('EQUATIONROW_TAGS');
$$tags{tags} = $_[1];
return; },
mode => 'text');
sub afterEquation {
my ($whatsit) = @_;
my $numbering = LookupValue('EQUATION_NUMBERING');
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
. "</ltx:Math>"
. "</ltx:equation>",
mode => 'display_math',
beforeDigest => sub {
prepareEquationCounter(numbered => undef, preset => 1);
beforeEquation(); },
afterDigestBody => sub {
afterEquation($_[1]); },
locked => 1);
DefMacro('\[', '\@@BEGINDISPLAYMATH');
DefMacro('\]', '\@@ENDDISPLAYMATH');
DefMacro('\(', '\@@BEGININLINEMATH');
DefMacro('\)', '\@@ENDINLINEMATH');
# Keep from expanding too early, if in alignments, or such.
DefMacroI('\ensuremath', undef,
Tokens(T_CS('\protect'), T_CS('\@ensuremath')));
DefMacro('\@ensuremath{}', sub {
my ($gullet, $stuff) = @_;
if (LookupValue('IN_MATH')) { $stuff->unlist; }
else { (T_MATH, $stuff->unlist, T_MATH); } });
# Magic check that math-mode trigger follows
our $MATHENVS = 'displaymath|equation*?|eqnarray*?'
. '|multline*?|align*?|falign*?|alignat*?|xalignat*?|xxalignat*?|gather*?';
DefMacro('\ensuremathfollows', sub {
my ($gullet) = @_;
$gullet->closeMouth unless ($gullet->getMouth->hasMoreInput);
if (my $tok = $gullet->readToken()) {
my $csname = $tok->getCSName;
if ($csname eq '\begin') {
my $arg = $gullet->readArg();
$csname = $arg->toString;
$gullet->unread(T_BEGIN, $arg->unlist, T_END);
}
$gullet->unread($tok);
# We need to determine whether the TeX we're given needs to be wrapped in \(...\)
# Does it have $'s around it? Does it have a display math environment?
if ($csname !~ /^Math|\\\(|\\\[|(?:$MATHENVS)/o) {
AssignValue('automath_triggered' => 1, 'global');
return T_CS('\\('); } }
return;
});
DefMacro('\ensuremathpreceeds', sub {
return LookupValue('automath_triggered') ? T_CS('\\)') : ();
});
# Since the arXMLiv folks keep wanting ids on all math, let's try this!
Tag('ltx:Math', afterOpen => sub { GenerateID(@_, 'm'); });
#======================================================================
# Sub-numbered equations
# Although LaTeX itself doesn't provide such an environment,
# many other packages & classes do, and they seem essentially equivalent.
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
DefConstructor('\lx@equationgroup@subnumbering@begin',
"<ltx:equationgroup xml:id='#id'>"
. "#tags",
afterDigest => sub {
my ($stomach, $whatsit) = @_;
my %eqn = RefStepCounter('equation');
my $eqnum = Expand(T_CS('\theequation'));
AssignValue(SAVED_EQUATION_NUMBER => LookupRegister('\c@equation'));
$whatsit->setProperties(%eqn);
ResetCounter('equation');
DefMacroI('\theequation', undef, UnTeX($eqnum) . '\alph{equation}');
DefMacroI('\theequation@ID', undef, UnTeX($eqn{id}) . '.\@equation@ID'); });
Tag('ltx:equationgroup', autoClose => 1);
DefConstructor('\lx@equationgroup@subnumbering@end', sub {
$_[0]->maybeCloseElement('ltx:equationgroup'); },
afterDigest => sub {
AssignRegister('\c@equation', LookupValue('SAVED_EQUATION_NUMBER'), 'global');
});
#======================================================================
# ========================================
# eqnarray, etal
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
# ========================================
# Some special kinds of rows...
DefConditionalI('\if@in@firstcolumn', undef, sub {
my $alignment = LookupValue('Alignment');
my $n = ($alignment ? $alignment->currentColumnNumber : 9);
return $alignment && (!$$alignment{in_row} ||
(!$$alignment{in_column} && ($alignment->currentColumnNumber < 2))); });
# A bit more defensiveness, since people abuse eqnarray so badly.
# Eg. &&\lefteqn{...} whatever?!?!
DefMacro('\lefteqn{}',
'\if@in@firstcolumn\multicolumn{3}{l}{\@ADDCLASS{ltx_eqn_lefteqn}\@@BEGININLINEMATH \displaystyle #1\@@ENDINLINEMATH\mbox{}}'
. '\else\rlap{\@@BEGININLINEMATH\displaystyle #1\@@ENDINLINEMATH}\fi');
# \intertext (in amsmath)
Let('\displ@y', '\displaystyle'); # good enough?
DefMacro('\@lign', ''); # good enough?
# ========================================
# eqnarray
DefMacroI('\eqnarray', undef,
'\@eqnarray@bindings\@@eqnarray'
. '\@equationgroup@numbering{numbered=1,preset=1,deferretract=1,grouped=1,aligned=1}'
. '\@start@alignment',
locked => 1);
DefMacroI('\endeqnarray', undef,
'\cr\@finish@alignment\end@eqnarray',
locked => 1);
DefMacro('\csname eqnarray*\endcsname',
'\@eqnarray@bindings\@@eqnarray'
. '\@equationgroup@numbering{numbered=1,preset=1,retract=1,grouped=1,aligned=1}'
. '\@start@alignment',
locked => 1);
DefMacro('\csname endeqnarray*\endcsname',
'\@finish@alignment\end@eqnarray',
locked => 1);
DefPrimitive('\@eqnarray@bindings', sub {
eqnarrayBindings(); });
DefPrimitiveI('\eqnarray@row@before@', undef, sub { beforeEquation(); });
DefPrimitiveI('\eqnarray@row@after@', undef, sub { afterEquation(); });
DefMacroI('\eqnarray@row@before', undef, '\hidden@noalign{\eqnarray@row@before@}');
DefMacroI('\eqnarray@row@after', undef, '\hidden@noalign{\eqnarray@row@after@}');
sub eqnarrayBindings {
my $col1 = { before => Tokens(T_CS('\hfil'), T_MATH, T_CS('\displaystyle')),
after => Tokens(T_MATH) };
my $col2 = { before => Tokens(T_CS('\hfil'), T_MATH, T_CS('\displaystyle')),
after => Tokens(T_MATH, T_CS('\hfil')) };
my $col3 = { before => Tokens(T_MATH, T_CS('\displaystyle')),
after => Tokens(T_MATH, T_CS('\hfil')) };
my %attributes = (
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
Let("\\\\", '\@alignment@newline');
Let('\lx@intercol', '\lx@math@intercol');
Let('\@row@before', '\eqnarray@row@before');
Let('\@row@after', '\eqnarray@row@after');
Let('\lx@eqnarray@save@label', '\label');
Let('\label', '\lx@eqnarray@label');
return; }
# A \label preceding \lefteqn throws of the implied \omit,e tc; so wrap in \hidden@align
DefMacro('\lx@eqnarray@label Semiverbatim',
'\hidden@noalign{\lx@eqnarray@save@label{#1}}');
DefConstructor('\@@eqnarray SkipSpaces DigestedBody',
'#1',
beforeDigest => sub { $_[0]->bgroup; },
afterConstruct => sub { rearrangeEqnarray($_[0], $_[0]->getNode->lastChild); });
DefPrimitiveI('\end@eqnarray', undef, sub { $_[0]->egroup; });
# ========================================
# Some tools for analyzing the equationgroup after we've constructed it.
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
#======================================================================
# C.7.4 Arrays
#======================================================================
# See Section C.10.2
#======================================================================-
# C.7.5 Delimiters
#======================================================================-
# All this is already in TeX.pool
DefMacro('\stackrel{}{}', '\lx@stackrel{{\scriptstyle #1}}{{#2}}');
DefConstructor('\lx@stackrel{}{}',
"<ltx:XMApp role='RELOP'>"
. "<ltx:XMTok role='SUPERSCRIPTOP' scriptpos='#scriptpos'/>"
. "<ltx:XMArg>#2</ltx:XMArg>"
. "<ltx:XMArg>#1</ltx:XMArg>"
. "</ltx:XMApp>",
reversion => '\stackrel{#1}{#2}',
properties => { scriptpos => sub { "mid" . $_[0]->getScriptLevel; } }
);
#======================================================================-
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
font => { family => 'sansserif', series => 'medium', shape => 'upright' });
DefConstructor('\mathtt{}', '#1', bounded => 1, requireMath => 1, locked => 1,
font => { family => 'typewriter', series => 'medium', shape => 'upright' });
DefConstructor('\mathcal{}', '#1', bounded => 1, requireMath => 1, locked => 1,
font => { family => 'caligraphic', series => 'medium', shape => 'upright' });
DefConstructor('\mathscr{}', '#1', bounded => 1, requireMath => 1, locked => 1,
font => { family => 'script', series => 'medium', shape => 'upright' });
DefConstructor('\mathnormal{}', '#1', bounded => 1, requireMath => 1, locked => 1,
font => { family => 'math', shape => 'italic', series => 'medium' });
DefMacroI('\fontsubfuzz', undef, '.4pt');
DefMacroI('\oldstylenums', undef, Tokens());
DefPrimitiveI('\operator@font', undef, undef,
font => { family => 'serif', series => 'medium', shape => 'upright' });
#**********************************************************************
# C.8 Definitions, Numbering and Programming
#**********************************************************************
#======================================================================
# C.8.1 Defining Commands
#======================================================================
DefMacro('\@tabacckludge {}', '\csname\string#1\endcsname');
DefPrimitive('\newcommand OptionalMatch:* SkipSpaces DefToken [Number][]{}', sub {
my ($stomach, $star, $cs, $nargs, $opt, $body) = @_;
if (!isDefinable($cs)) {
Info('ignore', $cs, $stomach,
"Ignoring redefinition (\\newcommand) of '" . ToString($cs) . "'")
unless LookupValue(ToString($cs) . ':locked');
return; }
DefMacroI($cs, convertLaTeXArgs($nargs, $opt), $body); });
DefPrimitive('\CheckCommand OptionalMatch:* SkipSpaces DefToken [Number][]{}', undef);
DefPrimitive('\renewcommand OptionalMatch:* SkipSpaces DefToken [Number][]{}', sub {
my ($stomach, $star, $cs, $nargs, $opt, $body) = @_;
DefMacroI($cs, convertLaTeXArgs($nargs, $opt), $body); });
# low-level implementation of both \newcommand and \renewcommand depends on \@argdef
# and robustness upgrades are often realized via redefining \l@ngrel@x
DefPrimitive('\@argdef DefToken []{}', sub {
DefMacroI($_[1], convertLaTeXArgs($_[2]), $_[3]); });
DefPrimitive('\@xargdef DefToken [][]{}', sub {
DefMacroI($_[1], convertLaTeXArgs($_[2], $_[3]), $_[4]); });
DefPrimitive('\@yargdef DefToken DefToken {}{}', sub {
DefMacroI($_[1],
(T_CS('\tw@')->equals($_[2])
? convertLaTeXArgs($_[3], Tokens())
: convertLaTeXArgs($_[3])),
$_[4]); });
DefPrimitive('\@reargdef DefToken []{}', sub {
DefMacroI($_[1], convertLaTeXArgs($_[2]), $_[3]); });
DefPrimitive('\providecommand OptionalMatch:* SkipSpaces DefToken [Number][]{}', sub {
my ($stomach, $star, $cs, $nargs, $opt, $body) = @_;
return unless isDefinable($cs);
DefMacroI($cs, convertLaTeXArgs($nargs, $opt), $body); });
# Crazy; define \cs in terms of \cs[space] !!!
DefPrimitive('\DeclareRobustCommand OptionalMatch:* SkipSpaces DefToken [Number][]{}', sub {
my ($stomach, $star, $cs, $nargs, $opt, $body) = @_;
DefMacroI($cs, convertLaTeXArgs($nargs, $opt), $body, robust => 1); });
DefPrimitive('\MakeRobust DefToken', sub {
my ($stomach, $cs) = @_;
my $mungedcs = T_CS($cs->getString . ' ');
if (!LookupDefinition($cs)) { } # Not defined
elsif (LookupDefinition($mungedcs)) { } # Already robust
else {
Let($mungedcs, $cs);
DefMacroI($cs, undef, Tokens(T_CS('\protect'), $mungedcs)); } });
# There are a bunch of ways in LaTeX to assign a command to
# a particular point within a font (which has one of many encodings)
# Since we have no practical way of knowing what that point is,
# and we really want to create unicode, we just ignore this stuff (but warn).
sub ignoredDefinition {
my ($stomach, $command, $cs) = @_;
# Warn('ignore',$cs,$stomach,"ignoring ".ToString($command)." definition of ".ToString($cs));
return; }
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
# the current encoding, if any, or the default expansion (for encoding "?").
# We don't want to redefine control-sequence if it already has a definition:
# It may be that we've already defined it to expand into the above conditional.
# But more importantly, we don't want to override a hand-written definition (if any).
#------------------------------------------------------------
DefPrimitive('\DeclareTextCommand DefToken {}[Number][]{}', sub {
my ($gullet, $cs, $encoding, $nargs, $opt, $expansion) = @_;
my $css = ToString($cs);
$encoding = ToString(Expand($encoding));
if (!IsDefined($cs)) { # If not already defined...
DefMacroI($cs, undef,
'\expandafter\ifx\csname\cf@encoding\string' . $css . '\endcsname\relax\csname?\string' . $css . '\endcsname'
. '\else\csname\cf@encoding\string' . $css . '\endcsname\fi'); }
my $ecs = T_CS('\\' . $encoding . $css);
DefMacroI($ecs, convertLaTeXArgs($nargs, $opt), $expansion);
return; });
DefMacro('\DeclareTextCommandDefault DefToken', '\DeclareTextCommand{#1}{?}');
DefPrimitive('\ProvideTextCommand DefToken {}[Number][]{}', sub {
my ($gullet, $cs, $encoding, $nargs, $opt, $expansion) = @_;
my $css = ToString($cs);
$encoding = ToString(Expand($encoding));
if (isDefinable($cs)) { # If not already defined...
DefMacroI($cs, undef,
'\expandafter\ifx\csname\cf@encoding\string' . $css . '\endcsname\relax\csname?\string' . $css . '\endcsname'
. '\else\csname\cf@encoding\string' . $css . '\endcsname\fi'); }
my $ecs = T_CS('\\' . $encoding . $css);
if (!IsDefined($ecs)) { # If not already defined...
DefMacroI($ecs, convertLaTeXArgs($nargs, $opt), $expansion); }
return; });
DefMacro('\ProvideTextCommandDefault DefToken', '\ProvideTextCommand{#1}{?}');
#------------------------------------------------------------
DefPrimitive('\DeclareTextSymbol DefToken {}{Number}', sub {
my ($gullet, $cs, $encoding, $code) = @_;
$code = $code->valueOf;
my $css = ToString($cs);
$encoding = ToString(Expand($encoding));
if (isDefinable($cs)) { # If not already defined...
DefMacroI($cs, undef,
'\expandafter\ifx\csname\cf@encoding\string' . $css . '\endcsname\relax\csname?\string' . $css . '\endcsname'
. '\else\csname\cf@encoding\string' . $css . '\endcsname\fi'); }
my $ecs = T_CS('\\' . $encoding . $css);
DefPrimitiveI($ecs, undef, FontDecode($code, $encoding));
return; });
# hmmm... what needs doing here; basically it means use this encoding as the default for the symbol
DefMacro('\DeclareTextSymbolDefault DefToken {}', ''); # '\DeclareTextSymbol{#1}{?}');
#------------------------------------------------------------
DefPrimitive('\DeclareTextAccent DefToken {}{}', sub {
ignoredDefinition('DeclareTextAccent', $_[1]); });
DefPrimitive('\DeclareTextAccentDefault{}{}',
sub { ignoredDefinition('DeclareTextAccentDefault', $_[1]); });
#------------------------------------------------------------
# TODO: Need to convert these DefPrimitive's into DefConstroctors
# that add a preable PI!!!!!!!!!
DefPrimitive('\DeclareTextComposite{}{}{}{}',
sub { ignoredDefinition('DeclareTextComposite', $_[1]); });
DefPrimitive('\DeclareTextCompositeCommand{}{}{}{}',
sub { ignoredDefinition('DeclareTextCompositeCommand', $_[1]); });
DefPrimitive('\UndeclareTextCommand{}{}', undef);
DefMacro('\UseTextSymbol{}{}', '{\fontencoding{#1}#2}');
DefMacro('\UseTextAccent{}{}', '{\fontencoding{#1}#2{#3}}');
DefPrimitive('\DeclareMathAccent DefToken {}{} {Number}', sub {
my ($stomach, $cs, $kind, $class, $code) = @_;
$class = ToString($class);
my $info = LookupValue('fontdeclaration@' . $class);
my $glyph = FontDecode($code->valueOf, ($info ? $$info{encoding} : $class));
DefMathI($cs, 'Digested', $glyph, operator_role => 'OVERACCENT');
return AddToPreamble('\DeclareMathAccent', $cs, $kind, $class, $code); });
DefPrimitive('\DeclareMathDelimiter{}{}{}{}',
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
my $csname = ToString($cs);
# We won't override this, e.g. \mathrm by fouriernc.sty
if (IsDefined($csname)) {
Info('ignore', $csname, $stomach,
"Ignoring redefinition (\\DeclareMathAlphabet) of '" . $csname . "'"); }
else {
my %font = LaTeXML::Common::Font::lookupTeXFont($family, $series, $shape);
DefPrimitiveI(T_CS($csname), undef, undef, font => {%font}); }
return; });
DefMacro('\newmathalphabet{}{}{}', Tokens()); # or expand int DeclareMathAlphabet?
DefPrimitive('\DeclareFontShape{}{}{}{}{}{}', undef);
DefPrimitive('\DeclareFontFamily{}{}{}', undef);
DefPrimitive('\DeclareSizeFunction{}{}', undef);
my $symboltype_roles = {
'\mathord' => 'ID', '\mathop' => 'BIGOP', '\mathbin' => 'BINOP', '\mathrel' => 'RELOP',
'\mathopen' => 'OPEN', '\mathclose' => 'CLOSE', '\mathpunct' => 'PUNCT' };
DefPrimitive('\DeclareMathSymbol DefToken SkipSpaces DefToken {}{Number}', sub {
my ($stomach, $cs, $type, $font, $code) = @_;
my $encoding = ToString($font); # Or maybe just a font name or class?
if (my $decl = LookupValue('fontdeclaration@' . $encoding)) {
$encoding = $$decl{encoding} if $$decl{encoding}; }
my $glyph = FontDecode($code->valueOf, $encoding);
my $role = $$symboltype_roles{ ToString($type) };
DefMathI($cs, undef, $glyph, role => $role);
return; });
DefPrimitive('\DeclareFixedFont{}{}{}{}{}{}', sub { DefMacroI($_[1], undef, T_CS('\relax')); return; });
DefPrimitive('\DeclareErrorFont{}{}{}{}{}', sub { DefMacroI($_[1], undef, T_CS('\relax')); return; });
DefMacroI('\cdp@list', undef, '\@empty');
Let('\cdp@elt', '\relax');
DefPrimitive('\DeclareFontEncoding{}{}{}', sub {
my ($stomach, $encoding, $x, $y) = @_;
AddToMacro(T_CS('\cdp@list'), T_CS('\cdp@elt'),
T_BEGIN, $_[1]->unlist, T_END,
T_BEGIN, T_CS('\default@family'), T_END,
T_BEGIN, T_CS('\default@series'), T_END,
T_BEGIN, T_CS('\default@shape'), T_END);
my $encoding_expanded = Expand($encoding);
my $encoding_str = ToString($encoding_expanded);
DefMacroI('\LastDeclaredEncoding', undef, $encoding_expanded);
DefMacroI('\T@' . $encoding_str, undef, $x);
DefMacroI('\M@' . $encoding_str, undef, Tokens(T_CS('\default@M'), $y->unlist));
if (my $path = $encoding_str && FindFile(lc($encoding_str) . "enc", type => "dfu")) {
InputDefinitions($path);
}
return;
});
DefMacroI('\LastDeclaredEncoding', undef, '');
DefPrimitive('\DeclareFontSubstitution{}{}{}{}', undef);
DefPrimitive('\DeclareFontEncodingDefaults{}{}', undef);
DefPrimitive('\DeclareEncodingSubset{}{}{}', undef);
DefMacroI('\LastDeclaredEncoding', undef, Tokens());
DefPrimitive('\SetSymbolFont{}{}{}{}{}{}', undef);
DefPrimitive('\SetMathAlphabet{}{}{}{}{}{}', undef);
DefPrimitive('\addtoversion{}{}', undef);
DefPrimitive('\TextSymbolUnavailable{}', undef);
RawTeX(<<'EoTeX');
\DeclareSymbolFont{operators} {OT1}{cmr} {m}{n}
\DeclareSymbolFont{letters} {OML}{cmm} {m}{it}
\DeclareSymbolFont{symbols} {OMS}{cmsy}{m}{n}
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
DefPrimitiveI('\lx@utf@ss', undef, UTF(0xDF), alias => '\ss'); # LATIN SMALL LETTER SHARP S
DefPrimitiveI('\lx@utf@dh', undef, UTF(0xf0), alias => '\dh'); # eth
DefPrimitiveI('\lx@utf@DH', undef, UTF(0xd0), alias => '\DH'); # Eth (looks same as \DJ!)
DefPrimitiveI('\lx@utf@dj', undef, "\x{0111}", alias => '\dj'); # d with stroke
DefPrimitiveI('\lx@utf@DJ', undef, "\x{0110}", alias => '\DJ'); # D with stroke (looks sames as \DH!)
DefPrimitiveI('\lx@utf@ng', undef, "\x{014B}", alias => '\ng');
DefPrimitiveI('\lx@utf@NG', undef, "\x{014A}", alias => '\NG');
DefPrimitiveI('\lx@utf@th', undef, UTF(0xFE), alias => '\th');
DefPrimitiveI('\lx@utf@TH', undef, UTF(0xDE), alias => '\TH');
DefMacroI('\OE', undef, '\lx@utf@OE');
DefMacroI('\oe', undef, '\lx@utf@oe');
DefMacroI('\AE', undef, '\lx@utf@AE');
DefMacroI('\ae', undef, '\lx@utf@ae');
DefMacroI('\ae', undef, '\lx@utf@ae');
DefMacroI('\AA', undef, '\lx@utf@AA');
DefMacroI('\aa', undef, '\lx@utf@aa');
DefMacroI('\O', undef, '\lx@utf@O');
DefMacroI('\o', undef, '\lx@utf@o');
DefMacroI('\L', undef, '\lx@utf@L');
DefMacroI('\l', undef, '\lx@utf@l');
DefMacroI('\ss', undef, '\lx@utf@ss');
DefMacroI('\dh', undef, '\lx@utf@dh'); # in latex?
DefMacroI('\DH', undef, '\lx@utf@DH');
DefMacroI('\dj', undef, '\lx@utf@dj');
DefMacroI('\DJ', undef, '\lx@utf@DJ');
DefMacroI('\ng', undef, '\lx@utf@ng');
DefMacroI('\NG', undef, '\lx@utf@NG');
DefMacroI('\th', undef, '\lx@utf@th');
DefMacroI('\TH', undef, '\lx@utf@TH');
#======================================================================
# C.8.2 Defining Environments
#======================================================================
# Note that \env & \endenv defined by \newenvironment CAN be
# invoked directly.
DefPrimitive('\newenvironment OptionalMatch:* {}[Number][]{}{}', sub {
my ($stomach, $star, $name, $nargs, $opt, $begin, $end) = @_;
$name = ToString(Expand($name));
if (IsDefined(T_CS("\\$name"))) {
Info('ignore', $name, $stomach,
"Ignoring redefinition (\\newenvironment) of Environment '$name'")
unless (LookupValue('\\' . $name . ':locked')
|| LookupValue('\\begin{' . $name . '}:locked'));
return; }
DefMacroI(T_CS("\\$name"), convertLaTeXArgs($nargs, $opt), $begin);
DefMacroI(T_CS("\\end$name"), undef, $end);
return; });
DefPrimitive('\renewenvironment OptionalMatch:* {}[Number][]{}{}', sub {
my ($stomach, $star, $name, $nargs, $opt, $begin, $end) = @_;
$name = ToString(Expand($name));
if (!LookupValue("\\$name:locked")
&& !LookupValue("\\begin{$name}:locked")) {
DefMacroI(T_CS("\\$name"), convertLaTeXArgs($nargs, $opt), $begin);
DefMacroI(T_CS("\\end$name"), undef, $end); }
return; });
#======================================================================
# C.8.3 Theorem-like Environments
#======================================================================
# The core non-customizable part is defined here.
# For customizable theorems, see amsthm.
AssignValue('thm@swap' => 0);
DefRegister('\thm@style' => Tokenize('plain'));
DefRegister('\thm@headfont' => Tokens(T_CS('\bfseries')));
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
DefRegister('\thm@prework' => Tokens());
DefRegister('\thm@postwork' => Tokens());
DefRegister('\thm@symbol' => Tokens());
DefRegister('\thm@numbering' => Tokens(T_CS('\arabic')));
DefPrimitive('\th@plain', sub {
AssignRegister('\thm@bodyfont' => T_CS('\itshape'));
AssignRegister('\thm@headstyling' => T_CS('\lx@makerunin'));
return; });
DefMacroI('\lx@makerunin', undef, '\@ADDCLASS{ltx_runin}');
DefMacroI('\lx@makeoutdent', undef, '\@ADDCLASS{ltx_outdent}');
DefMacroI('\@thmcountersep', undef, '.');
DefMacroI('\thm@doendmark', undef, '');
DefPrimitive('\newtheorem OptionalMatch:* {}[]{}[]', sub {
my ($stomach, $flag, $thmset, $otherthmset, $type, $reset) = @_;
defineNewTheorem($stomach, $flag, $thmset, $otherthmset, $type, $reset);
# Reset these!
DefRegister('\thm@prework' => Tokens());
DefRegister('\thm@postwork' => Tokens()); },
locked => 1);
# These record which style parameters CAN BE saved/restored for each style.
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
$listname =~ s/\?/question/g;
$listname =~ s/\#/hash/g;
$otherthmset = $otherthmset && ToString($otherthmset);
$type = undef if IsEmpty($type);
$within = $within ? ToString(Digest($within)) : undef;
my $counter = $otherthmset || $thmset;
$counter =~ s/\s+/./; # convert spaces to period?
if ($counter ne $thmset) {
AssignMapping('counter_for_type', $thmset => $counter);
DefMacroI(T_CS('\the' . $thmset), undef, T_CS('\the' . $counter), scope => 'global');
}
my $style = ToString(LookupRegister('\thm@style')); # The name of the style
my $numbering = ToString(LookupRegister('\thm@numbering')); # The number style macro
$flag = 1 unless $numbering;
if (!$otherthmset) {
my $idprefix = "Thm$classname";
$idprefix =~ s/\*/./g;
if (!LookupDefinition(T_CS('\c@' . $counter))) { # if isn't already defined...
NewCounter($counter, $within, idprefix => $idprefix); }
DefMacroI(T_CS("\\the$counter"), undef,
($within
? "\\csname the" . $within . "\\endcsname\\\@thmcountersep" . $numbering . "{" . $counter . "}"
: $numbering . "{" . $counter . "}"),
scope => 'global') if $numbering; }
my %parameters = %{ LookupValue('SAVABLE_THEOREM_PARAMETERS') };
my %saved = ();
foreach my $key (keys %parameters) {
$saved{$key} = ($key =~ /^\\/ ? LookupRegister($key) : LookupValue($key)); }
saveTheoremStyle($thmset, %saved);
my $thmname = '\\lx@name@' . $thmset;
DefMacroI($thmname, undef, $type, scope => 'global');
my $swap = LookupValue('thm@swap');
DefMacroI('\fnum@' . $thmset, undef,
Tokens($flag || !$counter
? (T_CS($thmname))
: ($swap
? (T_CS('\the' . $counter), ($type ? (T_SPACE) : ()), T_CS($thmname))
: (T_CS($thmname), ($type ? (T_SPACE) : ()), T_CS('\the' . $counter)))),
scope => 'global');
# amsthm allows you to define your own title formatter
# if there was one defined, use it, else define a new one.
my $headformatter = LookupRegister('\thm@headformatter');
DefMacroI('\format@title@' . $thmset, convertLaTeXArgs(1, 0),
(!IsEmpty($headformatter)
? Tokens(
T_CS('\the'), T_CS('\thm@headfont'),
$headformatter->unlist,
T_BEGIN, ($type ? $type->unlist : ()), T_END,
T_CS('\the' . $counter), T_BEGIN, Tokens(T_PARAM, T_OTHER('1')), T_END,
T_CS('\the'), T_CS('\thm@headpunct'))
: '{\the\thm@headfont\lx@tag{\csname fnum@' . $thmset . '\endcsname}'
. '{' . ($type ? '\ifx.#1.\else\space\the\thm@notefont(#1)\fi' : '#1') . '}'
. '\the\thm@headpunct}'),
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
my $prevreset = LookupValue($reg);
AssignValue($reg => Tokens(grep { !$t->equals($_) && !$unt->equals($_) } $prevreset->unlist),
'global') if $prevreset;
return; }
sub defCounterID {
my ($ctr, $within) = @_;
my $prefix = LookupValue('@ID@prefix@' . $ctr);
if (defined $prefix) {
if ($within) {
DefMacroI(T_CS("\\the$ctr\@ID"), undef,
"\\expandafter\\ifx\\csname the$within\@ID\\endcsname\\\@empty"
. "\\else\\csname the$within\@ID\\endcsname.\\fi"
. " $prefix\\csname \@$ctr\@ID\\endcsname",
scope => 'global'); }
else {
DefMacroI(T_CS("\\the$ctr\@ID"), undef, "$prefix\\csname \@$ctr\@ID\\endcsname",
scope => 'global'); } }
return; }
DefPrimitive('\@addtoreset{}{}', sub {
my ($stomach, $ctr, $within) = @_;
$ctr = ToString(Expand($ctr));
$within = ToString(Expand($within));
addtoCounterReset($ctr, $within);
defCounterID($ctr, $within) unless LookupDefinition(T_CS("\\the$ctr\@ID"));
return; });
DefMacro('\value{}', sub {
T_CS("\\c@" . ToString(Expand($_[1]))) });
DefMacro('\@arabic{Number}', sub {
ExplodeText(ToString($_[1]->valueOf)); });
DefMacro('\arabic{}', sub {
ExplodeText(CounterValue(ToString(Expand($_[1])))->valueOf); });
DefMacro('\@roman{Number}', sub {
ExplodeText(radix_roman(ToString($_[1]->valueOf))); });
DefMacro('\roman{}', sub {
ExplodeText(radix_roman(CounterValue(ToString(Expand($_[1])))->valueOf)); });
DefMacro('\@Roman{Number}', sub {
ExplodeText(radix_Roman(ToString($_[1]->valueOf))); });
DefMacro('\Roman{}', sub {
ExplodeText(radix_Roman(CounterValue(ToString(Expand($_[1])))->valueOf)); });
DefMacro('\@alph{Number}', sub {
ExplodeText(radix_alpha($_[1]->valueOf)); });
DefMacro('\alph{}', sub {
ExplodeText(radix_alpha(CounterValue(ToString(Expand($_[1])))->valueOf)); });
DefMacro('\@Alph{Number}', sub {
ExplodeText(radix_Alpha($_[1]->valueOf)); });
DefMacro('\Alph{}', sub {
ExplodeText(radix_Alpha(CounterValue(ToString(Expand($_[1])))->valueOf)); });
our @fnsymbols = ("*", "\x{2020}", "\x{2021}", UTF(0xA7), UTF(0xB6),
"\x{2225}", "**", "\x{2020}\x{2020}", "\x{2021}\x{2021}");
DefMacro('\@fnsymbol{Number}', sub {
ExplodeText(radix_format($_[1]->valueOf, @fnsymbols)); });
DefMacro('\fnsymbol{}', sub {
ExplodeText(radix_format(CounterValue(ToString(Expand($_[1])))->valueOf, @fnsymbols)); });
# The following two macros were originally defined in chngcntr.sty,
# but were moved to LaTeX core in 2018.
DefPrimitive('\counterwithin OptionalMatch:* {}{}', sub {
my ($stomach, $starred, $ctr, $within) = @_;
$ctr = ToString($ctr);
$within = ToString($within);
addtoCounterReset($ctr, $within);
if (!$starred) {
DefMacroI(T_CS("\\the$ctr"), undef, "\\the$within.\\arabic{$ctr}", scope => 'global');
defCounterID($ctr, $within); }
return; });
DefPrimitive('\counterwithout OptionalMatch:* {}{}', sub {
my ($stomach, $starred, $ctr, $within) = @_;
$ctr = ToString($ctr);
$within = ToString($within);
remfromCounterReset($ctr, $within);
if (!$starred) {
DefMacroI(T_CS("\\the$ctr"), undef, "\\arabic{$ctr}", scope => 'global');
defCounterID($ctr); }
return; });
DefPrimitive('\@removefromreset{}{}', sub {
my ($stomach, $ctr, $within) = @_;
$ctr = ToString($ctr);
$within = ToString($within);
remfromCounterReset($ctr, $within);
# Should \the$ctr@ID be redefined? It really should track changes to \the$ctr!
# defCounterID($ctr);
return; });
DefMacroI('\cl@@ckpt', undef, '\@elt{page}');
#======================================================================
# C.8.5 The ifthen Package.
#======================================================================
# \ifthenelse
# and sundry conditionals...
#
# Yeah, maybe this'll get done someday....
#**********************************************************************
# C.9 Figures and Other Floating Bodies
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
#======================================================================
# Note that, the number is associated with the caption.
# (to allow multiple figures per figure environment?).
# Whatever reason, that causes complications: We can only increment
# counters with the caption, but then have to arrange for the counters,
# refnums, ids, get passed on to the figure, table when needed.
# AND, as soon as possible, since other items may base their id's on the id of the table!
# Let the fonts for float be the default for all floats, figures, tables, etc.
DefMacro('\fnum@font@float', '\@empty');
DefMacro('\format@title@font@float', '\@empty');
DefMacro('\fnum@font@figure', '\fnum@font@float');
DefMacro('\fnum@font@table', '\fnum@font@float');
DefMacro('\format@title@font@figure', '\format@title@font@float');
DefMacro('\format@title@font@table', '\format@title@font@float');
# stubs for the latex float internals
DefEnvironmentI('@float', '[]{}',
"<ltx:float xml:id='#id' inlist='#inlist' ?#1(placement='#1') class='ltx_float_#2'>"
. "#body"
. "</ltx:float>",
properties => { layout => 'vertical' },
beforeDigestBegin => sub { beforeFloat(ToString($_[1]->getArg(2))); },
afterDigest => sub { afterFloat($_[1]); });
DefEnvironmentI('@dblfloat', '[]{}',
"<ltx:float xml:id='#id' inlist='#inlist' ?#1(placement='#1') class='ltx_float_#2'>"
. "#body"
. "</ltx:float>",
properties => { layout => 'vertical' },
beforeDigestBegin => sub { beforeFloat(ToString($_[1]->getArg(2)), double => 1); },
afterDigest => sub { afterFloat($_[1]); });
# Could perhaps parameterize further with a separator?
DefMacro('\format@title@figure{}', '\lx@tag[][: ]{\lx@fnum@@{figure}}#1');
DefMacro('\format@title@table{}', '\lx@tag[][: ]{\lx@fnum@@{table}}#1');
DefMacro('\ext@figure', 'lof');
DefMacro('\ext@table', 'lot');
DefConditional('\iflx@donecaption');
DefMacro('\caption',
'\lx@donecaptiontrue\@ifundefined{@captype}{\@@generic@caption}{\expandafter\@caption\expandafter{\@captype}}');
# First, check for trailing \label, move it into the caption as a standard position
# NOTE: If one day we want to unlock \@caption, make sure to test against arXiv:cond-mat/0001395 for a passing build.
DefMacro('\@caption{}[]{}',
'\@ifnext\label{\@caption@postlabel{#1}{#2}{#3}}{\@caption@{#1}{#2}{#3}}', locked => 1);
DefMacro('\@caption@postlabel{}{}{} SkipMatch:\label Semiverbatim',
'\@caption@{#1}{#2}{#3\label{#4}}');
# Now, check for \label(s) inside to (potentially) record them.
DefMacro('\@caption@{}{}{}',
'\@hack@caption@{#1}{#2}{}#3\label\endcaption');
DefMacro('\@hack@caption@{}{}{} Until:\label Until:\endcaption',
'\ifx.#5.\@caption@@@{#1}{#2}{#3#4}' # No more labels
. '\else\@@@hack@caption@{#1}{#2}{#3#4}#5\endcaption\fi');
DefMacro('\@@@hack@caption@{}{}{} Semiverbatim Until:\label Until:\endcaption',
'\lx@note@caption@label{#4}' .
'\@hack@caption@{#1}{#2}{#3\label{#4}#5}\label#6\endcaption');
DefPrimitive('\lx@note@caption@label{}', sub { MaybeNoteLabel($_[1]); });
DefMacro('\@caption@@@{}{}{}',
'\@@add@caption@counters'
. '\@@toccaption{\lx@format@toctitle@@{#1}{\ifx.#2.#3\else#2\fi}}'
. '\@@caption{\lx@format@title@@{#1}{#3}}');
# Note that the counters only get incremented by \caption, NOT by \table, \figure, etc.
DefPrimitive('\@@add@caption@counters', sub {
my $captype = ToString(Digest(T_CS('\@captype')));
my $pre = LookupValue('PREINCREMENTED_' . $captype); # If pre-incremented by beforeFloat
my %props = ($pre ? %$pre : RefStepCounter($captype));
my $inlist = ToString(Digest(T_CS('\ext@' . $captype)));
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
# These may need to float up to where they're allowed,
# or they may need to close <p> or similar.
DefConstructor('\@@caption{}', "^^<ltx:caption>#1</ltx:caption>", sizer => 0);
DefConstructor('\@@toccaption{}', "^^<ltx:toccaption>#1</ltx:toccaption>",
sizer => 0);
sub beforeFloat {
my ($type, %options) = @_;
#Debug("FLOAT begin $type". join(',',map { $_."=".ToString($options{$_}); } sort keys %options));
DefMacroI('\@captype', undef, $type);
AssignRegister('\hsize' => LookupDimension($options{double} ? '\textwidth' : '\columnwidth'));
if (my $main = $options{preincrement}) {
if (($type ne (LookupValue('LAST_FLOATTYPE') || '')) # first of subtype?
&& !IfCondition('\iflx@donecaption')) { # If main caption NOT already appeared?
AssignValue('PREINCREMENTED_' . $main => { RefStepCounter($main) }, 'global'); } }
return; }
sub afterFloat {
my ($whatsit) = @_;
my $type = ToString(Expand(T_CS('\@captype')));
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
}
return; }
Tag('ltx:figure', afterClose => \&collapseFloat);
Tag('ltx:table', afterClose => \&collapseFloat);
Tag('ltx:float', afterClose => \&collapseFloat);
DefPrimitive('\flushbottom', undef);
DefPrimitive('\suppressfloats[]', undef);
NewCounter('topnumber');
DefMacroI('\topfraction', undef, "0.25");
NewCounter('bottomnumber');
DefMacroI('\bottomfraction', undef, "0.25");
NewCounter('totalnumber');
DefMacroI('\textfraction', undef, "0.25");
DefMacroI('\floatpagefraction', undef, "0.25");
NewCounter('dbltopnumber');
DefMacroI('\dbltopfraction', undef, "0.7");
DefMacroI('\dblfloatpagefraction', undef, "0.25");
DefRegister('\floatsep' => Glue('12.0pt plus 2.0pt minus 2.0pt'));
DefRegister('\textfloatsep' => Glue('20.0pt plus 2.0pt minus 4.0pt'));
DefRegister('\intextsep' => Glue('12.0pt plus 2.0pt minus 2.0pt'));
DefRegister('\dblfloatsep' => Glue('12.0pt plus 2.0pt minus 2.0pt'));
DefRegister('\dbltextfloatsep' => Glue('20.0pt plus 2.0pt minus 4.0pt'));
DefRegister('\@maxsep' => Dimension(0));
DefRegister('\@dblmaxsep' => Dimension(0));
DefRegister('\@fptop' => Glue(0));
DefRegister('\@fpsep' => Glue(0));
DefRegister('\@fpbot' => Glue(0));
DefRegister('\@dblfptop' => Glue(0));
DefRegister('\@dblfpsep' => Glue(0));
DefRegister('\@dblfpbot' => Glue(0));
DefRegister('\abovecaptionskip' => Glue(0));
DefRegister('\belowcaptionskip' => Glue(0));
Let('\topfigrule', '\relax');
Let('\botfigrule', '\relax');
Let('\dblfigrule', '\relax');
DefMacroI('\figurename', undef, 'Figure');
DefMacroI('\figuresname', undef, 'Figures'); # Never used?
DefMacroI('\tablename', undef, 'Table');
DefMacroI('\tablesname', undef, 'Tables');
Let('\outer@nobreak', '\@empty');
DefMacro('\@dbflt{}', '#1');
DefMacro('\@xdblfloat{}[]', '\@xfloat{#1}[#2]');
DefMacro('\@floatplacement', '');
DefMacro('\@dblfloatplacement', '');
#======================================================================
# C.9.2 Marginal Notes
#======================================================================
DefConditional('\if@reversemargin');
Let('\reversemarginpar', '\@reversemargintrue');
Let('\normalmarginpar', '\@reversemarginfalse');
DefConstructor('\marginpar[]{}',
"?#1(<ltx:note role='margin' class='ltx_marginpar_left'><ltx:inline-logical-block>#1</ltx:inline-logical-block></ltx:note>"
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
#**********************************************************************
# C.10 Lining It Up in Columns
#**********************************************************************
#======================================================================
# C.10.1 The tabbing Environment
#======================================================================
DefRegister('\tabbingsep' => Dimension(0));
DefMacroI('\tabbing', undef,
'\par\@tabbing@bindings\@@tabbing\@start@alignment');
DefMacroI('\endtabbing', undef,
'\@finish@alignment\@end@tabbing\par');
DefPrimitiveI('\@end@tabbing', undef, sub { $_[0]->egroup; });
DefConstructor('\@@tabbing SkipSpaces DigestedBody',
'#1',
reversion => '\begin{tabbing}#1\end{tabbing}',
beforeDigest => sub { $_[0]->bgroup; },
mode => 'text');
DefMacroI('\@tabbing@tabset', undef, '\@tabbing@tabset@marker&');
DefMacroI('\@tabbing@nexttab', undef, '\@tabbing@nexttab@marker&');
DefMacro('\@tabbing@newline OptionalMatch:* [Dimension]', '\@tabbing@newline@marker\cr');
DefMacroI('\@tabbing@kill', undef, '\@tabbing@kill@marker\cr\@tabbing@start@tabs');
DefConstructorI('\@tabbing@tabset@marker', undef, '', reversion => '\=',
properties => { alignmentSkippable => 1 });
DefConstructorI('\@tabbing@nexttab@marker', undef, '', reversion => '\>',
properties => { alignmentSkippable => 1 });
DefConstructorI('\@tabbing@newline@marker', undef, '', reversion => Tokens(T_CS("\\\\"), T_CR));
DefConstructorI('\@tabbing@kill@marker', undef, '', reversion => '\kill',
afterDigest => sub { LookupValue('Alignment')->removeRow; return; },
properties => { alignmentSkippable => 1 });
AssignValue(tabbing_start_tabs => Tokens());
DefMacroI('\@tabbing@start@tabs', undef, sub { LookupValue('tabbing_start_tabs')->unlist; });
DefPrimitiveI('\@tabbing@increment', undef, sub {
my @tabs = LookupValue('tabbing_start_tabs')->unlist;
AssignValue(tabbing_start_tabs => Tokens(@tabs, T_CS('\>')), 'global'); });
DefPrimitiveI('\@tabbing@decrement', undef, sub {
my ($ignore, @tabs) = LookupValue('tabbing_start_tabs')->unlist;
AssignValue(tabbing_start_tabs => Tokens(@tabs), 'global'); });
# NOTE: \< is NOT currently handled!!!
# Ugh!! The way we're setting the initial tabs, we can't really handle this!
DefPrimitiveI('\@tabbing@untab', undef, undef);
# NOTE: \' and \` are NOT currently handled
DefPrimitiveI('\@tabbing@flushright', undef, undef);
DefPrimitiveI('\@tabbing@hfil', undef, undef);
# NOTE: \pushtabs and \poptabs are NOT currently handled.
DefPrimitiveI('\@tabbing@pushtabs', undef, undef);
DefPrimitiveI('\@tabbing@poptabs', undef, undef);
DefMacro('\@tabbing@accent{}', sub { T_CS('\@tabbing@' . ToString($_[1])); });
# Should there be some rowsep/colsep set here?
# Note that {tabbign} really shouldn't be handled by a tabular AT ALL....
# Should be recording accumulated widths and wrapping in ltx:text, with specified widths.
sub tabbingBindings {
AssignValue(Alignment => LaTeXML::Core::Alignment->new(
template => LaTeXML::Core::Alignment::Template->new(
repeated => [{ before => Tokens(T_CS('\lx@text@intercol')),
after => Tokens(T_CS('\hfil'), T_CS('\lx@text@intercol')) }]),
openContainer => sub { $_[0]->openElement('ltx:tabular', @_[1 .. $#_]); },
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
Let("\\<", '\@tabbing@untab');
Let('\@tabbing@' . "'", "\\'");
Let('\@tabbing@' . "`", "\\`");
Let('\a', '\@tabbing@accent');
Let("\\'", '\@tabbing@flushright');
Let("\\`", '\@tabbing@hfil');
Let('\pushtabs', '\@tabbing@pushtabs');
Let('\poptabs', '\@tabbing@poptabs');
return; }
DefMacroI('\pushtabs', undef, Tokens());
DefMacroI('\poptabs', undef, Tokens());
DefMacroI('\kill', undef, Tokens());
DefPrimitiveI('\@tabbing@bindings', undef, sub {
tabbingBindings(); });
# NOTE: Do it!!
# Internals of tabbing, as an experiment (e.g. files using program.sty raw as in cs/0003026)
DefMacro('\@startfield', '\global\setbox\@curfield\hbox\bgroup\color@begingroup');
DefMacro('\@stopfield', '\color@endgroup\egroup');
DefMacro('\@contfield', '\global\setbox\@curfield\hbox\bgroup\color@begingroup\unhbox\@curfield');
DefMacro('\@addfield', '\global\setbox\@curline\hbox{\unhbox\@curline\unhbox\@curfield}');
#======================================================================
# C.10.2 The array and tabular Environments
#======================================================================
# Tabular are a bit tricky in that we have to arrange for tr and td to
# be openned and closed at the right times; the only real markup is
# the & and \\. Also \multicolumn has to be cooperative.
# Along with this, we have to track which column specification applies
# to the current column.
# To simulate LaTeX's tabular borders & hlines, we simply add border
# attributes to all cells. For HTML, CSS will be necessary to display them.
# [We'll ignore HTML's frame, rules and colgroup mechanisms.]
DefRegister('\lx@arstrut', Dimension('0pt'));
DefRegister('\lx@default@tabcolsep', Dimension('6pt'));
DefRegister('\tabcolsep', Dimension('6pt'));
DefMacroI('\arraystretch', undef, "1");
Let('\@tabularcr', '\@alignment@newline');
AssignValue(GUESS_TABULAR_HEADERS => 1) # Defaults to yes
unless defined LookupValue('GUESS_TABULAR_HEADERS');
sub tabularBindings {
my ($template, %properties) = @_;
$properties{guess_headers} = LookupValue('GUESS_TABULAR_HEADERS')
unless defined $properties{guess_headers};
if (!defined $properties{attributes}{colsep}) {
my $sep = LookupDimension('\tabcolsep');
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
my $str = ToString(Expand(T_CS('\arraystretch')));
if ($str != 1) {
$properties{attributes}{rowsep} = Dimension(($str - 1) . 'em'); } }
if (!defined $properties{strut}) {
$properties{strut} = LookupRegister('\baselineskip')->multiply(1.5); } # Account for html space
alignmentBindings($template, 'text', %properties);
Let("\\\\", '\@tabularcr');
Let('\lx@intercol', '\lx@text@intercol');
Let('\tabularnewline', "\\\\");
# NOTE: Fit this back in!!!!!!!
# # Do like AddToMacro, but NOT global!
foreach my $name ('@row@before', '@row@after', '@column@before', '@column@after') {
my $cs = '\\' . $name;
DefMacroI($cs, undef,
Tokens(LookupDefinition(T_CS($cs))->getExpansion->unlist,
T_CS('\@tabular' . $name))); }
return; }
# Keyvals are for attributes for the alignment.
# Typical keys are width, vattach,...
DefKeyVal('tabular', 'width', 'Dimension');
DefPrimitive('\@tabular@bindings AlignmentTemplate OptionalKeyVals:tabular', sub {
my ($stomach, $template, $attributes) = @_;
my %attr = ($attributes ? $attributes->getPairs : ());
if (my $va = $attr{vattach}) {
$attr{vattach} = translateAttachment($va) || ToString($va); }
tabularBindings($template, attributes => {%attr});
return; });
DefMacroI('\@tabular@before', undef, '');
DefMacroI('\@tabular@after', undef, '');
DefMacroI('\@tabular@row@before', undef, '');
DefMacroI('\@tabular@row@after', undef, '');
DefMacroI('\@tabular@column@before', undef, '');
DefMacroI('\@tabular@column@after', undef, '');
# The Core alignment support is in LaTeXML::Core::Alignment and in TeX.ltxml
##DefMacro('\tabular[]{}', '\@tabular@bindings{#2}\@@tabular[#1]{#2}\@start@alignment');
DefMacro('\tabular[]{}',
'\@tabular@bindings{#2}[vattach=#1]\@@tabular[#1]{#2}\@start@alignment\@tabular@before',
locked => 1);
DefMacroI('\endtabular', undef,
'\@tabular@after\@finish@alignment\@end@tabular',
locked => 1);
DefPrimitiveI('\@end@tabular', undef, sub { $_[0]->egroup; });
#DefMacroI('\@end@tabular', undef, undef);
# Note that the pattern will already have been interpreted by \@tabular@bindings,
# so make it Undigested here!
DefConstructor('\@@tabular[] Undigested DigestedBody',
'#3',
reversion => '\begin{tabular}[#1]{#2}#3\end{tabular}',
beforeDigest => sub { $_[0]->bgroup; },
sizer => '#3',
afterDigest => sub {
my ($stomach, $whatsit) = @_;
if (my $alignment = LookupValue('Alignment')) {
my $attr = $alignment->getProperty('attributes');
$$attr{vattach} = translateAttachment($whatsit->getArg(1)); }
return; },
locked => 1,
mode => 'text');
DefMacro('\csname tabular*\endcsname{Dimension}[]{}',
### '\@tabular@bindings{#3}\@@tabular@{#1}[#2]{#3}\@start@alignment');
'\@tabular@bindings{#3}[width=#1,vattach=#2]\@@tabular@{#1}[#2]{#3}\@start@alignment');
DefMacro('\csname endtabular*\endcsname',
'\@finish@alignment\@end@tabular@');
DefConstructor('\@@tabular@{Dimension}[] Undigested DigestedBody',
'#4',
beforeDigest => sub { $_[0]->bgroup; },
reversion => '\begin{tabular*}{#1}[#2]{#3}#4\end{tabular*}',
mode => 'text');
DefPrimitive('\@end@tabular@', sub { $_[0]->egroup; });
Let('\multicolumn', '\@multicolumn');
# A weird bit that sometimes gets invoked by Cargo Cult programmers...
# to \noalign in the defn of \hline! Bizarre! (see latex.ltx)
# However, the really weird thing is the way this provides the } to close the argument
DefMacroI('\@xhline', undef, '\ifnum0=`{\fi}');
DefMacro('\cline{}', '\noalign{\@cline{#1}}');
DefConstructor('\@cline{}', '',
afterDigest => sub {
my ($stomach, $whatsit) = @_;
my $cols = ToString($whatsit->getArg(1));
my @cols = ();
while ($cols =~ s/^,?(\d+)//) {
my $n = $1;
push(@cols, ($cols =~ s/^-(\d+)// ? ($n .. $1) : ($n))); }
my $alignment = LookupValue('Alignment');
$alignment->addLine('t', @cols) if $alignment;
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
properties => { isHorizontalRule => 1 });
DefConstructorI('\vline', undef, "", # ???
properties => { isVerticalRule => 1 },
sizer => 0,
);
DefRegister('\lx@default@arraycolsep', Dimension('5pt'));
DefRegister('\arraycolsep', Dimension('5pt'));
DefRegister('\arrayrulewidth', Dimension('0.4pt'));
DefRegister('\doublerulesep', Dimension('2pt'));
DefMacro('\extracolsep{}', Tokens());
#DefMacroI('\tabularnewline', undef, Tokens());
#Let('\tabularnewline', '\cr');
#DefMacroI('\tabularnewline', undef, '\cr'); # ???
#======================================================================
# Array and similar environments
DefPrimitive('\@array@bindings [] AlignmentTemplate', sub {
my ($stomach, $pos, $template) = @_;
my $attr = { vattach => translateAttachment($pos),
role => 'ARRAY' };
# Determine column and row separations, if non default
my $colsep = LookupDimension('\arraycolsep');
if ($colsep && ($colsep->valueOf != LookupDimension('\lx@default@arraycolsep')->valueOf)) {
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
if ($str != 1) {
$$attr{rowsep} = Dimension(($str - 1) . 'em'); }
alignmentBindings($template, 'math', attributes => $attr);
if (my $font = LookupValue('font')) {
if (($font->getMathstyle || 'text') eq 'display') {
MergeFont(mathstyle => 'text'); } }
Let("\\\\", '\@alignment@newline');
Let('\lx@intercol', '\lx@math@intercol');
return; });
DefMacro('\array[]{}',
'\@array@bindings[#1]{#2}\@@array[#1]{#2}\@start@alignment');
DefMacroI('\endarray', undef,
'\@finish@alignment\@end@array');
DefPrimitiveI('\@end@array', undef, sub { $_[0]->egroup; });
DefConstructor('\@@array[] Undigested DigestedBody',
'#3',
beforeDigest => sub { $_[0]->bgroup; },
reversion => '\begin{array}[#1]{#2}#3\end{array}');
DefMacro('\@tabarray', '\m@th\@@array[c]');
#**********************************************************************
# C.11 Moving Information Around
#**********************************************************************
#======================================================================
# C.11.1 Files
#======================================================================
DefPrimitive('\nofiles', undef);
#======================================================================
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
# \usepackage{latexml} ... \iflatexml alternate\else page \pageref{label}\fi
Let('\pageref', '\ref');
#======================================================================
# C.11.3 Bibliography and Citation
#======================================================================
# Note that it's called \refname in LaTeX's article, but \bibname in report & book.
# And likewise, mixed up in various other classes!
DefMacroI('\thebibliography@ID', undef, Tokens());
# Do this before digesting the body of a bibliography
sub beforeDigestBibliography {
AssignValue(inPreamble => 0); Digest('\@lx@inbibliographytrue');
DefMacro('\bibliographystyle{}', '');
DefMacro('\bibliography {}', '');
# avoid \let-based redefinitions of the ending.
Let('\endthebibliography', '\saved@endthebibliography');
ResetCounter('@bibitem');
return; }
# This sub does things that would commonly be needed when starting a bibliography
# setting the ID, etc...
sub beginBibliography {
my ($whatsit) = @_;
beginBibliography_clean($whatsit);
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
# Check for balanced? or just take balanced begining?
$bibtitle = Tokens(@t); } }
noteBackmatterElement($whatsit, 'ltx:bibliography');
# Try to compute a reasonable, but unique ID;
# relative to the document's ID, if any.
# But also, if there are multiple bibliographies,
my $bibnumber = LookupValue('n_bibliographies') || 0;
AssignValue(n_bibliographies => ++$bibnumber, 'global');
my $docid = ToString(Expand(T_CS('\thedocument@ID')));
my $bibid = ($docid ? $docid . '.' : '') . 'bib' . radix_alpha($bibnumber - 1);
DefMacroI(T_CS('\thebibliography@ID'), undef, T_OTHER($bibid), scope => 'global');
# $whatsit->setProperty(id=>ToString(Expand(T_CS('\thebibliography@ID'))));
$whatsit->setProperty(id => $bibid);
my $title = ($bibtitle ? Digest($bibtitle)
: DigestIf('\refname') || DigestIf('\bibname'));
$whatsit->setProperty(title => $title) if $title;
$whatsit->setProperty(titlefont => $title->getFont) if $title;
$whatsit->setProperty(bibstyle => LookupValue('BIBSTYLE'));
$whatsit->setProperty(citestyle => LookupValue('CITE_STYLE'));
# $whatsit->setProperty(sort=> ???
# And prepare for the likely nonsense that appears within bibliographies
ResetCounter('enumiv');
return; }
DefMacro('\bibliography Semiverbatim',
'\lx@ifusebbl{#1}{\input{\jobname.bbl}}{\lx@bibliography{#1}}');
DefMacro('\lx@ifusebbl{}{}{}', sub {
my ($gullet, $bib_files, $bbl_clause, $bib_clause) = @_;
$bib_files = ToString(Expand($bib_files));
return unless $bib_files;
my $jobname = ToString(Expand(T_CS('\jobname')));
my $bbl_path = FindFile($jobname, type => 'bbl');
my $missing_bibs = '';
if (LookupValue("NO_BIBTEX")) {
if (not $bbl_path) {
Info('expected', "bbl", $_[0], "Couldn't find bbl file, bibliography may be empty.");
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
},
afterDigest => sub {
my $style = ToString($_[1]->getArg(1));
AssignValue(BIBSTYLE => $style, 'global');
if (my $parms = $$BIBSTYLES{$style}) {
AssignValue(CITE_STYLE => $$parms{citestyle}); }
else {
Info('unexpected', $style, $_[0], "Unknown bibstyle '$style', it will be ignored"); }
return; });
DefMacro('\bibliographystyle Semiverbatim', '\bibstyle{#1}');
DefConditional('\if@lx@inbibliography');
# Should be an environment, but people seem to want to misuse it.
DefConstructorI('\thebibliography', undef,
"<ltx:bibliography xml:id='#id'>"
. "<ltx:title font='#titlefont' _force_font='true'>#title</ltx:title>"
. "<ltx:biblist>",
beforeDigest => sub {
beforeDigestBibliography(); },
afterDigest => sub {
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
# And protect from redefinitions.
Let('\newblock', '\lx@bibnewblock');
my $gullet = $STATE->getStomach->getGullet;
# Risky, but when bibliography immediatesly starts with text (no implied \par)
if (my $token = $gullet->readNonSpace) {
$gullet->unread($token);
if (!$token->isExecutable) {
$gullet->unread(T_CS('\par')); } }
return; }
DefMacroI('\par@in@bibliography', undef, sub {
my ($gullet) = @_;
$gullet->skipSpaces;
my $tok = $gullet->readToken;
# If next token is another \par, or a REAL \bibitem,
if (Equals($tok, T_CS('\par')) || Equals($tok, T_CS('\bibitem'))) {
($tok); } # then this \par expands into what followed
else { # Else, put it back, and start a bibitem.
$gullet->unread($tok);
(T_CS('\save@bibitem'), T_BEGIN, T_END); } });
DefMacro('\vskip@in@bibliography Glue', undef);
DefMacroI('\item@in@bibliography', undef, '\save@bibitem{}');
# If we hit a real \bibitem, put \par & \bibitem back to correct defn, and then \bibitem.
# A bibitem with now key or label...
DefMacro('\restoring@bibitem',
'\let\bibitem\save@bibitem\let\par\save@par\let\\\\\save@backbackslash\bibitem');
NewCounter('@bibitem', 'bibliography', idprefix => 'bib');
DefMacroI('\the@bibitem', undef, '\arabic{@bibitem}');
DefMacro('\@biblabel{}', '[#1]');
DefMacroI('\fnum@@bibitem', undef, '{\@biblabel{\the@bibitem}}');
# Hack for abused bibliographies; see below
DefMacro('\bibitem',
'\if@lx@inbibliography\else\expandafter\lx@mung@bibliography\expandafter{\@currenvir}\fi'
. '\lx@bibitem', locked => 1);
DefConstructor('\lx@bibitem[] Semiverbatim',
"<ltx:bibitem key='#key' xml:id='#id'>"
. "#tags"
. "<ltx:bibblock>",
afterDigest => sub {
my $tag = $_[1]->getArg(1);
my $key = CleanBibKey($_[1]->getArg(2));
if ($tag) {
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
tags => Digest(T_BEGIN,
T_CS('\def'), T_CS('\the@bibitem'), T_BEGIN, Revert($tag), T_END,
Invocation(T_CS('\lx@make@tags'), T_OTHER('@bibitem')),
T_END)); }
else {
$_[1]->setProperties(key => $key, RefStepCounter('@bibitem')); }
});
# This attempts to handle the case where folks put \bibitem's within an enumerate or such.
# We try to close the list and open the bibliography
DefMacro('\lx@mung@bibliography{}', sub {
my ($gullet, $env) = @_;
my $tag = ToString($env);
my @tokens = ();
# If we're in some sort of list environment, maybe we can recover
if (($tag eq 'enumerate') || ($tag eq 'itemize') || ($tag eq 'description')) {
# nDamn! We're in a list {$tag}; try to close it!
push(@tokens, Invocation('\end', $env),
T_CS('\let'), T_CS('\end' . $tag), T_CS('\endthebibliography'),
T_CS('\let'), T_CS('\end{' . $tag . '}'), T_CS('\end{thebibliography}')); }
# else ? it probably isn't going to work??
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
# The design is intended to support natbib, as well as plain LaTeX.
AssignValue(CITE_STYLE => 'numbers');
AssignValue(CITE_OPEN => T_OTHER('['));
AssignValue(CITE_CLOSE => T_OTHER(']'));
AssignValue(CITE_SEPARATOR => T_OTHER(','));
AssignValue(CITE_YY_SEPARATOR => T_OTHER(','));
AssignValue(CITE_NOTE_SEPARATOR => T_OTHER(','));
AssignValue(CITE_UNIT => undef);
DefMacro('\@cite{}{}', '[{#1\if@tempswa , #2\fi}]');
DefConstructor('\@@cite []{}', "<ltx:cite ?#1(class='ltx_citemacro_#1')>#2</ltx:cite>",
alias => '\cite',
mode => 'text');
# \@@bibref{what to show}{bibkeys}{phrase1}{phrase2}
DefConstructor('\@@bibref Semiverbatim Semiverbatim {}{}',
"<ltx:bibref show='#1' bibrefs='#bibrefs' inlist='#bibunit'"
. " separator='#separator' yyseparator='#yyseparator'>#3#4</ltx:bibref>",
properties => sub { (bibrefs => CleanBibKey($_[2]),
separator => ToString(Digest(LookupValue('CITE_SEPARATOR'))),
yyseparator => ToString(Digest(LookupValue('CITE_YY_SEPARATOR'))),
bibunit => LookupValue('CITE_UNIT')); });
# Simple container for any phrases used in the bibref
DefConstructor('\@@citephrase{}', "<ltx:bibrefphrase>#1</ltx:bibrefphrase>",
mode => 'text');
DefMacro('\cite[] Semiverbatim', sub {
my ($gullet, $post, $keys) = @_;
my ($style, $open, $close, $ns)
= map { LookupValue($_) } qw(CITE_STYLE CITE_OPEN CITE_CLOSE CITE_NOTE_SEPARATOR);
$post = undef if IsEmpty($post);
Invocation(T_CS('\@@cite'),
Tokens(Explode('cite')),
Tokens($open,
Invocation(T_CS('\@@bibref'), undef, $keys, undef, undef),
($post ? ($ns, T_SPACE, $post) : ()), $close)); });
# NOTE: Eventually needs to be recognized by MakeBibliography
# For now, defer until document end.
DefMacro('\nocite{}', sub {
PushValue('@at@end@document', (T_CS('\lx@mark@nocite'), T_BEGIN, $_[1], T_END));
return (); });
DefConstructor('\lx@mark@nocite Semiverbatim',
"<ltx:cite><ltx:bibref show='nothing' bibrefs='#bibrefs' inlist='#bibunit'/></ltx:cite>",
properties => sub {
(bibrefs => CleanBibKey($_[1]),
bibunit => LookupValue('CITE_UNIT')); });
#======================================================================
# C.11.4 Splitting the input
#======================================================================
Let('\@@input', '\input'); # Save TeX's version.
# LaTeX's \input is a bit different...
# Input, now
DefPrimitive('\ltx@input {}', sub { Input(Expand($_[1])); });
DefMacroI('\input', undef, '\@ifnextchar\bgroup\@iinput\@@input');
Let('\@iinput', '\ltx@input');
DefMacro('\@input{}', '\IfFileExists{#1}{\@@input\@filef@und}{\typeout{No file #1.}}');
DefMacro('\@input@{}', '\InputIfFileExists{#1}{}{\typeout{No file #1.}}');
DefMacro('\quote@name{}', '"\quote@@name#1\@gobble""');
DefMacro('\quote@@name{} Match:"', '#1\quote@@name');
DefMacro('\unquote@name{}', '\quote@@name#1\@gobble"');
# Note that even excluded files SHOULD have the effects of their inclusion
# simulated by having read the corresponding aux file;
# But we're not bothering with that.
DefPrimitive('\include{}', sub {
my ($stomach, $path) = @_;
$path = ToString($path);
my $table = LookupValue('including@only');
if (!$table || $$table{$path}) {
Input($path); }
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
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:
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
# where the \index argument was malformed for one reason or another.
#
# the strangeness comes from the original TeX workflow requiring multiple conversion calls,
# alongside a call to the `makeidx` binary, which we don't do in latexml. This parameter type
# emulates one important aspect implied by those steps.
$arg = TokenizeInternal(UnTeX($arg));
return $arg; },
reversion => sub { (T_BEGIN, Revert($_[0]), T_END); });
# real-world LaTeX \index
DefMacro('\index SanitizedVerbatim', \&process_index_phrases);
Tag('ltx:indexphrase', afterClose => \&addIndexPhraseKey);
Tag('ltx:glossaryphrase', afterClose => \&addIndexPhraseKey);
### ltx:indexsee does NOT get a key (at this stage)!
sub addIndexPhraseKey {
my ($document, $node) = @_;
if (!$node->getAttribute('key')) {
$node->setAttribute(key => CleanIndexKey($node->textContent)); }
return; }
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
DefConstructorI('\index@dotfill', undef, sub {
my ($document) = @_;
closeIndexPhrase($document);
$document->openElement('ltx:indexrefs'); });
DefConstructorI('\index@item', undef, sub { doIndexItem($_[0], 1); });
DefConstructorI('\index@subitem', undef, sub { doIndexItem($_[0], 2); });
DefConstructorI('\index@subsubitem', undef, sub { doIndexItem($_[0], 3); });
DefConstructorI('\index@done', undef, sub { doIndexItem($_[0], 0); });
DefMacroI('\indexname', undef, 'Index');
DefEnvironment('{theindex}',
"<ltx:index xml:id='#id'>"
. "<ltx:title font='#titlefont' _force_font='true'>#title</ltx:title>"
. "#body"
. "</ltx:index>",
beforeDigest => sub {
Let('\item', '\index@item');
Let('\subitem', '\index@subitem');
Let('\subsubitem', '\index@subsubitem');
Let('\dotfill', '\index@dotfill'); },
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
# C.12.1 Line Breaking
#======================================================================
DefPrimitive('\linebreak[]', undef);
DefPrimitive('\nolinebreak[]', undef);
DefPrimitiveI('\-', undef, undef); # We don't do hyphenation.
# \hyphenation in TeX.pool
DefPrimitiveI('\sloppy', undef, undef);
DefPrimitiveI('\fussy', undef, undef);
# sloppypar can be used as an environment, or by itself.
DefMacro('\sloppypar', '\par\sloppy');
DefMacro('\endsloppypar', '\par');
DefMacroI('\nobreakdashes', undef, T_OTHER('-'));
DefMacro('\showhyphens{}', '#1'); # ?
#======================================================================
# C.12.2 Page Breaking
#======================================================================
DefMacro('\pagebreak[Default:4]', sub {
my ($gullet, $arg) = @_;
$arg = $arg->toString;
if ($arg <= 2) {
return; }
return Invocation(T_CS('\vadjust'), T_CS('\clearpage')); });
DefPrimitive('\nopagebreak[]', undef);
DefPrimitiveI('\columnbreak', undef, undef); # latex? or multicol?
DefPrimitive('\enlargethispage OptionalMatch:* {}', undef);
DefMacroI('\clearpage', undef, '\LTX@newpage');
DefMacroI('\cleardoublepage', undef, '\LTX@newpage');
DefPrimitiveI('\samepage', undef, undef);
#**********************************************************************
# C.13 Lengths, Spaces and Boxes
#**********************************************************************
#####
#####
# Complete to here
# [except for NOTE'd entries, of course]
#####
#####
#======================================================================
# C.13.1 Length
#======================================================================
# \fill
DefMacro('\stretch{}', '0pt plus #1fill\relax');
DefPrimitive('\newlength DefToken', sub {
my ($stomach, $cs) = @_;
DefRegisterI($cs, undef, Glue(0), allocate => '\skip'); });
DefPrimitive('\setlength {Variable}{Dimension}', sub {
my ($stomach, $variable, $length) = @_;
my ($defn, @params) = @$variable;
if (ref $defn) {
$defn->setValue($length, undef, @params); }
return; });
DefPrimitive('\addtolength {Variable}{Dimension}', sub {
my ($stomach, $variable, $length) = @_;
my ($defn, @params) = @$variable;
if (ref $defn) {
my $oldlength = $defn->valueOf(@params);
$defn->setValue($defn->valueOf(@params)->add($length), undef, @params); }
return; });
DefMacro('\@settodim{}{}{}',
'\setbox\@tempboxa\hbox{{#3}}#2#1\@tempboxa\setbox\@tempboxa\box\voidb@x');
DefMacroI('\settoheight', undef, '\@settodim\ht');
DefMacroI('\settodepth', undef, '\@settodim\dp');
DefMacroI('\settowidth', undef, '\@settodim\wd');
DefMacro('\@settopoint{}', '\divide#1\p@\multiply#1\p@');
DefRegister('\fill', Glue('0pt plus 1fill'));
#======================================================================
# C.13.2 Space
#======================================================================
DefPrimitive('\hspace OptionalMatch:* {Dimension}', sub {
my ($stomach, $star, $length) = @_;
my $s = DimensionToSpaces($length);
return unless defined $s;
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
DefPrimitive('\addvspace {}', undef);
DefPrimitive('\addpenalty {}', undef);
DefPrimitiveI('\@endparenv');
# \hfill, \vfill
#======================================================================
# C.13.3 Boxes
#======================================================================
# Can't really get these?
DefMacroI('\height', undef, '0pt');
DefMacroI('\totalheight', undef, '0pt');
DefMacroI('\depth', undef, '0pt');
DefMacroI('\width', undef, '0pt');
DefConstructor('\mbox {}',
"<ltx:text _noautoclose='1'>#1</ltx:text>", mode => 'text', bounded => 1,
sizer => '#1',
robust => 1,
beforeDigest => sub { reenterTextMode(); });
our %makebox_alignment = (l => 'left', r => 'right', s => 'justified');
DefMacro('\makebox', '\@ifnextchar(\pic@makebox\@makebox', robust => 1);
DefConstructor('\@makebox[Dimension][]{}',
"<ltx:text ?#width(width='#width') ?#align(align='#align') _noautoclose='1'>#3</ltx:text>",
mode => 'text', bounded => 1, alias => '\makebox', sizer => '#3',
beforeDigest => sub { reenterTextMode(); },
properties => sub {
(($_[2] ? (align => $makebox_alignment{ ToString($_[2]) }) : ()),
($_[1] ? (width => $_[1]) : ())) });
DefRegister('\fboxrule', Dimension('.4pt'));
DefRegister('\fboxsep', Dimension('3pt'));
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
# So, we need to switch to text mode, as usual, but FIRST note whether we started in math mode!
# Afterwards, if we were in math mode, and the content is math, we'll convert the whole thing
# to a framed math object.
# Second special issue:
# Although framebox doesn't allow flowed content inside, it is also somewhat common
# to put a vbox or some other block construct inside.
# Seemingly, the ultimate html gets somewhat tangled (browser bugs?)
# At any rate, since we're wrapping with an ltx:text, we'll try to unwrap it,
# if the contents are a single child that can handle the framing.
DefMacro('\fbox{}', '\@framebox{#1}', robust => 1);
DefMacro('\framebox', '\@ifnextchar(\pic@framebox\@framebox', robust => 1);
DefConstructor('\@framebox[Dimension][]{}',
"?#mathframe(<ltx:XMArg enclose='box'>#inner</ltx:XMArg>)"
. "(<ltx:text ?#width(width='#width') ?#align(align='#align')"
. " framed='rectangle' framecolor='#framecolor' cssstyle='#cssstyle'"
. " _noautoclose='1'>#3</ltx:text>)",
alias => '\framebox', sizer => '#3',
beforeDigest => sub {
my ($stomach) = @_;
my $wasmath = LookupValue('IN_MATH');
$stomach->beginMode('text');
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
properties => sub {
(width => $_[4],
vattach => translateAttachment($_[1]),
height => $_[2]); },
mode => 'text', bounded => 1,
robust => 1,
beforeDigest => sub {
reenterTextMode(1); # actually vertical mode!
AssignRegister('\hsize' => $_[4]);
Let('\\\\', '\lx@newline'); });
DefMacroI('\@parboxrestore', undef, Tokens());
DefConditional('\if@minipage');
DefMacro('\@setminipage', '');
DefEnvironment('{minipage}[][][]{Dimension}', sub {
my ($document, $attachment, $b, $c, $width, %props) = @_;
my $vattach = translateAttachment($attachment);
insertBlock($document, $props{body},
width => $width,
vattach => $vattach,
class => 'ltx_minipage');
return; },
sizer => '#body',
mode => 'text',
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
DefConstructor('\rule[Dimension]{Dimension}{Dimension}',
"<ltx:rule ?#offset(yoffset='#offset') width='#width' height='#height'/>",
properties => sub { (offset => $_[1], width => $_[2], height => $_[3]) });
DefConstructor('\raisebox{Dimension}[Dimension][Dimension]{}',
"<ltx:text yoffset='#1' _noautoclose='1'>#4</ltx:text>",
mode => 'text', bounded => 1,
beforeDigest => sub { reenterTextMode(); },
sizer => sub { raisedSizer($_[0]->getArg(4), $_[0]->getArg(1)); });
DefMacro('\@finalstrut{}', '\unskip\ifhmode\nobreak\fi\vrule\@width\z@\@height\z@\@depth\dp#1');
#**********************************************************************
# C.14 Pictures and Color
#**********************************************************************
# These are stubs for color or xcolor packages
Let('\set@color', '\relax');
Let('\color@begingroup', '\relax');
Let('\color@endgroup', '\relax');
Let('\color@setgroup', '\relax');
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
my ($value) = @_;
return ((defined $value) && (ref $value) ? $value->pxValue : $value); }
#----------------------------------------------------------------------
# Picture parameters.
DefRegister('\unitlength', Dimension('1pt'));
DefPrimitiveI('\thinlines', undef, sub { AssignRegister('\@wholewidth', Dimension('0.4pt')); });
DefPrimitiveI('\thicklines', undef, sub { AssignRegister('\@wholewidth', Dimension('0.8pt')); });
DefRegister('\@wholewidth' => Dimension('0.4pt'));
DefRegister('\@halfwidth' => Dimension('0.2pt'));
DefMacro('\linethickness{}', '\@wholewidth #1\relax');
DefPrimitive('\arrowlength{Dimension}', sub { AssignValue('arrowlength', $_[1]); });
#----------------------------------------------------------------------
# Picture transformation support
sub slopeToPicCoord {
my ($slope, $xlength) = @_;
my ($mx, $my) = ($slope->getX, $slope->getY);
my $s = $mx->sign();
$xlength = picScale($xlength);
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
my (%props) = @_;
if (($props{stroke} || '') ne 'none') {
$props{thick} = ptValue(LookupRegister('\@wholewidth')); }
if (my $arrowlength = LookupValue('arrowlength')) {
$props{arrowlength} = ptValue($arrowlength); }
$props{color} = Black unless defined $props{color};
return %props; }
#----------------------------------------------------------------------
# the code
DefMacroI('\qbeziermax', undef, '500');
sub before_picture {
Let('\raisebox', '\pic@raisebox'); # ? needs special treatment within picture
return; }
sub after_picture {
return; }
# Ugh... Is this safe? Apparently, picture stuff is allowed w/o a {picture} environment???
Tag('ltx:picture', autoOpen => 0.5, autoClose => 1,
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
my ($stomach, $size, $pos) = @_;
picProperties(unitlength => LookupRegister('\unitlength'),
width => $size && picScale($size->getX),
height => $size && picScale($size->getY),
depth => Dimension(0),
'origin-x' => $pos && picScale($pos->getX),
'origin-y' => $pos && picScale($pos->getY),
($pos ? (transform => 'translate(' . picScale($pos->negate)->pxValue . ')') : ())); },
afterDigest => \&after_picture);
DefMacroI(T_CS('\Gin@driver'), undef, Tokens());
DefMacro('\@killglue', '\unskip\@whiledim \lastskip >\z@\do{\unskip}');
DefMacro('\put SkipSpaces Match:( Until:, Until:){}', '\lx@pic@put(#2,#3){#4\relax}');
DefConstructor('\lx@pic@put Pair{}',
"<ltx:g transform='#transform'"
. " innerwidth='#innerwidth' innerheight='#innerheight' innerdepth='#innerdepth'>#2</ltx:g>",
properties => sub {
my ($w, $h, $d) = $_[2]->getSize;
$w = undef if $w && ($w->ptValue == 0);
(transform => 'translate(' . picScale($_[1])->pxValue . ')',
innerwidth => $w, innerheight => $h, innerdepth => $d); },
alias => '\put',
mode => 'text');
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
width => Dimension($size->getX->valueOf),
height => Dimension($size->getY->valueOf),
); });
DefConstructor('\qbezier [Number] Pair Pair Pair',
"<ltx:bezier ?#1(displayedpoints='#1') points='&ptValue(#pt)' stroke='#color' stroke-width='#thick' />",
alias => '\qbezier',
properties => sub {
picProperties(pt => PairList(picScale($_[2]), picScale($_[3]), picScale($_[4]))); });
DefMacro('\bezier Until:(', '\ifx.#1.\lx@pic@bezier{0}(\else\lx@pic@bezier{#1}(\fi');
DefConstructor('\lx@pic@bezier {Number} Pair Pair Pair',
"<ltx:bezier ?#1(displayedpoints='#1') points='&ptValue(#pt)' stroke-width='#thick' />",
alias => '\bezier',
properties => sub {
picProperties(pt => PairList(picScale($_[2]), picScale($_[3]), picScale($_[4]))); });
# Generic boxing command (frames, dash, etc)
DefConstructor('\pic@makebox@ Undigested RequiredKeyVals Pair []{}',
"?#framed(<ltx:rect x='0' y='0' width='#fwidth' height='#fheight'"
. " stroke='#color' stroke-width='#thick' fill='none' stroke-dasharray='#dash'/>)()"
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
my $fw = ($ww && $ww->valueOf ? $ww : $w);
my $fh = ($hh && $hh->valueOf ? $hh : $h->add($d));
picProperties(
box => $box,
width => $w, height => $h, depth => $d,
fwidth => $fw, fheight => $fh,
xshift => $x->pxValue, yshift => $y->pxValue,
framed => $kv->getValue('framed'), dash => $kv->getValue('dash') # dashed
); });
DefMacro('\pic@makebox', '\pic@makebox@{\makebox}{}');
DefMacro('\pic@framebox', '\pic@makebox@{\framebox}{framed=true}');
DefMacro('\lx@pic@dashbox{Float}', '\pic@makebox@{\dashbox(#1)}{framed=true,dash={#1}}');
DefMacro('\dashbox Until:(', '\ifx.#1.\lx@pic@dashbox{0}(\else\lx@pic@dashbox{#1}(\fi');
DefMacro('\frame{}', '\pic@makebox@{\framebox}{framed=true}(0,0)[bl]{#1}');
DefMacro('\pic@savebox DefToken Pair []{}', '\pic@@savebox{#1}{\pic@makebox #2[#3]{#4}}');
DefPrimitive('\pic@@savebox DefToken {}', sub {
AssignValue('box' . ToString($_[1]), Digest($_[2])); return; });
DefMacro('\@savepicbox', '\pic@savebox');
DefConstructor('\pic@raisebox{Dimension}[Dimension][Dimension]{}',
"<ltx:g y='#1'>#4</ltx:g>",
alias => '\raisebox');
our %alignments = (l => 'left', c => 'center', r => 'right');
# Not sure that ltx:p is the best to use here, but ... (see also \vbox, \vtop)
# This should be fairly compact vertically.
DefConstructor('\@shortstack@cr',
"</ltx:p><ltx:p>",
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
AssignRegister('\baselineskip' => Glue('-1pt'));
AssignRegister('\lineskip' => Glue('3pt'));
$_[0]->bgroup; },
afterDigest => sub { $_[1]->getSize; # precompute while binding in effect
$_[0]->egroup; },
# Note: does not get layout=vertical, since linebreaks are explicit
properties => { align => sub { ($_[1] ? $alignments{ ToString($_[1]) } : undef); },
vattach => 'bottom' }, # for size computation
mode => 'text');
DefMacro('\multiput Pair Pair {}{}', sub {
my ($gullet, $pos, $d, $nt, $body) = @_;
my ($x, $y, $dx, $dy, $n)
= map { ToString($_) } ($pos->getX, $pos->getY, $d->getX, $d->getY, $nt);
my @exp = ();
for (my $i = 0 ; $i < $n ; $i++) {
push(@exp, T_CS('\put'), T_OTHER('('), Explode($x), T_OTHER(','), Explode($y), T_OTHER(')'),
T_BEGIN, $body->unlist, T_END);
$x += $dx; $y += $dy; }
@exp; });
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
# \savebox -- already defined differntly in C.13 above ?
#**********************************************************************
# C.15 Font Selection
#**********************************************************************
#======================================================================
# C.15.1 Changing the Type Style
#======================================================================
# Text styles.
DefMacroI('\rmdefault', undef, 'cmr', locked => 1);
DefMacroI('\sfdefault', undef, 'cmss', locked => 1);
DefMacroI('\ttdefault', undef, 'cmtt', locked => 1);
DefMacroI('\bfdefault', undef, 'bx', locked => 1);
DefMacroI('\mddefault', undef, 'm', locked => 1);
DefMacroI('\itdefault', undef, 'it', locked => 1);
DefMacroI('\sldefault', undef, 'sl', locked => 1);
DefMacroI('\scdefault', undef, 'sc', locked => 1);
DefMacroI('\updefault', undef, 'n', locked => 1);
DefMacroI('\encodingdefault', undef, 'OT1');
DefMacroI('\familydefault', undef, '\rmdefault');
DefMacroI('\seriesdefault', undef, '\mddefault');
DefMacroI('\shapedefault', undef, '\updefault');
Let('\mediumseries', '\mdseries');
Let('\normalshape', '\upshape');
# ? DefMacro('\f@encoding','cm');
DefMacro('\f@family', 'cmr');
DefMacro('\f@series', 'm');
DefMacro('\f@shape', 'n');
DefMacro('\f@size', '10');
# These do NOT immediately effect the font!
DefMacro('\fontfamily{}', '\edef\f@family{#1}');
DefMacro('\fontseries{}', '\edef\f@series{#1}');
DefMacro('\fontshape{}', '\edef\f@shape{#1}');
# For fonts not allowed in math!!!
DefPrimitive('\not@math@alphabet@@ {}', sub {
if ($STATE->lookupValue('IN_MATH')) {
my $c = ToString($_[1]);
Warn('unexpected', $c, $_[0], "Command $c invalid in math mode"); }
return; });
# These DO immediately effect the font!
DefMacroI('\mdseries', undef, '\not@math@alphabet@@{\mddefault}\fontseries{\mddefault}\selectfont');
DefMacroI('\bfseries', undef, '\not@math@alphabet@@{\bfdefault}\fontseries{\bfdefault}\selectfont');
DefMacroI('\rmfamily', undef, '\not@math@alphabet@@{\rmdefault}\fontfamily{\rmdefault}\selectfont');
DefMacroI('\sffamily', undef, '\not@math@alphabet@@{\sfdefault}\fontfamily{\sfdefault}\selectfont');
DefMacroI('\ttfamily', undef, '\not@math@alphabet@@{\ttdefault}\fontfamily{\ttdefault}\selectfont');
DefMacroI('\upshape', undef, '\not@math@alphabet@@{\updefault}\fontshape{\updefault}\selectfont');
DefMacroI('\itshape', undef, '\not@math@alphabet@@{\itdefault}\fontshape{\itdefault}\selectfont');
DefMacroI('\slshape', undef, '\not@math@alphabet@@{\sldefault}\fontshape{\sldefault}\selectfont');
DefMacroI('\scshape', undef, '\not@math@alphabet@@{\scdefault}\fontshape{\scdefault}\selectfont');
DefMacroI('\normalfont', undef,
'\fontfamily{\rmdefault}\fontseries{\mddefault}\fontshape{\updefault}\selectfont');
DefMacroI('\verbatim@font', undef,
'\fontfamily{\ttdefault}\fontseries{\mddefault}\fontshape{\updefault}\selectfont');
Let('\reset@font', '\normalfont');
DefMacro('\@fontswitch{}{}', '\ifmmode #2\relax\else #1 \fi');
DefPrimitive('\selectfont', sub {
my $family = ToString(Expand(T_CS('\f@family')));
my $series = ToString(Expand(T_CS('\f@series')));
my $shape = ToString(Expand(T_CS('\f@shape')));
if (my $sh = LaTeXML::Common::Font::lookupFontFamily($family)) { MergeFont(%$sh); }
elsif (LoadFontMap($family)) {
# Special case hack: Tentatively treat family as the encoding! (typically "U" encoding)
MergeFont(encoding => $family); }
elsif (!LookupValue("reported_unrecognized_font_family_$family")) {
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
if (my $sh = LaTeXML::Common::Font::lookupFontSeries($series)) { MergeFont(%$sh); }
elsif (!LookupValue("reported_unrecognized_font_series_$series")) {
AssignValue("reported_unrecognized_font_series_$series", 1, 'global');
Info('unexpected', $series, $_[0], "Unrecognized font series '$series'."); }
if (my $sh = LaTeXML::Common::Font::lookupFontShape($shape)) { MergeFont(%$sh); }
elsif (!LookupValue("reported_unrecognized_font_shape_$shape")) {
AssignValue("reported_unrecognized_font_shape_$shape", 1, 'global');
Info('unexpected', $shape, $_[0], "Unrecognized font shape '$shape'."); }
return; });
DefMacro('\usefont{}{}{}{}',
'\fontencoding{#1}\fontfamily{#2}\fontseries{#3}\fontshape{#4}\selectfont');
# If these series or shapes appear in math, they revert it to roman, medium, upright (?)
DefConstructor('\textmd@math{}', "<ltx:text _noautoclose='1'>#1</ltx:text>", mode => 'text',
bounded => 1, font => { series => 'medium' }, alias => '\textmd',
beforeDigest => sub { DefMacro('\f@series', 'm'); });
DefConstructor('\textbf@math{}', "<ltx:text _noautoclose='1'>#1</ltx:text>", mode => 'text',
bounded => 1, font => { series => 'bold' }, alias => '\textbf',
beforeDigest => sub { DefMacro('\f@series', 'b'); });
DefConstructor('\textrm@math{}', "<ltx:text _noautoclose='1'>#1</ltx:text>", mode => 'text',
bounded => 1, font => { family => 'serif' }, alias => '\textrm',
beforeDigest => sub { DefMacro('\f@family', 'cm'); });
DefConstructor('\textsf@math{}', "<ltx:text _noautoclose='1'>#1</ltx:text>", mode => 'text',
bounded => 1, font => { family => 'sansserif' }, alias => '\textsf',
beforeDigest => sub { DefMacro('\f@family', 'cmss'); });
DefConstructor('\texttt@math{}', "<ltx:text _noautoclose='1'>#1</ltx:text>", mode => 'text',
bounded => 1, font => { family => 'typewriter' }, alias => '\texttt',
beforeDigest => sub { DefMacro('\f@family', 'cmtt'); });
DefConstructor('\textup@math{}', "<ltx:text _noautoclose='1'>#1</ltx:text>", mode => 'text',
bounded => 1, font => { shape => 'upright' }, alias => '\textup',
beforeDigest => sub { DefMacro('\f@shape', ''); });
DefConstructor('\textit@math{}', "<ltx:text _noautoclose='1'>#1</ltx:text>", mode => 'text',
bounded => 1, font => { shape => 'italic' }, alias => '\textit',
beforeDigest => sub { DefMacro('\f@shape', 'it'); });
DefConstructor('\textsl@math{}', "<ltx:text _noautoclose='1'>#1</ltx:text>", mode => 'text',
bounded => 1, font => { shape => 'slanted' }, alias => '\textsl',
beforeDigest => sub { DefMacro('\f@shape', 'sl'); });
DefConstructor('\textsc@math{}', "<ltx:text _noautoclose='1'>#1</ltx:text>", mode => 'text',
bounded => 1, font => { shape => 'smallcaps' }, alias => '\textsc',
beforeDigest => sub { DefMacro('\f@shape', 'sc'); });
DefConstructor('\textnormal@math{}', "<ltx:text _noautoclose='1'>#1</ltx:text>", mode => 'text',
bounded => 1, font => { family => 'serif', series => 'medium', shape => 'upright' }, alias => '\textnormal',
beforeDigest => sub { DefMacro('\f@family', 'cmtt');
DefMacro('\f@series', 'm');
DefMacro('\f@shape', 'n'); });
# These really should be robust! which is a source of expand timing issues!
DefMacro('\textmd{}', '\ifmmode\textmd@math{#1}\else{\mdseries #1}\fi', protected => 1);
DefMacro('\textbf{}', '\ifmmode\textbf@math{#1}\else{\bfseries #1}\fi', protected => 1);
DefMacro('\textrm{}', '\ifmmode\textrm@math{#1}\else{\rmfamily #1}\fi', protected => 1);
DefMacro('\textsf{}', '\ifmmode\textsf@math{#1}\else{\sffamily #1}\fi', protected => 1);
DefMacro('\texttt{}', '\ifmmode\texttt@math{#1}\else{\ttfamily #1}\fi', protected => 1);
DefMacro('\textup{}', '\ifmmode\textup@math{#1}\else{\upshape #1}\fi', protected => 1);
DefMacro('\textit{}', '\ifmmode\textit@math{#1}\else{\itshape #1}\fi', protected => 1);
DefMacro('\textsl{}', '\ifmmode\textsl@math{#1}\else{\slshape #1}\fi', protected => 1);
DefMacro('\textsc{}', '\ifmmode\textsc@math{#1}\else{\scshape #1}\fi', protected => 1);
DefMacro('\textnormal{}', '\ifmmode\textnormal@math{#1}\else{\normalfont #1}\fi', protected => 1);
DefPrimitive('\DeclareTextFontCommand{}{}', sub {
my ($stomach, $cmd, $font) = @_;
DefConstructorI($cmd, "{}",
"?#isMath(<ltx:text _noautoclose='1'>#1</ltx:text>)(#1)",
mode => 'text', bounded => 1,
beforeDigest => sub { Digest($font); (); });
return; });
DefPrimitive('\mathversion{}', sub {
my ($stomach, $version) = @_;
$version = ToString($version);
if ($version eq 'bold') {
AssignValue(mathfont => LookupValue('mathfont')->merge(forcebold => 1), 'local'); }
elsif ($version eq 'normal') {
AssignValue(mathfont => LookupValue('mathfont')->merge(forcebold => 0), 'local'); }
else { Error('unexpected', $version, $stomach, "Unknown math verison '$version'"); } });
DefMacro('\not@math@alphabet{}{}', '\relax
\ifmmode
\@latex@error{Command \noexpand#1 invalid in math mode}%
{%
Please
\ifx#2\relax
define a new math alphabet
if you want to use a special font in math mode%
\else
use the math alphabet \noexpand#2 instead of
the #1 command%
\fi.
}%
\fi');
DefMacro('\math@version', 'normal');
DefPrimitive('\DeclareOldFontCommand{}{}{}', sub {
my ($stomach, $cmd, $font, $mathcmd) = @_;
DefMacroI($cmd, undef, sub {
return (LookupValue('IN_MATH') ? $mathcmd->unlist : $font->unlist); });
# Tokens(T_CS('\ifmmode'), $mathcmd->unlist, T_CS('\else'), $font->unlist, T_CS('\fi')));
return; });
DefMacro('\newfont{}{}', '\font#1=#2\relax');
Let('\normalcolor', '\relax');
#======================================================================
# C.15.2 Changing the Type Size
#======================================================================
# Handled in TeX.pool.ltxml
#======================================================================
# C.15.3 Special Symbol
#======================================================================
DefMacro('\symbol{}', '\char#1\relax');
# These in LaTeX, but not in the book...
DefPrimitiveI('\textdollar', undef, "\$");
DefPrimitiveI('\textemdash', undef, "\x{2014}"); # EM DASH
DefPrimitiveI('\textendash', undef, "\x{2013}"); # EN DASH
DefPrimitiveI('\textexclamdown', undef, UTF(0xA1)); # INVERTED EXCLAMATION MARK
DefPrimitiveI('\textquestiondown', undef, UTF(0xBF)); # INVERTED QUESTION MARK
DefPrimitiveI('\textquotedblleft', undef, "\x{201C}"); # LEFT DOUBLE QUOTATION MARK
DefPrimitiveI('\textquotedblright', undef, "\x{201D}"); # RIGHT DOUBLE QUOTATION MARK
DefPrimitiveI('\textquotedbl', undef, "\""); # plain ascii DOUBLE QUOTATION
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
# if not - use the combining accent.
# For now supports the range 0 to 20 as well as the latin alphabet.
my $is_number = $text =~ /^\d+$/;
my $content = $unicode_enclosed_alphanumerics{$text} || "$text\x{20DD}";
my %props = $STATE->lookupValue('IN_MATH') ?
(role => ($is_number ? 'NUMBER' : 'UNKNOWN'), meaning => "circled-$text") : ();
return Box($content, undef, undef, undef, %props); });
DefPrimitiveI('\SS', undef, 'SS', # ?
locked => 1); # cause it shows up in uclist!
DefMacroI('\dag', undef, '\ifmmode{\dagger}\else\textdagger\fi');
DefMacroI('\ddag', undef, '\ifmmode{\ddagger}\else\textdaggerdbl\fi');
DefConstructor('\sqrtsign Digested',
"<ltx:XMApp><ltx:XMTok meaning='square-root'/><ltx:XMArg>#1</ltx:XMArg></ltx:XMApp>");
DefPrimitiveI('\mathparagraph', undef, UTF(0xB6));
DefPrimitiveI('\mathsection', undef, UTF(0xA7));
DefPrimitiveI('\mathdollar', undef, '$');
DefPrimitiveI('\mathsterling', undef, UTF(0xA3));
DefPrimitiveI('\mathunderscore', undef, '_');
DefPrimitiveI('\mathellipsis', undef, "\x{2026}");
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
\def\@nameuse#1{\csname #1\endcsname}
\def\@cons#1#2{\begingroup\let\@elt\relax\xdef#1{#1\@elt #2}\endgroup}
\def\@car#1#2\@nil{#1}
\def\@cdr#1#2\@nil{#2}
\def\@carcube#1#2#3#4\@nil{#1#2#3}
\def\nfss@text#1{{\mbox{#1}}}
\def\@sect#1#2#3#4#5#6[#7]#8{}
EoTeX
Let('\@begindocumenthook', '\@empty');
DefMacroI('\@preamblecmds', undef, Tokens());
DefMacro('\@ifdefinable DefToken {}', sub {
my ($gullet, $token, $if) = @_;
if (isDefinable($token)) {
return $if->unlist }
else {
my ($slash, @s) = ExplodeText($token->toString);
DefMacroI('\reserved@a', undef, Tokens(@s));
return (T_CS('\@notdefinable')); } });
Let('\@@ifdefinable', '\@ifdefinable');
DefMacro('\@rc@ifdefinable DefToken {}', sub {
my ($gullet, $token, $if) = @_;
Let('\@ifdefinable', '\@@ifdefinable');
return $if->unlist; });
DefMacroI('\@notdefinable', undef, <<'EOL');
\@latex@error{%
Command \@backslashchar\reserved@a\space
already defined.
Or name \@backslashchar\@qend... illegal,
see p.192 of the manual}
EOL
DefMacroI('\@qend', undef, Tokens(Explode('end')));
DefMacroI('\@qrelax', undef, Tokens(Explode('relax')));
DefMacroI('\@spaces', undef, '\space\space\space\space');
Let('\@sptoken', T_SPACE);
DefMacroI('\@uclclist', undef, '\oe\OE\o\O\ae\AE\dh\DH\dj\DJ\l\L\ng\NG\ss\SS\th\TH');
RawTeX(<<'EOL');
\DeclareRobustCommand{\MakeUppercase}[1]{{%
\def\i{I}\def\j{J}%
\def\reserved@a##1##2{\let##1##2\reserved@a}%
\expandafter\reserved@a\@uclclist\reserved@b{\reserved@b\@gobble}%
\let\UTF@two@octets@noexpand\@empty
\let\UTF@three@octets@noexpand\@empty
\let\UTF@four@octets@noexpand\@empty
\protected@edef\reserved@a{\uppercase{#1}}%
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
\let\UTF@four@octets@noexpand\@empty
\protected@edef\reserved@a{\lowercase{#1}}%
\reserved@a
}}
\protected@edef\MakeUppercase#1{\MakeUppercase{#1}}
\protected@edef\MakeLowercase#1{\MakeLowercase{#1}}
EOL
#======================================================================
DefMacroI('\@ehc', undef, "I can't help");
DefMacro('\@gobble{}', Tokens());
DefMacro('\@gobbletwo{}{}', Tokens());
DefMacro('\@gobblefour{}{}{}{}', Tokens());
DefMacro('\@firstofone{}', sub { $_[1]; });
Let('\@iden', '\@firstofone');
DefMacro('\@firstoftwo{}{}', sub { $_[1]; });
DefMacro('\@secondoftwo{}{}', sub { $_[2]; });
DefMacro('\@thirdofthree{}{}{}', sub { $_[3]; });
DefMacro('\@expandtwoargs{}{}{}', sub {
($_[1]->unlist, T_BEGIN, Expand($_[2])->unlist, T_END, T_BEGIN, Expand($_[3])->unlist, T_END); });
DefMacro('\@makeother{}', sub {
my $letter = ToString($_[1]); $letter =~ s/^\\//;
AssignCatcode($letter => CC_OTHER, 'local'); });
RawTeX(<<'EoTeX');
{\catcode`\^^M=13 \gdef\obeycr{\catcode`\^^M13 \def^^M{\\\relax}%
\@gobblecr}%
{\catcode`\^^M=13 \gdef\@gobblecr{\@ifnextchar
\@gobble\ignorespaces}}%
\gdef\restorecr{\catcode`\^^M5 }}
EoTeX
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
\def\@sanitize{\@makeother\ \@makeother\\\@makeother\$\@makeother\&%
\@makeother\#\@makeother\^\@makeother\_\@makeother\%\@makeother\~}
\def \@onelevel@sanitize #1{%
\edef #1{\expandafter\strip@prefix
\meaning #1}%
}
\def\dospecials{\do\ \do\\\do\{\do\}\do\$\do\&%
\do\#\do\^\do\_\do\%\do\~}
EoTeX
DefMacroI('\nfss@catcodes', undef, <<'EOMacro');
\makeatletter
\catcode`\ 9%
\catcode`\^^I9%
\catcode`\^^M9%
\catcode`\\\z@
\catcode`\{\@ne
\catcode`\}\tw@
\catcode`\#6%
\catcode`\^7%
\catcode`\%14%
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
\@makeother\>%
\@makeother\*%
\@makeother\.%
\@makeother\-%
\@makeother\/%
\@makeother\[%
\@makeother\]%
\@makeother\`%
\@makeother\'%
\@makeother\"%
EOMacro
DefMacroI('\ltx@hard@MessageBreak', undef, '^^J');
sub make_message {
my ($cmd, @args) = @_;
my $stomach = $STATE->getStomach;
my $lead_arg = ToString(shift(@args)) || '';
$lead_arg =~ s/(?:\\\@?spaces?)+//g;
my $type = $lead_arg || $cmd;
$stomach->bgroup;
Let('\protect', '\string');
# Note that the arg really should be digested to get to the underlying text,
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
\GenericInfo{%
\@spaces\@spaces\@spaces
}{%
LaTeX Info: #1%
}%
}
\def\@latex@info@no@line#1{%
\@latex@info{#1\@gobble}}
EoTeX
DefMacro('\@setsize{}{}{}{}', '');
DefMacro('\hexnumber@ {}', '\ifcase\number#1
0\or 1\or 2\or 3\or 4\or 5\or 6\or 7\or 8\or
9\or A\or B\or C\or D\or E\or F\fi');
DefMacro('\on@line', ' on input line \the\inputlineno');
Let('\@warning', '\@latex@warning');
Let('\@@warning', '\@latex@warning@no@line');
DefMacro('\G@refundefinedtrue', '');
DefMacro('\@nomath{}',
'\relax\ifmmode\@font@warning{Command \noexpand#1invalid in math mode}\fi');
DefMacro('\@font@warning{}',
'\GenericWarning{(Font)\@spaces\@spaces\@spaces\space\space}{LaTeX Font Warning: #1}');
#======================================================================
RawTeX(<<'EOTeX');
\chardef\@xxxii=32
\mathchardef\@Mi=10001
\mathchardef\@Mii=10002
\mathchardef\@Miii=10003
\mathchardef\@Miv=10004
\def\@fontenc@load@list{\@elt{T1,OT1}}
EOTeX
DefMacroI('\@vpt', undef, '5');
DefMacroI('\@vipt', undef, '6');
DefMacroI('\@viipt', undef, '7');
DefMacroI('\@viiipt', undef, '8');
DefMacroI('\@ixpt', undef, '9');
DefMacroI('\@xpt', undef, '10');
DefMacroI('\@xipt', undef, '10.95');
DefMacroI('\@xiipt', undef, '12');
DefMacroI('\@xivpt', undef, '14.4');
DefMacroI('\@xviipt', undef, '17.28');
DefMacroI('\@xxpt', undef, '20.74');
DefMacroI('\@xxvpt', undef, '24.88');
DefMacroI('\@tempa', undef, '');
DefMacroI('\@tempb', undef, '');
DefMacroI('\@tempc', undef, '');
DefMacroI('\@gtempa', undef, '');
RawTeX(<<'EOTeX');
\long\def \loop #1\repeat{%
\def\iterate{#1\relax % Extra \relax
\expandafter\iterate\fi
}%
\iterate
\let\iterate\relax
}
\newdimen\@ydim
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
\newif\if@inlabel \@inlabelfalse
\newif\if@newlist \@newlistfalse
\newif\if@noparitem \@noparitemfalse
\newif\if@noparlist \@noparlistfalse
\newif\if@noitemarg \@noitemargfalse
\newif\if@nmbrlist \@nmbrlistfalse
\def\glb@settings{}%
EOTeX
DefMacroI('\@height', undef, 'height');
DefMacroI('\@width', undef, 'width');
DefMacroI('\@depth', undef, 'depth');
DefMacroI('\@minus', undef, 'minus');
DefMacroI('\@plus', undef, 'plus');
DefMacroI('\hb@xt@', undef, '\hbox to');
DefMacroI('\hmode@bgroup', undef, '\leavevmode\bgroup');
DefMacroI('\@backslashchar', undef, T_OTHER('\\'));
DefMacroI('\@percentchar', undef, T_OTHER('%'));
DefMacroI('\@charlb', undef, T_LETTER('{'));
DefMacroI('\@charrb', undef, T_LETTER('}'));
#======================================================================
DefMacroI('\check@mathfonts', undef, Tokens());
DefMacro('\fontsize{}{}', Tokens());
# https://tex.stackexchange.com/questions/112492/setfontsize-vs-fontsize#112501
DefMacro('\@setfontsize{}{}{}', '\let\@currsize#1');
DefMacroI('\@vpt', undef, T_OTHER('5'));
DefMacroI('\@vipt', undef, T_OTHER('6'));
DefMacroI('\@viipt', undef, T_OTHER('7'));
DefMacroI('\@viiipt', undef, T_OTHER('8'));
DefMacroI('\@ixpt', undef, T_OTHER('9'));
DefMacro('\@xpt', '10');
DefMacro('\@xipt', '10.95');
DefMacro('\@xiipt', '12');
DefMacro('\@xivpt', '14.4');
DefMacro('\@xviipt', '17.28');
DefMacro('\@xxpt', '20.74');
DefMacro('\@xxvpt', '24.88');
DefMacro('\vpt', '\edef\f@size{\@vpt}\rm');
DefMacro('\vipt', '\edef\f@size{\@vipt}\rm');
DefMacro('\viipt', '\edef\f@size{\@viipt}\rm');
DefMacro('\viiipt', '\edef\f@size{\@viiipt}\rm');
DefMacro('\ixpt', '\edef\f@size{\@ixpt}\rm');
DefMacro('\xpt', '\edef\f@size{\@xpt}\rm');
DefMacro('\xipt', '\edef\f@size{\@xipt}\rm');
DefMacro('\xiipt', '\edef\f@size{\@xiipt}\rm');
DefMacro('\xivpt', '\edef\f@size{\@xivpt}\rm');
DefMacro('\xviipt', '\edef\f@size{\@xviipt}\rm');
DefMacro('\xxpt', '\edef\f@size{\@xxpt}\rm');
DefMacro('\xxvpt', '\edef\f@size{\@xxvpt}\rm');
DefMacroI('\defaultscriptratio', undef, '.7');
DefMacroI('\defaultscriptscriptratio', undef, '.5');
#======================================================================
DefMacroI('\loggingoutput', undef, Tokens());
DefMacroI('\loggingall', undef, Tokens());
DefMacroI('\tracingfonts', undef, Tokens());
DefMacroI('\showoverfull', undef, Tokens());
DefMacroI('\showoutput', undef, Tokens());
#======================================================================
# Various symbols, accents, etc from Chapter 3 defined in TeX.pool
#**********************************************************************
# Semi-Undocumented stuff
#**********************************************************************
DefMacro('\@ifnextchar DefToken {}{}', sub {
my ($gullet, $token, $if, $else) = @_;
my $next = $gullet->readNonSpace;
# NOTE: Not actually substituting, but collapsing ## pairs!!!!
# use \egroup for $next, if we've fallen off end?
((XEquals($token, (defined $next ? $next : T_END)) ? $if : $else)->unlist,
(defined $next ? ($next) : ())); });
Let('\kernel@ifnextchar', '\@ifnextchar');
Let('\@ifnext', '\@ifnextchar'); # ????
# Hacky version matches multiple chars! but does NOT expand
DefMacro('\@ifnext@n {} {}{}', sub {
my ($gullet, $tokens, $if, $else) = @_;
my @toks = $tokens->unlist;
my @read = ();
while (my $t = $gullet->readToken) {
push(@read, $t);
if ($t->equals($toks[0])) { shift(@toks); }
else { last; } }
return Tokens((@toks ? $else->unlist : $if->unlist), @read); });
DefMacro('\@ifstar {}{}', sub {
my ($gullet, $if, $else) = @_;
my $next = $gullet->readNonSpace;
if (T_OTHER('*')->equals($next)) {
$if; }
else {
($else, ($next ? $next : ())); } });
DefMacro('\@dblarg {}', '\kernel@ifnextchar[{#1}{\@xdblarg{#1}}');
DefMacro('\@xdblarg {}{}', '#1[{#2}]{#2}');
DefMacro('\@testopt{}{}', sub {
my ($gullet, $cmd, $option) = @_;
($gullet->ifNext(T_OTHER('[')) ? $cmd->unlist
: ($cmd->unlist, T_OTHER('['), $option->unlist, T_OTHER(']'))); });
RawTeX(<<'EoTeX');
\def\@protected@testopt#1{%%
\ifx\protect\@typeset@protect
\expandafter\@testopt
\else
\@x@protect#1%
\fi}
EoTeX
Let('\l@ngrel@x', '\relax'); # Never actually used anywhere, but...
DefMacro('\@star@or@long{}', '\@ifstar{\let\l@ngrel@x\relax#1}{\let\l@ngrel@x\long#1}');
# maybe this is easiest just to punt.
RawTeX(<<'EoTeX');
\def\in@#1#2{%
\def\in@@##1#1##2##3\in@@{%
\ifx\in@##2\in@false\else\in@true\fi}%
\in@@#2#1\in@\in@@}
\newif\ifin@
EoTeX
DefMacro('\IfFileExists{}{}{}', sub {
my ($gullet, $file, $if, $else) = @_;
my $file_string = ToString(Expand($file));
if (FindFile($file_string)) {
DefMacro('\@filef@und', '"' . $file_string . '" ');
return ($if->unlist); }
else {
return ($else->unlist); } });
DefMacro('\InputIfFileExists{}{}{}', sub {
my ($gullet, $file, $if, $else) = @_;
$file = Expand($file);
my $file_string = ToString($file);
if (FindFile($file_string)) {
DefMacro('\@filef@und', '"' . $file_string . '" ');
return Tokens($if, T_CS('\@addtofilelist'), T_BEGIN, $file, T_END,
T_CS('\ltx@input'), T_BEGIN, $file, T_END); }
else { return ($else->unlist); } });
#======================================================================
# Hair
DefPrimitiveI('\makeatletter', undef, sub { AssignCatcode('@' => CC_LETTER, 'local'); });
DefPrimitiveI('\makeatother', undef, sub { AssignCatcode('@' => CC_OTHER, 'local'); });
#**********************************************************************
#**********************************************************************
# Sundry (is this ams ?)
DefPrimitiveI('\textprime', undef, UTF(0xB4)); # ACUTE ACCENT
Let('\endgraf', '\par');
Let('\endline', '\cr');
#**********************************************************************
# Should be defined in each (or many) package, but it's not going to
# get set correctly or maintained, so...
DefMacroI('\fileversion', undef, Tokens());
DefMacroI('\filedate', undef, Tokens());
# Ultimately these may be overridden by babel, or otherwise,
# various of these are defined in various places by different classes.
DefMacroI('\chaptername', undef, 'Chapter');
DefMacroI('\partname', undef, 'Part');
# The rest of these are defined in some classes, but not most.
#DefMacroI('\sectionname', undef, 'Section');
#DefMacroI('\subsectionname', undef, 'Subsection');
#DefMacroI('\subsubsectionname', undef, 'Subsubsection');
#DefMacroI('\paragraphname', undef, 'Paragraph');
#DefMacroI('\subparagraphname', undef, 'Subparagraph');
DefMacroI('\appendixname', undef, 'Appendix');
# These aren't defined in LaTeX,
# these definitions will give us more meaningful typerefnum's
DefMacroI('\sectiontyperefname', undef, '\lx@sectionsign\lx@ignorehardspaces');
DefMacroI('\subsectiontyperefname', undef, '\lx@sectionsign\lx@ignorehardspaces');
DefMacroI('\subsubsectiontyperefname', undef, '\lx@sectionsign\lx@ignorehardspaces');
DefMacroI('\paragraphtyperefname', undef, '\lx@paragraphsign\lx@ignorehardspaces');
DefMacroI('\subparagraphtyperefname', undef, '\lx@paragraphsign\lx@ignorehardspaces');
#**********************************************************************
# Stuff that would appear in the aux file... maybe somebody uses it?
DefMacro('\bibdata{}', Tokens());
DefMacro('\bibcite{}{}', Tokens());
DefMacro('\citation{}', Tokens());
DefMacro('\contentsline{}{}{}', Tokens());
DefMacro('\newlabel{}{}', Tokens());
DefMacroI('\stop', undef, sub { $_[0]->closeMouth(1); return; });
DefMacroI('\ignorespacesafterend', undef, Tokens());
Let('\mathgroup', '\fam');
Let('\mathalpha', '\relax');
#\def\mathhexbox#1#2#3{\mbox{$\m@th \mathchar"#1#2#3$}}
DefPrimitive('\mathhexbox {}{}{}', sub {
my ($stomach, $a, $b, $c) = @_;
my $n = ToString($a) * 256 + ToString($b) * 16 + ToString($c);
my ($role, $glyph) = decodeMathChar($n);
return Box($glyph, LookupValue('font')->specialize($glyph)); });
DefMacroI('\nocorrlist', undef, ',.');
Let('\nocorr', '\relax');
Let('\check@icl', '\@empty');
Let('\check@icr', '\@empty');
DefMacro('\text@command{}', ''); # ?
DefMacro('\check@nocorr@ Until:\nocorr Until:\@nil', '');
RawTeX('\newif\ifmaybe@ic');
DefMacroI('\maybe@ic', undef, '');
DefMacroI('\maybe@ic@', undef, '');
# \t@st@ic
DefMacroI('\sw@slant', undef, '');
DefMacroI('\fix@penalty', undef, '');
DefPrimitiveI('\@@end', undef, sub { $_[0]->getGullet->flush; return; });
#**********************************************************************
# Modern pdflatex seems to come with hyphenation tables predefined
# for many languages. We don't need or use hyphenation tables,
# but some (versions of some) software (babel), check for
# the presence of these \l@<language> macros
# But also see \iflanguage (re)defined in babel.def.ltxml
RawTeX(<<'EoTeX');
lib/LaTeXML/Package/LaTeX.pool.ltxml view on Meta::CPAN
return @stuff; });
#**********************************************************************
# LaTeX now includes fixltx2e by default.
# https://www.latex-project.org/news/latex2e-news/ltnews22.pdf
# This package allows you to define the font used for
# emphasis (\emph) within emphasis.
# For latexml, that styling should be left to the ultimate output,
# so we just define the command as a dummy.
DefMacro('\eminnershape', "");
# Undoubtedly not good enough
DefMacro('\TextOrMath{}{}', '\ifmmode#2\else#1\fi');
DefConstructor('\textsubscript{}', "<ltx:sub>#1</ltx:sub>",
mode => 'text');
#**********************************************************************
# We need this bit from utf8.def for textcomp
DefPrimitive('\DeclareUnicodeCharacter Expanded {}', sub {
my ($stomach, $hexcode, $expansion) = @_;
my $char = $hexcode->toString();
if ($char =~ /^[0-9a-fA-F]+$/) {
if ((my $cp = hex($char)) <= 0x10FFFF) {
$char = UTF($cp);
AssignCatcode($char, CC_ACTIVE);
DefMacroI(T_ACTIVE($char), undef, $expansion); }
else {
Error('unexpected', $char, $stomach,
"$char too large for Unicode. Values between 0 and 10FFFF are permitted."); } }
else {
Error('unexpected', $char, $stomach,
"'$char' is not a hexadecimal number."); } });
# LaTeX now includes textcomp by default.
RequirePackage('textcomp');
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Expl3 "Experimental LaTeX 3" is no longer Experimental!
# It is beginning to be built into latex.ltx
# We WILL need a new strategy to keep up; probably based in some form
# of pre-read/pre-processed latex.ltx !
#
# For now, a few macros required by other packages will be included:
DefMacroI(T_CS('\hook_gput_code:nnn'), '{}{}{}', '');
DefMacro('\NewHook{}', '');
DefMacro('\NewReversedHook{}', '');
DefMacro('\NewMirroredHookPair{}{}', '');
DefMacro('\ActivateGenericHook{}', '');
DefMacro('\DisableGenericHook{}', '');
DefMacro('\AddToHook{}[]{}', '');
DefMacro('\AddToHookNext{}{}', '');
DefMacro('\ClearHookNext{}', '');
DefMacro('\RemoveFromHook{}[]', '');
DefMacro('\SetDefaultHookLabel{}', '');
DefMacro('\PushDefaultHookLabel{}', '');
DefMacro('\PopDefaultHookLabel', '');
DefMacro('\UseHook{}', '');
DefMacro('\UseOneTimeHook{}', '');
DefMacro('\ShowHook{}', '');
DefMacro('\LogHook{}', '');
DefMacro('\DebugHooksOn', '');
DefMacro('\DebugHooksOff', '');
DefMacro('\DeclareHookRule{}{}{}{}', '');
DefMacro('\DeclareDefaultHookRule{}{}{}', '');
DefMacro('\ClearHookRule{}{}{}', '');
DefMacro('\IfHookEmptyTF{}{}{}', '#3');
DefMacro('\IfHookExistsTF{}{}{}', '#3');
DefMacro('\MakeTextLowercase', '\lowercase');
DefMacro('\MakeTextUppercase', '\uppercase');
DefConditional('\if@includeinrelease');
Let('\@kernel@after@enddocument', '\@empty');
Let('\@kernel@after@enddocument@afterlastpage', '\@empty');
Let('\@kernel@before@begindocument', '\@empty');
Let('\@kernel@after@begindocument', '\@empty');
Let('\conditionally@traceon', '\@empty');
Let('\conditionally@traceoff', '\@empty');
#**********************************************************************
1;
lib/LaTeXML/Package/OmniBus.cls.ltxml view on Meta::CPAN
# natbib is also often used, but reportedly clashes with cite.sty
# We'll autoload natbib if it hasn't already been loaded, and if any of its obvious macros are used.
foreach my $trigger (qw(citet citep citealt citealp citenum citeauthor citefullauthor
citeyear citeyearpar citeauthoryear setcitestyle bibpunct)) {
DefAutoload($trigger, 'natbib.sty.ltxml'); }
Let('\lx@OmniBus@saved@bibitem', '\bibitem');
# Another hacky autoload: Recognize \bibitem[\protect\citeauthoryear...
# when it would otherwise be too late to fix.
DefPrimitive('\lx@late@usepackage Semiverbatim', sub { RequirePackage(ToString($_[1])); });
DefMacro('\bibitem',
'\@ifnext@n{[\protect\citeauthoryear}{\lx@late@usepackage{natbib}\bibitem}{\lx@OmniBus@saved@bibitem}');
DefEnvironment('{frontmatter}', '#body');
DefEnvironment('{mainmatter}', '#body');
DefEnvironment('{backmatter}', '#body');
DefMacro('\shorttitle{}', '\@add@frontmatter{ltx:toctitle}{#1}');
DefMacro('\subtitle{}', '\@add@frontmatter{ltx:subtitle}{#1}');
DefMacro('\shortauthor{}', '');
DefRegister('\titlerunning', Tokens());
DefRegister('\authorrunning', Tokens());
Let('\runningauthor', '\authorrunning');
Let('\runauthor', '\authorrunning');
DefMacro('\runningtitle{}', Tokens());
Let('\runninghead', '\runningtitle');
DefMacro('\shortauthor{}', Tokens());
DefMacro('\authors{}', Tokens());
DefMacro('\shortauthors{}', Tokens());
DefMacro('\alignauthor', Tokens());
DefConstructor('\@@@email{}{}', "^ <ltx:contact role='#2'>#1</ltx:contact>");
DefMacro('\email{}', '\@add@to@frontmatter{ltx:creator}{\@@@email{#1}{email}}');
Let('\emailaddr', '\email');
DefMacro('\ead{}[]', '\@add@to@frontmatter{ltx:creator}{\@@@email{#1}{#2}}');
DefMacro('\emailname', 'E-mail');
DefMacro('\speaker{}', '\@add@frontmatter{ltx:creator}[role=speaker]{\@personname{#1}}');
# like from aas
DefConstructor('\@@@affiliation{}', "^ <ltx:contact role='affiliation'>#1</ltx:contact>");
DefMacro('\affil{}', '\@add@to@frontmatter{ltx:creator}{\@@@affiliation{#1}}');
DefMacro('\altaffilmark{}', sub {
my ($gullet, $marks) = @_;
map { (T_CS('\@altaffilmark'), T_BEGIN, @$_, T_END) } SplitTokens($marks, T_OTHER(',')); });
DefConstructor('\@altaffilmark{}',
"?#1(<ltx:note role='affiliationmark' mark='#1'/> )()");
Let('\affilnum', '\@altaffilmark');
DefConstructor('\altaffiltext{}{}',
"?#2(<ltx:note role='affiliationtext' mark='#1'>#2</ltx:note>)()");
DefConstructor('\@@@address{}', "^ <ltx:contact role='address'>#1</ltx:contact>");
DefMacro('\address[]{}', '\@add@to@frontmatter{ltx:creator}{\@@@address{#2}}');
Let('\affaddr', '\address');
DefMacro('\affiliation{}', '\@add@to@frontmatter{ltx:creator}{\@@@affiliation{#1}}');
DefRegister('\affilskip' => Dimension(0));
# some rarer name macros that are functionally no-ops for latexml
DefMacro('\prefix{}', '#1');
DefMacro('\suffix{}', '#1');
DefMacro('\fnms{}', '#1');
DefMacro('\snm{}', '#1');
DefMacro('\inits{}', '#1');
DefMacro('\printaddresses{}', '#1');
DefMacro('\printead{}', Tokens());
DefMacro('\firstpage{}', Tokens());
DefMacro('\lastpage{}', Tokens());
DefMacro('\runauthor{}', Tokens());
DefMacro('\runtitle{}', Tokens());
DefMacro('\corref{}', Tokens());
DefMacro('\listofauthors{}', Tokens());
DefMacro('\indexauthor{}', Tokens());
DefMacro('\preface', Tokens());
DefMacro('\thankstext', Tokens());
DefMacro('\numberofauthors{}', Tokens());
DefMacro('\resumen{}', '\@add@frontmatter{ltx:abstract}{#1}');
DefMacro('\ion{}{}', '{#1 \textsc{#2}}');
Let(T_CS('\fulladdresses'), T_CS('\address'));
Let(T_CS('\smonth'), T_CS('\month'));
Let(T_CS('\syear'), T_CS('\year'));
# Comes as both macro with arg, and environment! w/ or w/o "s"!
DefMacro('\keywords{}', '\@add@frontmatter{ltx:keywords}{#1}');
DefMacro('\kword{}', '\@add@frontmatter{ltx:keywords}{#1}');
DefMacro('\kwd[]{}', '\@add@frontmatter{ltx:keywords}{#2, }');
# {keyword}, {keywords}
sub after_digest_keywords {
my $frontmatter = LookupValue('frontmatter');
push(@{ $$frontmatter{'ltx:classification'} },
['ltx:classification', { scheme => 'keywords' }, @LaTeXML::LIST]);
return; }
DefEnvironment('{keyword}', '', afterDigest => \&after_digest_keywords);
DefEnvironment('{keywords}', '', afterDigest => \&after_digest_keywords);
# Extend to be callable as \keywords{} or \begin{keywords}...
# Probably want to use this trick more often?
Let('\lx@begin@keywords', '\keywords');
sub auto_keywords {
my ($gullet) = @_;
return ($gullet->ifNext(T_BEGIN)
? (T_CS('\keywords@onearg'))
: (T_CS('\g@addto@macro'), T_CS('\@startsection@hook'), T_CS('\maybe@end@keywords'),
T_CS('\lx@begin@keywords'))); }
# see arxiv:math/0601658 for a singular {keyword} example
DefMacro('\keyword', \&auto_keywords);
DefMacro('\keywords', \&auto_keywords);
DefMacro('\keywords@onearg{}', '\begin{keywords}#1\end{keywords}\let\endkeyword\relax\let\endkeywords\relax');
DefMacroI('\maybe@end@keywords', undef, '\endkeywords\let\maybe@end@keywords\relax');
Let(T_CS('\addto@keywords@list'), T_CS('\keyword'));
DefMacro('\classification{}', '\@add@frontmatter{ltx:classification}{#1}');
DefMacro('\pacs{}', '\@add@frontmatter{ltx:classification}[scheme=pacs]{#1}', locked => 1);
# \doi{doi} might be frontmatter, or just a \url-like thing. So, let's guess!
DefMacro('\doi{}',
'\if@in@preamble{\@add@frontmatter{ltx:classification}[scheme=doi]{#1}'
. '\else\lx@doi{#1}\fi');
DefConstructor('\lx@doi{}', '<ltx:ref href="https:/doi.org/#1">#1</ltx:ref>');
# from acm_proc_article, is it general enough?
DefMacro('\category{}{}{}[]', '\@add@frontmatter{ltx:classification}[scheme=category]{#1 #2 #3}\keywords{#4}');
our $omni_theorem_main = <<'EOL';
\newtheorem{theorem}{Theorem}[section]
\newtheorem{conjecture}[theorem]{Conjecture}
\newtheorem{proposition}[theorem]{Proposition}
\newtheorem{proof}[theorem]{Proof}
\newtheorem{lemma}[theorem]{Lemma}
\newtheorem{corollary}[theorem]{Corollary}
\newtheorem{example}[theorem]{Example}
\newtheorem{exercise}[theorem]{Exercise}
lib/LaTeXML/Package/OmniBus.cls.ltxml view on Meta::CPAN
\newtheorem{prob}[thm]{Problem}
\newtheorem{prin}[thm]{Principle}
\newtheorem{alg}{Algorithm}
EOL
for my $env (qw(
conjecture theorem corollary definition example exercise lemma
note problem proof proposition question remark solution
thm cor lem claim axiom conj fact hypo assum prop crit defn exmp rem prob prin alg)) {
my $beginenv = "\\begin{$env}";
DefMacroI(T_CS($beginenv), undef, sub {
RequirePackage('amsthm');
return Tokenize($omni_theorem_main . $omni_theorem_aux . $beginenv)->unlist; }); }
for my $new_theorem_alias (qw(\newproclaim \newdef \newremark)) {
DefMacroI(T_CS($new_theorem_alias), undef, sub {
RequirePackage('amsthm');
return T_CS('\newtheorem'); }); }
DefAutoload('theoremstyle', 'amsthm.sty.ltxml');
Let('\abstracts', '\abstract');
Let('\abst', '\abstract');
# Seems to come in different spellings and often misused!
DefConstructor('\acknowledgments', "<ltx:acknowledgements name='#name'>",
properties => sub { (name => Digest(T_CS('\acknowledgmentsname'))); });
DefConstructor('\endacknowledgments', "</ltx:acknowledgements>");
Tag("ltx:acknowledgements", autoClose => 1);
DefMacro('\acknowledgmentsname', 'Acknowledgements');
Let('\acknowledgements', '\acknowledgments');
Let('\endacknowledgements', '\endacknowledgments');
Let('\theacknowledgments', '\acknowledgments');
Let('\endtheacknowledgments', '\endacknowledgments');
DefMacro('\editors{}', '\@add@frontmatter{ltx:note}[role=editors]{#1}');
DefMacro('\received{}', '\@add@frontmatter{ltx:date}[role=received]{#1}');
DefMacro('\revised{}', '\@add@frontmatter{ltx:date}[role=revised]{#1}');
DefMacro('\accepted{}', '\@add@frontmatter{ltx:date}[role=accepted]{#1}');
DefMacro('\pubyear{}', '\@add@frontmatter{ltx:date}[role=publication]{#1}');
DefMacro('\copyrightyear{}', '\@add@frontmatter{ltx:date}[role=copyright]{#1}');
DefMacro('\preprint{}', '\@add@frontmatter{ltx:note}[role=preprint]{#1}');
DefMacro('\communicated{}', '\@add@frontmatter{ltx:date}[role=communicated]{#1}');
DefMacro('\dedicated{}', '\@add@frontmatter{ltx:note}[role=dedicated]{#1}');
DefMacro('\presented{}', '\@add@frontmatter{ltx:date}[role=presented]{#1}');
DefMacro('\articletype{}', '\@add@frontmatter{ltx:note}[role=articletype]{#1}');
DefMacro('\issue{}', '\@add@frontmatter{ltx:note}[role=issue]{#1}');
DefMacro('\journal{}', '\@add@frontmatter{ltx:note}[role=journal]{#1}');
DefMacro('\jname{}', '\@add@frontmatter{ltx:note}[role=journal]{#1}');
DefMacro('\volume{}', '\@add@frontmatter{ltx:note}[role=volume]{#1}');
DefMacro('\titlenote{}', '\@add@frontmatter{ltx:note}[role=titlenote]{#1}');
DefMacro('\terms{}', '\@add@frontmatter{ltx:note}[role=terms]{#1}');
DefMacro('\conferenceinfo{}{}', '\@add@frontmatter{ltx:note}[role=conference]{#1 #2}');
# what useful behavior can we add here? e.g. see arxiv:math/0601658
DefMacro('\thanksref{}', Tokens());
# rarer variants:
Let('\CopyrightYear', '\copyrightyear');
DefRegister('\confinfo', Tokens());
DefRegister('\acmcopyr', Tokens());
DefRegister('\copyrightetc', Tokens());
Let('\crdata', '\acmcopyr');
# work as environment or not...
DefConstructor('\references',
lib/LaTeXML/Package/OmniBus.cls.ltxml view on Meta::CPAN
beforeDigest => sub { beforeDigestBibliography(); },
afterDigest => sub { beginBibliography($_[1]); }
);
DefConstructor('\endreferences', sub {
$_[0]->maybeCloseElement('ltx:biblist');
$_[0]->maybeCloseElement('ltx:bibliography'); });
Let('\reference', '\bibitem');
DefMacro('\comment{}', '');
DefMacro('\etal', '\textit{et al.}');
DefMacro('\firstsection', '');
DefAutoload('align', 'amsmath.sty.ltxml');
DefAutoload('subequations', 'amsmath.sty.ltxml');
DefAutoload('split', 'amsmath.sty.ltxml');
DefAutoload('\multline', 'amsmath.sty.ltxml');
DefAutoload('\csname multline*\endcsname', 'amsmath.sty.ltxml');
DefAutoload('numberwithin', 'amsmath.sty.ltxml');
DefAutoload('mathfrak', 'amsfonts.sty.ltxml');
DefAutoload('mathbb', 'amsfonts.sty.ltxml');
DefAutoload('deluxetable', 'deluxetable.sty.ltxml');
DefAutoload('curraddr', 'ams_support.sty.ltxml');
DefAutoload('subjclass', 'ams_support.sty.ltxml');
DefAutoload('thechapter', 'book.cls.ltxml');
# nostalgicly painful from the 1990s arXiv:
# We lock to the internal definition, since we have
# \let\section\Section
# in some documents, and we don't want infinite loops
DefMacroI('\Section', undef, '\@startsection{section}{1}{}{}{}{}', locked => 1);
DefMacroI('\Subsection', undef, '\@startsection{subsection}{2}{}{}{}{}', locked => 1);
DefMacroI('\Subsubsection', undef, '\@startsection{subsubsection}{3}{}{}{}{}', locked => 1);
DefMacroI('\Paragraph', undef, '\@startsection{paragraph}{4}{}{}{}{}', locked => 1);
DefMacroI('\Subparagraph', undef, '\@startsection{subparagraph}{5}{}{}{}{}', locked => 1);
# author block, see e.g. arxbj.cls from arXiv:math0603447
DefEnvironment('{aug}', '#body');
1;
lib/LaTeXML/Package/PoS.cls.ltxml view on Meta::CPAN
use warnings;
use LaTeXML::Package;
# Proceedings of Science style.
LoadClass("JHEP", withoptions => 1);
RequirePackage('ifpdf');
RequirePackage('times');
RequirePackage('mathptmx');
RequirePackage('graphicx');
DefMacro('\ShortTitle{}', '\@add@frontmatter{ltx:toctitle}{#1}');
DefMacro('\PoScopydate{}', '\@add@frontmatter{ltx:date}[role=accepted]{#1}');
DefMacro('\PACSname', '\textbf{PACS}');
DefMacro('\PACS{}', '\@add@frontmatter{ltx:classification}[scheme=pacs,name={\PACSname}]{#1}');
DefMacro('\FullConference{}', ''); # Where to put this?
DefMacro('\Jmath', 'J');
#**********************************************************************
1;
lib/LaTeXML/Package/SIunits.sty.ltxml view on Meta::CPAN
# (things like \times, ^, etc appear)
Let('\unit', '\SI');
RawTeX(<<'EoTeX');
\sisetup{
parse-numbers = false,
input-product = \times,
}
EoTeX
DefMacro('\squaren{}', '{#1}^{2}');
# Apparently, all unit macros are available, all the time !!!
six_enableUnitMacros(1);
#======================================================================
1;
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
# or those prefixes defined by the Schema (typically RelaxNGSchema(..)
RegisterNamespace(ltx => "http://dlmf.nist.gov/LaTeXML");
RegisterNamespace(svg => "http://www.w3.org/2000/svg");
RegisterNamespace(xlink => "http://www.w3.org/1999/xlink"); # Needed for SVG
# Not directly used, but let's stake out the ground
RegisterNamespace(m => "http://www.w3.org/1998/Math/MathML");
RegisterNamespace(xhtml => "http://www.w3.org/1999/xhtml");
# Namespace for arbitrary data attributes (mapped to data-xxx in html5)
RegisterNamespace(data => "http://dlmf.nist.gov/LaTeXML/data");
DefMacroI("\\\@empty", undef, Tokens());
#======================================================================
# Core ID functionality.
#======================================================================
# DOCUMENTID is the ID of the document
# AND prefixes IDs on all other elements.
if (my $docid = LookupValue('DOCUMENTID')) {
# Wrap in T_OTHER so funny chars don't screw up (no space!)
DefMacroI('\thedocument@ID', undef, T_OTHER($docid)); }
else {
Let('\thedocument@ID', '\@empty'); }
NewCounter('@XMARG', 'document', idprefix => 'XM');
#======================================================================
Tag('ltx:document', afterOpen => \&ProcessPendingResources);
RequireResource('LaTeXML.css');
#======================================================================
# The default "initial context" for XML+RDFa specifies some default
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
MergeFont(family => 'typewriter'); },
afterDigest => sub {
$_[0]->egroup; },
reversion => sub { (T_BEGIN, Revert($_[0]), T_END); });
# Read Verbatim, but allows expanding command sequences
DefParameterType('HyperVerbatim', sub {
my ($gullet) = @_;
$gullet->readUntil(T_BEGIN);
StartSemiverbatim('%');
DefMacroI('\%', undef, T_OTHER('%'), scope => 'local');
DefMacroI('\#', undef, T_OTHER('#'), scope => 'local');
DefMacroI('\&', undef, T_OTHER('&'), scope => 'local');
DefMacroI('\textunderscore', undef, T_OTHER('_'), scope => 'local');
Let('\_', '\textunderscore');
DefMacroI('\hyper@tilde', undef, T_OTHER('~'), scope => 'local');
Let('\~', '\hyper@tilde');
Let('\textasciitilde', '\hyper@tilde');
Let('\\\\', '\@backslashchar');
my $arg = $gullet->readBalanced(1);
EndSemiverbatim();
return $arg; },
beforeDigest => sub {
$_[0]->bgroup;
MergeFont(family => 'typewriter'); },
afterDigest => sub {
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
beforeDigest => sub {
$_[0]->bgroup;
MergeFont(fraction => 1); },
afterDigest => sub {
$_[0]->egroup; },
reversion => sub { (T_BEGIN, Revert($_[0]), T_END); });
#**********************************************************************
# LaTeX has a very particular notion of "Undefined",
# so let's get that squared away at the outset; it's useful for TeX, too!
# Naturally, it uses \csname to check, which ends up DEFINING the possibly undefined macro as \relax
DefMacro('\@ifundefined{}{}{}', sub {
my ($gullet, $name, $if, $else) = @_;
my $cs = T_CS('\\' . ToString(Expand($name)));
if (IsDefined($cs)) {
return $else->unlist; }
else {
$STATE->assignMeaning($cs, $STATE->lookupMeaning(T_CS('\relax'))); # Let w/o AfterAssign
return $if->unlist; } },
locked => 1);
sub isDefinable {
my ($token) = @_;
return unless $token;
my $meaning = LookupMeaning($token);
my $name = $token->getString; $name =~ s/^\\//;
return (((!defined $meaning) || ($meaning eq LookupMeaning(T_CS('\relax')))
|| LookupValue('2.09_COMPATIBILITY')) # Let redefinitions happen in compatibility mode.
&& (($name ne 'relax') && ($name !~ /^end/))); }
#**********************************************************************
# Expandable Primitives
# See The TeXBook, Ch. 20, Definitions (also called Macros) pp. 212--215
#**********************************************************************
#======================================================================
# Should complain if we aren't actually evaluating an \if
# The following special cases are built-in to Definition
DefConditional('\else', undef);
DefConditional('\or', undef);
DefConditional('\fi', undef);
DefConditional('\ifcase Number', undef);
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
# (which seems most TeX like).
DefPrimitive('\relax', sub { (); });
### However, this keeps a box, so it can appear in UnTeX
### DefPrimitive('\relax',undef);
## But if you do that, you've got to watch out since it usually
### shouldn't be a box; See the isRelax code in handleScripts, below
# Internal token produced by Gullet in response to \dont_expand;
# Acts like \relax, but isn't equal to it.
DefPrimitiveI('\special_relax', undef, sub { (); });
DefMacro('\number Number', sub { Explode($_[1]->valueOf); });
# define it here (only approxmiately), since it's already useful.
Let('\protect', '\relax');
#======================================================================
DefMacro('\romannumeral Number', sub { roman($_[1]->valueOf); });
# Hmm... I wonder, should getString itself be dealing with escapechar?
sub escapechar {
my $code = LookupRegister('\escapechar')->valueOf;
return (($code >= 0) && ($code <= 255) ? chr($code) : ''); }
# 1) Knuth, The TeXBook, page 40, paragraph 1, Chapter 7: How TEX Reads What You Type.
# suggests all characters except spaces are returned in category code Other, i.e. Explode()
DefMacro('\string Token', sub {
my $s = $_[1]->toString;
if ($s =~ s/^\\//) {
$s = escapechar() . $s; }
Explode($s); });
DefMacroI('\jobname', undef, Tokens()); # Set to the filename by initialization
DefMacroI('\fontname', undef, sub { Explode("fontname not implemented"); });
our @CATCODE_MEANING = (
"the escape character", "begin-group character",
"end-group character", "math shift character",
"alignment tab character", "end-of-line character",
"macro parameter character", "superscript character",
"subscript character", "ignored character",
"blank space", "the letter",
"the character", "active character",
"comment character", "invalid character",
undef, "latexml marker character",
"macro parameter character");
# Not sure about this yet...
# NOTE: Lots of back-and-forth mangle with definition vs cs; don't do that!
DefMacro('\meaning Token', sub {
my ($gullet, $tok) = @_;
my $meaning = 'undefined';
if (my $definition = ($tok->defined_as(T_ALIGN) ? $tok : LookupMeaning($tok))) {
my $type = ref $definition;
$type =~ s/^LaTeXML:://;
# Pre-step: We can't extract the bodies of definitions which are defined via Perl subroutines.
# So do the next best thing -- represent them as their tokens.
if ($type =~ /(primitive|conditional|constructor)$/i) {
$definition = $definition->getCSorAlias;
$type = ref $definition;
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
"macro:$spec->$expansion_str$p_trailer"; }
elsif ($type =~ /chardef$/i) { # from \chardef or \mathchardef
my $prefix = ($$definition{mathglyph} ? '\mathchar' : '\char');
$meaning = $prefix . '"' . $definition->valueOf->valueOf; } }
# One catch: make sure all \s in the meaning string are normalized to a simple space ' '
$meaning =~ s/\s/ /g;
return Explode($meaning); });
DefParameterType('CSName', sub { $_[0]->readCSName; });
DefMacro('\csname CSName', sub {
my ($gullet, $token) = @_;
$STATE->assignMeaning($token, $STATE->lookupMeaning(T_CS('\relax'))) unless defined LookupMeaning($token);
$token; });
DefPrimitive('\endcsname', sub {
my ($stomach) = @_;
Error('unexpected', '\endcsname', $_[0], "Extra \\endcsname",
$stomach->getGullet->showUnexpected);
return; });
DefMacro('\expandafter Token Token', sub {
no warnings 'recursion';
my ($gullet, $tok, $xtok) = @_;
my $defn;
if (defined($defn = $STATE->lookupExpandable($xtok))) {
my @x = ();
{
local $LaTeXML::CURRENT_TOKEN = $xtok;
@x = $defn->invoke($gullet, 1); # Expand $xtok ONCE ONLY!
}
($tok, @x); }
elsif (!$STATE->lookupMeaning($xtok)) {
# Undefined token is an error, as expansion is expected.
# BUT The unknown token is NOT consumed, (see TeX B book, item 367)
# since probably in a real TeX run it would have been defined.
$STATE->generateErrorStub($gullet, $xtok);
($tok, $xtok); }
else {
($tok, $xtok); } });
use constant T_expandafter => T_CS('\expandafter');
DefMacro('\expandafter Token Token', sub {
no warnings 'recursion';
my ($gullet, $tok, $xtok) = @_;
my $defn;
my @skipped = ($tok);
while ($xtok->defined_as(T_expandafter)) {
push(@skipped, $gullet->readToken);
$xtok = $gullet->readToken; }
if (defined($defn = $STATE->lookupExpandable($xtok))) {
my @x = ();
{
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
# Undefined token is an error, as expansion is expected.
# BUT The unknown token is NOT consumed, (see TeX B book, item 367)
# since probably in a real TeX run it would have been defined.
$STATE->generateErrorStub($gullet, $xtok);
(@skipped, $xtok); }
else {
(@skipped, $xtok); } });
# If next token is expandable, prefix it with the internal marker \dont_expand
# That token is never defined, explicitly handled in Gullet & should never escape the Gullet
DefMacroI('\noexpand', undef, sub {
my $token = $_[0]->readToken;
# Missing token likely the result of "{\noexpand}" for which TeX would be unperturbed
return ($token
? ((($$token[1] == CC_CS) || ($$token[1] == CC_ACTIVE)) && $STATE->isDontExpandable($token)
? (T_CS('\dont_expand'), $token)
: $token)
: ()); });
DefPrimitiveI('\dont_expand', undef, sub {
Error('misdefined', '\dont_expand', $_[0],
"The token \\dont_expand should never reach Stomach!"); });
DefMacroI('\topmark', undef, Tokens());
DefMacroI('\firstmark', undef, Tokens());
DefMacroI('\botmark', undef, Tokens());
DefMacroI('\splitfirstmark', undef, Tokens());
DefMacroI('\splitbotmark', undef, Tokens());
DefMacro('\input TeXFileName', sub {
my $filename = $_[1];
my @t = $filename->unlist;
# If given a LaTeX-style argument, strip braces
if (@t && $t[0] && $t[0]->getCatcode == CC_BEGIN && $t[-1]->getCatcode == CC_END) {
$filename = Tokens(@t[1 .. $#t - 1]);
# and load LaTeX.pool if not already
if (!LookupValue('LaTeX.pool_loaded')) {
LoadPool("LaTeX"); } }
Input($filename, reloadable => 1); });
# Note that TeX doesn't actually close the mouth;
# it just flushes it so that it will close the next time it's read!
DefMacroI('\endinput', undef, sub { $_[0]->flushMouth; });
# \the<internal quantity>
DefMacro('\the Register', sub {
my ($gullet, $variable) = @_;
return () unless $variable;
my ($defn, @args) = @$variable;
if (!$defn || $defn eq 'missing') {
Error('expected', "<register>", $gullet, "a register was expected to be here"); return (); }
my $type = $defn->isRegister;
if (!$type) {
my $cs = ToString($defn->getCS);
if ($cs eq '\font') { # what to do here?
return T_CS('\tenrm'); }
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
escapechar => ord('\\'), endlinechar => ord("\r"), newlinechar => -1, maxdeadcycles => 0, hangafter => 0,
fam => -1, mag => 1000, magnification => 1000, delimiterfactor => 0,
time => 0, day => 0, month => 0, year => 0,
showboxbreadth => 5, showboxdepth => 3, errorcontextlines => 5);
foreach my $p (keys %iparms) {
DefRegister("\\$p", Number($iparms{$p})); }
}
# Most of these are ignored, but...
DefMacro('\tracingall',
'\tracingonline=1 \tracingcommands=2 \tracingstats=2'
. ' \tracingpages=1 \tracingoutput=1 \tracinglostchars=1'
. ' \tracingmacros=2 \tracingparagraphs=1 \tracingrestores=1'
. ' \showboxbreadth=\maxdimen \showboxdepth=\maxdimen \errorstopmode');
DefMacroI('\tracingnone', undef, Tokens());
DefMacroI('\hideoutput', undef, Tokens());
# This may mess up Daemon state?
{ my ($sec, $min, $hour, $mday, $mon, $year) = defined $ENV{SOURCE_DATE_EPOCH} ? gmtime($ENV{SOURCE_DATE_EPOCH}) : localtime();
AssignValue('\day' => Number($mday), 'global');
AssignValue('\month' => Number($mon + 1), 'global');
AssignValue('\year' => Number(1900 + $year), 'global');
AssignValue('\time' => Number(60 * $hour + $min), 'global'); }
our @MonthNames = (qw( January February March April May June
July August September October November December));
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
everyjob everycr everyhelp);
foreach my $p (@tparms) {
DefRegister("\\$p", Tokens()); }
}
#======================================================================
# Assignment, TeXBook Ch.24, p.275
#======================================================================
# <assignment> = <non-macro assignment> | <macro assignment>
#======================================================================
# Macros
# See Chapter 24, p.275-276
# <macro assignment> = <definition> | <prefix><macro assignment>
# <definition> = <def><control sequence><definition text>
# <def> = \def | \gdef | \edef | \xdef
# <definition text> = <register text><left brace><balanced text><right brace>
sub parseDefParameters {
my ($cs, $params) = @_;
my @tokens = $params->packParameters->unlist;
# Now, recognize parameters and delimiters.
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
DefPrimitive('\edef SkipSpaces Token UntilBrace DefExpanded', sub { do_def(0, @_); }, locked => 1);
DefPrimitive('\xdef SkipSpaces Token UntilBrace DefExpanded', sub { do_def(1, @_); }, locked => 1);
# <prefix> = \global | \long | \outer
# See Stomach.pm & Stomach.pm
DefPrimitiveI('\global', undef, sub { $STATE->setPrefix('global'); return; }, isPrefix => 1);
DefPrimitiveI('\long', undef, sub { $STATE->setPrefix('long'); return; }, isPrefix => 1);
DefPrimitiveI('\outer', undef, sub { $STATE->setPrefix('outer'); return; }, isPrefix => 1);
#======================================================================
# Non-Macro assignments; TeXBook Ch.24, pp 276--277
# <non-macro assignment> = <simple assignment> | \global <non-macro assignment>
# <filler> = <optional spaces> | <filler>\relax<optional spaces>
# <general text> = <filler>{<balanced text><right brace>
# <simple assignment> = <variable assignment> | <arithmetic>
# | <code assignment> | <let assignment> | <shorthand definition>
# | <fontdef token> | <family assignment> | <shape assignment>
# | \read <number> to <optional spaces><control sequence>
# | \setbox<8bit><equals><filler><box>
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
setter => sub { $STATE->assignDelcode(chr($_[2]->valueOf) => $_[0]->valueOf, $_[1]); });
# Remember, we're assigning a NUMBER (codepoint) to a CHARACTER!
foreach my $letter (ord('A') .. ord('Z')) {
$STATE->assignLCcode(chr($letter), $letter + 0x20, 'global');
$STATE->assignUCcode(chr($letter), $letter, 'global');
$STATE->assignLCcode(chr($letter + 0x20), $letter + 0x20, 'global');
$STATE->assignUCcode(chr($letter + 0x20), $letter, 'global'); }
# Stub definitions ???
DefMacro('\hyphenation GeneralText', Tokens());
DefMacro('\patterns{}', Tokens());
# <font> = <fontdef token> | \font | <family member>
# <family member> = <font range><4bit>
# <font range> = \textfont | \scriptfont | \scriptscriptfont
# Doubtful that we can do anything useful with these.
# These look essentially like Registers, although Knuth doesn't call them that.
# NOTE: These should just point to a CS token, right????
# (although it SHOULD be one defined to be a font switch??)
# NOTE: These should NOT be global(?)
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
# <interaction mode assignment> = \errorstopmode | \scrollmode | \nonstopmode | \batchmode
# These are no-ops; Basically, LaTeXML runs in scrollmode
DefPrimitiveI('\errorstopmode', undef, undef);
DefPrimitiveI('\scrollmode', undef, undef);
DefPrimitiveI('\nonstopmode', undef, undef);
DefPrimitiveI('\batchmode', undef, undef);
# <intimate assignment> = <special integer><equals><number>
# | <special dimension><equals><dimen>
DefMacro('\fontencoding{}', '\@@@fontencoding{#1}');
DefPrimitive('\@@@fontencoding{}', sub {
my ($stomach, $encoding) = @_;
$encoding = ToString(Expand($encoding));
if (LoadFontMap($encoding)) {
MergeFont(encoding => $encoding); }
else {
MergeFont(encoding => 'OT1'); } # Default to OT1 encoding if no map found
return; });
DefMacroI('\f@encoding', undef, sub { ExplodeText(LookupValue('font')->getEncoding); });
DefMacroI('\cf@encoding', undef, sub { ExplodeText(LookupValue('font')->getEncoding); });
# Used for SemiVerbatim text
DeclareFontMap('ASCII',
[undef, undef, undef, undef, undef, undef, undef, undef,
undef, undef, undef, undef, undef, undef, undef, undef,
undef, undef, undef, undef, undef, undef, undef, undef,
undef, undef, undef, undef, undef, undef, undef, undef,
" ", '!', "\"", '#', '$', '%', '&', "'",
'(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7',
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
AssignValue(INCLUDE_COMMENTS => 0);
my @tokens = ();
my ($t, $level) = (undef, 0);
while ($t = $mouth->readToken) {
my $cc = $t->getCatcode;
push(@tokens, $t) unless $cc == CC_MARKER; # End of line marker
$level++ if $cc == CC_BEGIN;
$level-- if $cc == CC_END;
last if !$level && $mouth->isEOL; }
$stomach->egroup;
DefMacroI($token, undef, Tokens(@tokens), nopackParameters => 1); }
return; });
DefConditional('\ifeof Number', sub {
my ($gullet, $port) = @_;
$port = ToString($port);
if (my $mouth = LookupValue('input_file:' . $port)) {
return $$mouth{at_eof}; }
else {
return 1; } });
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
my ($stomach, $whatsit) = @_;
$stomach->bgroup;
if (my $alignment = LookupValue('Alignment')) {
$whatsit->setProperty(alignment => $alignment);
$alignment->setBody($whatsit);
digestAlignmentBody($stomach, $whatsit); }
$stomach->egroup;
return; });
# Seems odd to need both end markers here...
DefMacroI('\@finish@alignment', undef,
'\hidden@crcr\@close@alignment');
DefPrimitive('\@close@alignment', sub { });
#======================================================================
# Low-level bits that appear within alignments or \halign
DefConstructorI('\cr', undef, "\n");
DefConstructorI('\crcr', undef, "\n");
# These are useful for reversion of higher-level macros that use alignment
# internally, but don't use explicit &,\cr in the user markup
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
# The issue is for \\ to look ahead for * and [],
# Eventually we'll expand into \cr (which should be preceded by the RHS of the template)
# BUT it should NOT trigger the template if it bumps into a &
# which happens when the 1st column of an alignment is empty.
# In proper LaTeX this is inhibited by a curious construct
# {\ifnum0='}
# and possibly by proper tracking of a Master Counter !?!?!?
# But we're not there (yet)
# This is the internal macro for \\[dim] used by LaTeX for various arrays, tabular, etc
DefMacroI('\@alignment@newline', undef, sub {
my ($gullet) = @_;
my ($star, $optional) = readNewlineArgs($gullet, 1);
return (T_CS('\hidden@cr'), T_BEGIN,
($optional
? (T_CS('\@alignment@newline@markertall'), T_BEGIN, $optional, T_END)
: T_CS('\@alignment@newline@marker')),
T_END); });
# However, the above will skip spaces --AND a newline! -- looking for [],
# which is kinda weird in math, since there may be a reasonable math [ in the 1st column!
# AMS kindly avoids that, by using a special version of \\
DefMacroI('\@alignment@newline@noskip', undef, sub {
my ($gullet) = @_;
my ($star, $optional) = readNewlineArgs($gullet);
return (T_CS('\hidden@cr'), T_BEGIN,
($optional
? (T_CS('\@alignment@newline@markertall'), T_BEGIN, $optional, T_END)
: T_CS('\@alignment@newline@marker')),
T_END); });
# These are the markers that produce \\ in the reversion,
# and (eventually will) add vertical space to the row!
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
reversion => Tokens(T_CS("\\\\"), T_CR));
# AND add the spacing to the alignment!!!
DefConstructor('\@alignment@newline@markertall {Dimension}', '',
afterDigest => sub {
if (my $alignment = LookupValue('Alignment')) {
$alignment->currentRow->{padding} = $_[1]->getArg(1); }
return; },
reversion => sub {
Tokens(T_CS("\\\\"), T_OTHER('['), Revert($_[1]), T_OTHER(']'), T_CR); });
DefMacroI('\tabularnewline', undef, '\cr'); # ???
# \lx@intercol is our replacement for LaTeX's \@acol which places intercolumn space in tabular
# (but NOT used by TeX's \halign!)
DefMacro('\lx@intercol', '');
# Candidates for binding \lx@intercol for LaTeX tabular or math arrays
# These provide "padding" of half tabcolsep, since added before & after columns
# [these could be \hskip\tabcolsep, but the expansion confounds trimColumnSpec]
DefConstructor('\lx@text@intercol', sub {
my ($document, %props) = @_;
$document->absorb(DimensionToSpaces($props{width})); },
reversion => '\lx@intercol',
properties => sub {
my $defn;
my $w = (($defn = $STATE->lookupDefinition(T_CS('\tabcolsep'))) && $defn->isRegister
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
# Like \noalign, takes an arg; handled within alignment processing.
# But doesn't create a pseudo-row (??? Or does it?; is it still needed?)
DefConstructor('\hidden@noalign{}', '#1',
reversion => '',
properties => sub {
# Sometimes, we're smuggling stuff that needs to be carried into the XML.
my $preserve = grep { $_->getProperty('alignmentPreserve'); } $_[1]->unlist;
(alignmentSkippable => 1, alignmentPreserve => $preserve); });
DefMacro('\hline', '\noalign{\@@alignment@hline}');
DefConstructorI('\@@alignment@hline', undef, '',
afterDigest => sub {
if (my $alignment = LookupValue('Alignment')) {
$alignment->addLine('t'); }
return; },
properties => { isHorizontalRule => 1 },
sizer => 0, alias => '\hline');
DefMacroI('\@tabular@begin@heading', undef, sub {
my $alignment = LookupValue('Alignment');
$$alignment{in_tabular_head} = 1;
return; });
DefMacroI('\@tabular@end@heading', undef, sub {
my $alignment = LookupValue('Alignment');
$$alignment{in_tabular_head} = 0;
return; });
#======================================================================
# Math mode in alignment
# Special forms for $ appearing within alignments.
# Note that $ within a math alignment (eg array environment),
# switches to text mode! There's no $$ for display math.
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
DefConstructorI('\@@BEGININLINETEXT', undef,
"<ltx:XMText>"
. "#body"
. "</ltx:XMText>",
alias => T_MATH, beforeDigest => sub { $_[0]->beginMode('text'); }, captureBody => 1);
DefConstructorI('\@@ENDINLINETEXT', undef, "", alias => T_MATH,
beforeDigest => sub { $_[0]->endMode('text'); });
DefPrimitiveI('\@LTX@nonumber', undef, sub { AssignValue(EQUATIONROW_NUMBER => 0, 'global'); });
DefMacroI('\hidewidth', undef, Tokens());
#======================================================================
# Multicolumn support
DefMacro('\multispan{Number}', sub {
my ($gullet, $span) = @_;
$span = $span->valueOf;
(T_CS('\omit'), map { (T_CS('\span'), T_CS('\omit')) } 1 .. $span - 1); });
DefRegisterI('\@alignment@ncolumns', undef, Dimension(0),
getter => sub {
if (my $alignment = LookupValue('Alignment')) {
Number(scalar($alignment->getTemplate->columns)); }
else { Number(0); } });
DefRegisterI('\@alignment@column', undef, Dimension(0),
getter => sub {
if (my $alignment = LookupValue('Alignment')) {
Number($alignment->currentColumnNumber); }
else { Number(0); } });
DefMacro('\@multicolumn {Number} AlignmentTemplate {}', sub {
my ($gullet, $span, $template, $tokens) = @_;
my $column = $template->column(1);
$span = $span->valueOf;
# First part, like \multispan
(T_CS('\omit'), (map { (T_CS('\span'), T_CS('\omit')) } 1 .. $span - 1),
# Next part, just put the template in-line, since it's only used once.
($column ? beforeCellUnlist($$column{before}) : ()),
$tokens->unlist,
($column ? afterCellUnlist($$column{after}) : ())); });
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
closeRow => sub { $_[0]->closeElement($rowtype); },
openColumn => sub { $_[0]->openElement($coltype, @_[1 .. $#_]); },
closeColumn => sub { $_[0]->closeElement($coltype); },
isMath => $ismath,
properties => {%properties});
AssignValue(Alignment => $alignment);
Debug("Halign $alignment: New " . $template->show) if $LaTeXML::DEBUG{halign};
Let(T_MATH, ($ismath ? '\@dollar@in@mathmode' : '\@dollar@in@textmode'));
return; }
DefMacroI('\@row@before', undef, undef);
DefMacroI('\@row@after', undef, undef);
DefMacroI('\@column@before', undef, undef);
DefMacroI('\@column@after', undef, undef);
sub pRevert {
my ($arg) = @_;
local $LaTeXML::DUAL_BRANCH = 'presentation';
return Revert($arg); }
sub cRevert {
my ($arg) = @_;
local $LaTeXML::DUAL_BRANCH = 'content';
return Revert($arg); }
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
shift(@poss) if scalar(@poss) % 2; # Get pairs!
while (@poss) {
my ($p2, $p1) = (pop(@poss), pop(@poss));
splice(@tokens, $p1, 2) if $p2 == $p1 + 1; }
return @tokens; }
# "Initialized" alignment; presets spacing, but since we're ignoring it anyway...
Let('\ialign', '\halign');
# Overlapping alignments ???
DefMacro('\oalign{}',
'\@@oalign{\@start@alignment#1\@finish@alignment}');
DefConstructor('\@@oalign{}',
'#1',
reversion => '\oalign{#1}', bounded => 1, mode => 'text',
beforeDigest => sub { alignmentBindings('l'); });
# This is actually different; the lines should lie ontop of each other.
# How should this be represented?
DefMacro('\ooalign{}',
'\@@ooalign{\@start@alignment#1\@finish@alignment}');
DefConstructor('\@@ooalign{}',
'#1',
reversion => '\ooalign{#1}', bounded => 1, mode => 'text',
beforeDigest => sub { alignmentBindings('l'); });
#----------------------------------------------------------------------
# These determine whether the _next_ paragraph gets indented!
# thus it needs \par to check whether such indentation has been set.
DefConstructorI('\indent', undef, sub {
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
# Vertical adjustments
if (my $vadj = LookupValue('vAdjust')) {
AssignValue(vAdjust => [], 'global');
Digest(Tokens(@$vadj)); }
else {
return; } } },
properties => { alignmentSkippable => 1 },
alias => '\par');
Let('\par', '\normal@par');
DefMacro('\inner@par OptionalMatch:* [Glue]', '\normal@par'); # Obsolete, but in case still used...
Tag('ltx:para', autoClose => 1, autoOpen => 1, afterClose => \&pruneEmpty);
sub pruneEmpty {
my ($document, $node) = @_;
# In some cases we could have e.g. a \noindent followed by a {table},
# in which case we end up with an empty ltx:para which we can prune.
if (!scalar(element_nodes($node))) {
my $prev = element_prev($node);
if (!$prev || ($document->getNodeQName($prev) ne 'ltx:para')) { # If $node WAS the 1st child
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
AssignValue($box, undef);
(defined $stuff ? $stuff->unlist : List()); });
DefPrimitive('\unhcopy Number', sub {
my $box = 'box' . $_[1]->valueOf;
my $stuff = LookupValue($box);
adjustBoxColor($stuff);
(defined $stuff ? $stuff->unlist : List()); });
# Implement ???
# DefMacro('\vrule','\relax');
DefMacro('\valign', '');
DefMacro('\vspace{}', '\vskip#1\relax');
# \indent, \noindent, \par; see above.
DefMacro('\discretionary{}{}{}', '#3'); # No hyphenation here!
DefPrimitiveI('\-', undef, undef);
DefPrimitive('\setlanguage Number', undef);
#======================================================================
# Math mode stuff
# See TeXBook Ch.26
#======================================================================
# Decide whether we're going into or out of math, inline or display.
Tag('ltx:XMText', autoOpen => 1, autoClose => 1);
# This really should be T_MATH
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
#**********************************************************************
Let('\vcenter', '\vbox');
# \eqno & \leqno are really bizzare.
# They should seemingly digest until $ (or while still in math mode),
# and use that stuff as the reference number.
# However, since people abuse this, and we're really not quite TeX,
# we really can't do it Right.
# Even a \begin{array} ends up expanding into a $ !!!
DefMacroI('\eqno', undef, sub {
my ($gullet) = @_;
my $locator = $gullet->getLocator;
my @stuff = ();
# This is risky!!!
while (my $t = $gullet->readXToken(0)) {
if ($t->defined_as(T_BEGIN)) {
push(@stuff, $t, $gullet->readBalanced, T_END); }
# What do I need to explicitly list here!?!?!? UGGH!
elsif ($t->defined_as(T_MATH)
|| $t->defined_as(T_CS('\]'))
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
. "</ltx:XMApp>",
reversion => sub { (T_BEGIN, T_END, T_SUPER, revertScript($_[1])); },
sizer => sub { scriptSizer($_[0]->getArg(1), undef, undef, 'SUPERSCRIPT', 'post'); });
DefConstructor('\@@FLOATINGSUBSCRIPT InScriptStyle',
"<ltx:XMApp role='FLOATSUBSCRIPT' scriptpos='?#scriptpos(#scriptpos)(#scriptlevel)'>"
. "<ltx:XMArg rule='Subscript'>#1</ltx:XMArg>"
. "</ltx:XMApp>",
reversion => sub { (T_BEGIN, T_END, T_SUB, revertScript($_[1])); },
sizer => sub { scriptSizer($_[0]->getArg(1), undef, undef, 'SUBSCRIPT', 'post'); });
DefMacroI('\active@math@prime', undef, sub {
my ($gullet) = @_;
my @sup = (T_CS('\prime'));
# Collect up all ', convering to \prime
while ($gullet->ifNext(T_OTHER('\''))) {
$gullet->readToken;
push(@sup, T_CS('\prime')); }
# Combine with any following superscript!
# However, this is semantically screwed up!
# We really need to set up separate superscripts, but at same level!
if ($gullet->ifNext(T_SUPER)) {
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
xmkey2 => LaTeXML::Package::getXMArgID()); }
return $closing; }, # and leave the closing bit, whatever it is.
properties => sub { %{ $_[2]->getKeyVals }; },
sizer => sub { fracSizer($_[0]->getProperty('top'), $_[0]->getProperty('bottom')); },
reversion => sub {
my ($whatsit) = @_;
(Revert($whatsit->getProperty('top')),
$whatsit->getArg(1)->unlist,
Revert($whatsit->getProperty('bottom'))); });
DefMacro('\choose',
'\lx@generalized@over{\choose}{meaning=binomial,thickness=0pt,left=\@left(,right=\@right)}');
DefMacro('\brace',
'\lx@generalized@over{\brace}{thickness=0pt,left=\@left\{,right=\@right\}}');
DefMacro('\brack',
'\lx@generalized@over{\brack}{thickness=0pt,left=\@left[,right=\@right]}');
DefMacro('\atop',
'\lx@generalized@over{\atop}{thickness=0pt}');
DefMacro('\atopwithdelims Token Token',
'\lx@generalized@over{\atopwithdelims #1 #2}{thickness=0pt,left={\@left#1},right={\@right#2}}');
DefMacro('\over',
'\lx@generalized@over{\over}{meaning=divide}');
DefMacro('\overwithdelims Token Token',
'\lx@generalized@over{\overwithdelims #1 #2}{left={\@left#1},right={\@right#2},meaning=divide}');
# My thinking was that this is a "fraction" providing the dimension is > 0!
DefMacro('\above Dimension',
'\lx@generalized@over{\above #1}{meaning=divide,thickness=#1}');
DefMacro('\abovewithdelims Token Token Dimension',
'\lx@generalized@over{\abovewithdelims #1 #2 #3}{left={\@left#1},right={\@right#2},meaning=divide,thickness=#3}');
#======================================================================
DefPrimitiveI('\cal', undef, undef,
font => { family => 'caligraphic', series => 'medium', shape => 'upright' });
# In principle, <ltx:emph> is a nice markup for emphasized.
# Unfortunately, TeX really just treats it as a font switch.
# Something like: \em et.al. \rm more stuff
# works in TeX, but in our case, since there is no explicit {},
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
DefConstructorI('&', undef, sub { Error('unexpected', '&', $_[0], "Stray alignment \"&\""); });
#**********************************************************************
# Plain; Extracted from Appendix B.
#**********************************************************************
#======================================================================
# TeX Book, Appendix B, p. 344
#======================================================================
RawTeX('\outer\def^^L{\par}');
DefMacro('\dospecials', '\do\ \do\\\do\{\do\}\do\$\do\&\do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~');
# Normally, the content branch contains the pure structure and meaning of a construct,
# and the presentation is generated from lower level TeX macros that only concern
# themselves with how to display the object.
# Nevertheless, it is sometimes useful to know where the tokens in the presentation branch
# came from; particularly what their presumed "meaning" is.
# For example, when search-indexing pmml, or providing links to definitions from the pmml.
#
# The following constructor (see how it's used in DefMath), adds meaning attributes
# whereever it seems sensible on the presentation branch, after it has been generated.
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
DefPrimitive('\newtoks DefToken', sub { DefRegisterI($_[1], undef, Tokens()); });
# the next 4 actually work by doing a \chardef instead of \countdef, etc.
# which means they actually work quite differently
DefPrimitive('\alloc@@ {}', sub {
my ($stomach, $type) = @_;
my $c = 'allocation @' . ToString($type);
my $n = LookupValue($c) || '0';
$n = $n->valueOf if ref $n;
AssignValue($c => $n + 1, 'global');
AssignRegister('\allocationnumber' => Number($n), 'global'); });
DefMacro('\newread DefToken', '\alloc@@{read}\global\chardef#1=\allocationnumber');
DefMacro('\newwrite DefToken', '\alloc@@{write}\global\chardef#1=\allocationnumber');
DefMacro('\newfam DefToken', '\alloc@@{fam}\global\chardef#1=\allocationnumber');
DefMacro('\newlanguage DefToken', '\alloc@@{language}\global\chardef#1=\allocationnumber');
DefMacro('\e@alloc{}{}{}{}{}{}',
'\global\advance#3\@ne
% \e@ch@ck{#3}{#4}{#5}#1%
\allocationnumber#3\relax
\global#2#6\allocationnumber
% \wlog{\string#6=\string#1\the\allocationnumber}
');
DefMacro('\alloc@{}{}{}{}', '\e@alloc#2#3{\count1#1}#4\float@count');
DefMacro('\newread', '\e@alloc\read \chardef{\count16}\m@ne\sixt@@n');
DefMacro('\newwrite', '\e@alloc\write
{\ifnum\allocationnumber=18
\advance\count17\@ne
\allocationnumber\count17 %
\fi
\global\chardef}%
{\count17}%
\m@ne
{128}');
# This implementation is quite wrong
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
DefRegister('\medskipamount' => Glue('6pt plus 2pt minus 2pt'));
DefRegister('\bigskipamount' => Glue('12pt plus 4pt minus 4pt'));
DefRegister('\normalbaselineskip' => Glue('12pt'));
DefRegister('\normallineskip' => Glue('1pt'));
DefRegister('\normallineskiplimit' => Dimension('0pt'));
DefRegister('\jot' => Dimension('3pt'));
DefRegister('\lx@default@jot' => LookupRegister('\jot'));
DefRegister('\interdisplaylinepenalty' => Number(100));
DefRegister('\interfootnotelinepenalty' => Number(100));
DefMacroI('\magstephalf', undef, '1095');
our @mags = (1000, 1200, 1440, 1728, 2074, 2488);
DefMacro('\magstep{}', sub {
my $level = ToString($_[1]);
$level = ($level =~ /^\d$/) ? int($level) : 0;
$level = 0 unless $level >= 0 and $level < 6;
Explode($mags[$level]); });
#======================================================================
# TeX Book, Appendix B, p. 350
# Font stuff ...
RawTeX(<<'EoTeX');
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
DefPrimitiveI('\large', undef, undef, font => { size => 12 });
DefPrimitiveI('\Large', undef, undef, font => { size => 14.4 });
DefPrimitiveI('\LARGE', undef, undef, font => { size => 17.28 });
DefPrimitiveI('\huge', undef, undef, font => { size => 20.74 });
DefPrimitiveI('\Huge', undef, undef, font => { size => 29.8 });
DefPrimitiveI('\mit', undef, undef, requireMath => 1, font => { family => 'italic' });
DefPrimitiveI('\frenchspacing', undef, undef);
DefPrimitiveI('\nonfrenchspacing', undef, undef);
DefMacroI('\normalbaselines', undef,
'\lineskip=\normallineskip\baselineskip=\normalbaselineskip\lineskiplimit=\normallineskiplimit');
DefMacroI('\space', undef, Tokens(T_SPACE));
DefMacroI('\lq', undef, "`");
DefMacroI('\rq', undef, "'");
Let('\empty', '\@empty');
DefMacroI('\null', undef, '\hbox{}');
Let('\bgroup', T_BEGIN);
Let('\egroup', T_END);
Let('\endgraf', '\par');
Let('\endline', '\cr');
DefPrimitiveI('\endline', undef, undef);
# Use \r for the newline from TeX!!!
DefMacroI("\\\r", undef, '\ '); # \<cr> == \<space> Interesting (see latex.ltx)
Let(T_ACTIVE("\r"), '\par'); # (or is this just LaTeX?)
Let("\\\t", "\\\r"); # \<tab> == \<space>, also
#======================================================================
# TeX Book, Appendix B, p. 352
DefPrimitiveI('\obeyspaces', undef, sub {
AssignCatcode(" " => 13);
Let(T_ACTIVE(" "), '\space');
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
my $s = DimensionToSpaces($length);
return unless defined $s;
Box($s, undef, undef, Invocation(T_CS('\hglue'), $length),
name => 'hglue', width => $length, isSpace => 1); });
DefPrimitive('\vglue Glue', undef);
DefPrimitiveI('\topglue', undef, undef);
DefPrimitiveI('\nointerlineskip', undef, undef);
DefPrimitiveI('\offinterlineskip', undef, undef);
DefMacroI('\smallskip', undef, '\vskip\smallskipamount');
DefMacroI('\medskip', undef, '\vskip\medskipamount');
DefMacroI('\bigskip', undef, '\vskip\bigskipamount');
#======================================================================
# TeX Book, Appendix B, p. 353
DefPrimitiveI('\break', undef, undef);
DefPrimitiveI('\nobreak', undef, undef);
DefPrimitiveI('\allowbreak', undef, undef);
DefPrimitiveI('\nobreakspace', undef, sub {
Box(UTF(0xA0), undef, undef, T_ACTIVE("~"),
width => Dimension('0.333em'), isSpace => 1); });
DefMacro("~", '\nobreakspace{}');
DefMacroI('\slash', undef, '/');
DefPrimitiveI('\filbreak', undef, undef);
DefMacroI('\goodbreak', undef, '\par');
DefMacroI('\eject', undef, '\par\LTX@newpage');
Let('\newpage', '\eject');
DefConstructorI('\LTX@newpage', undef, "^<ltx:pagination role='newpage'/>");
DefMacroI('\supereject', undef, '\par\LTX@newpage');
DefPrimitiveI('\removelastskip', undef, undef);
DefMacroI('\smallbreak', undef, '\par');
DefMacroI('\medbreak', undef, '\par');
DefMacroI('\bigbreak', undef, '\par');
DefMacroI('\line', undef, '\hbox to \hsize');
DefMacro('\leftline Undigested', '\ltx@leftline{\hbox{#1}}');
DefMacro('\rightline Undigested', '\ltx@rightline{\hbox{#1}}');
DefMacro('\centerline Undigested', '\ltx@centerline{\hbox{#1}}');
DefConstructor('\ltx@leftline{}', sub {
alignLine($_[0], $_[1], 'left'); },
alias => '\leftline',
bounded => 1);
DefConstructor('\ltx@rightline{}', sub {
alignLine($_[0], $_[1], 'right'); },
alias => '\rightline',
bounded => 1);
DefConstructor('\ltx@centerline{}', sub {
alignLine($_[0], $_[1], 'center'); },
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
if ($document->isOpenable('ltx:p')) {
$document->insertElement('ltx:p', $line, class => 'ltx_align_' . $alignment); }
elsif ($document->isOpenable('ltx:text')) {
$document->insertElement('ltx:text', $line, class => 'ltx_align_' . $alignment);
$document->insertElement('ltx:break'); }
else {
$document->absorb($line); }
return; }
# These should be 0 width, but perhaps also shifted?
DefMacro('\llap{}', '\hbox to 0pt{\hss#1}');
DefMacro('\rlap{}', '\hbox to 0pt{#1\hss}');
DefMacroI('\m@th', undef, '\mathsurround=0pt ');
# \strutbox
DefMacroI('\strut', undef, Tokens());
RawTeX('\newbox\strutbox');
#======================================================================
# TeX Book, Appendix B. p. 354
# TODO: Not yet done!!
# tabbing stuff!!!
DefMacroI('\settabs', undef, undef);
#======================================================================
# TeX Book, Appendix B. p. 355
# TODO: \item, \itemitem not done!
# This could probably be adopted from LaTeX, if the <itemize> could auto-open
# and close!
DefMacro('\hang', '\hangindent\parindent');
DefMacro('\item', '\par\hang\textindent');
DefMacro('\itemitem', '\par\indent \hangindent2\parindent \textindent');
DefMacro('\textindent{}', '\indent\llap{#1\enspace}\ignorespaces');
DefMacro('\narrower', '\advance\leftskip by\parindent'
. '\advance\rightskip by\parindent');
#----------------------------------------------------------------------
# General support for Front Matter.
# Not (yet) used by TeX (finish plain?)
# But provides support for LaTeX (and other formats?) for handling frontmatter.
#
# The idea is to accumulate any frontmatter material (title, author,...)
# rather than directly drop it into the digested stream.
# When we begin constructing the document, all accumulated material is output.
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
# Maintain a list of classes that apply to the document root.
# This might involve global style options, like leqno.
Tag('ltx:document', 'afterOpen:late' => sub {
my ($document, $root) = @_;
if (my $classes = join(' ', LookupMappingKeys('DOCUMENT_CLASSES'))) {
$document->addClass($root, $classes); } });
# If folks start using plain TeX macros, and never load LaTeX.pool,
# they might benefit from a ltx-plain.css?
DefMacro('\beginsection Until:\par', '\@beginsection{{\bf #1}}');
DefConstructor('\@beginsection {}',
"<ltx:section><ltx:title>#1</ltx:title>");
# POSSIBLY #1 is a name or reference number and #2 is the theoremm TITLE
# If so, how do know when the theorem ends?
DefMacroI('\proclaim', parseDefParameters('\proclaim', Tokenize('#1. #2\par')),
'\@proclaim{{\bf #1}}{{\sl #2}}');
DefConstructor('\@proclaim{}{}',
"<ltx:theorem>"
. "<ltx:title font='#titlefont' _force_font='true' >#title</ltx:title>"
. "#2",
afterConstruct => sub { $_[0]->maybeCloseElement('ltx:theorem'); },
properties => sub {
my $title = $_[1];
(title => $title, titlefont => $title->getFont); });
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
# of the various forms, some types (eg. theorems) share the same counter.
# LaTeX defines this handling on an adhoc basis; defines \fnum@table, \fnum@figure for some types
# but \labelenumi, etc for others.
# This section synthesizes a more uniform support for reference numbers,
# references to reference numbers, title formatting etc.
# It allows you to customize each of the forms for each type encountered.
# The design reflects LaTeX needs, more than TeX, but support starts here!
# This collects up the various declared ltx:tag's into an ltx:tags
DefMacro('\lx@make@tags {}', sub {
my ($gullet, $type) = @_;
my @tags = ();
my $formatters = LookupValue('type_tag_formatter');
foreach my $role (sort keys %{$formatters}) {
my $formatter = $$formatters{$role};
push(@tags, Invocation(T_CS('\lx@tag@intags'), T_OTHER($role),
Invocation($formatter, $type))); }
return (T_CS('\lx@tags'), T_BEGIN, @tags, T_END); });
# Remove the last closed node, if it's empty.
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
afterConstruct => \&removeEmptyElement);
DefConstructor('\lx@tags{}',
"<ltx:tags>#1</ltx:tags>",
afterConstruct => \&removeEmptyElement);
#----------------------------------------------------------------------
# "refnum" is the lowest level reference number for an object is typically \the<counter>
# but be sure to use the right counter! This is how \ref will show the number.
# You'll typically customize this by defining \the<counter> (and \p@<counter) as in LaTeX.
DefMacro('\lx@counterfor{}', sub {
my ($gullet, $type) = @_;
my $ctr = LookupMapping('counter_for_type', ToString($type));
return ($ctr ? T_OTHER($ctr) : $type); });
DefMacro('\lx@the@@{}', '\expandafter\lx@@the@@\expandafter{\lx@counterfor{#1}}');
DefMacro('\lx@@the@@{}', '\csname the#1\endcsname');
DefMacro('\lx@therefnum@@{}', '\expandafter\lx@@therefnum@@\expandafter{\lx@counterfor{#1}}');
DefMacro('\lx@@therefnum@@{}',
'{\normalfont\csname p@#1\endcsname\csname the#1\endcsname}');
AssignMapping('type_tag_formatter', 'refnum' => '\lx@therefnum@@');
#----------------------------------------------------------------------
# \lx@fnum@@{type} Gets the formatted form of the refnum, as part of the object, (no @role).
# Customize by defining \fnum@<type> or \<type>name and \fnum@font@<type>
# Default uses \fnum@font@<type> \<type>name prefix + space (if any) and \the<counter>.
# When using the "name", uses \<type>name in preference to fallback \lx@name@<type>
DefMacro('\lx@refnum@compose{}{}', '\expandafter\lx@refnum@compose@\expandafter{#2}{#1}');
DefMacro('\lx@refnum@compose@{}{}', '\if.#1.#2\else#2\space#1\fi');
####DefMacro('\lx@refnum@compose@{}{}', '\if.#1.#2\else#2~#1\fi');
DefMacro('\lx@fnum@@{}',
'{\normalfont\@ifundefined{fnum@font@#1}{}{\csname fnum@font@#1\endcsname}'
. '\@ifundefined{fnum@#1}{\lx@@fnum@@{#1}}{\csname fnum@#1\endcsname}}');
# Really seems like <type>name should take precedence over \lx@name@<type>,
# since users might define it.
# BUT amsthm defines \thmname{}!
DefMacro('\lx@@fnum@@ {}',
'\@ifundefined{lx@name@#1}{'
. '\@ifundefined{#1name}{'
. '\lx@the@@{#1}'
. '}{'
. '\lx@refnum@compose{\csname #1name\endcsname}{\lx@the@@{#1}}'
. '}}{'
. '\lx@refnum@compose{\csname lx@name@#1\endcsname}{\lx@the@@{#1}}'
. '}');
AssignMapping('type_tag_formatter', '' => '\lx@fnum@@'); # Default!
#----------------------------------------------------------------------
# \lx@fnum@toc@{type} is similar, but formats the number for use within \toctitle
# Customize by defining \fnum@toc@<type> or \fnum@tocfont@<type>
# Default uses just \the<counter>, else composes using \lx@@fnum@@{type}
DefMacro('\lx@fnum@toc@@{}',
'{\normalfont\@ifundefined{fnum@tocfont@#1}{}{\csname fnum@tocfont@#1\endcsname}'
. '\@ifundefined{fnum@toc@#1}{\lx@the@@{#1}}{\csname fnum@toc@#1\endcsname}}');
#----------------------------------------------------------------------
# "typerefnum" form is used by automatic cross-references, typically "type number" or similar.
# Customize by defining \typerefnum@<type> or \typerefnum@font@<type>
# Default uses either \<type>typerefname or \<type>name (if any, followed by space, then \the<counter>
DefMacro('\lx@typerefnum@@{}',
'{\normalfont\@ifundefined{typerefnum@font@#1}{}{\csname typerefnum@font@#1\endcsname}'
. '\@ifundefined{typerefnum@#1}{\lx@@typerefnum@@{#1}}{\csname typerefnum@#1\endcsname}}');
DefMacro('\lx@@typerefnum@@{}',
'\@ifundefined{#1typerefname}{'
. '\@ifundefined{lx@name@#1}{'
. '\@ifundefined{#1name}{'
. '}{'
. '\lx@refnum@compose{\csname #1name\endcsname}{\csname p@#1\endcsname\lx@the@@{#1}}'
. '}}{'
. '\lx@refnum@compose{\csname lx@name@#1\endcsname}{\csname p@#1\endcsname\lx@the@@{#1}}'
. '}}{'
. '\lx@refnum@compose{\csname #1typerefname\endcsname}{\csname p@#1\endcsname\lx@the@@{#1}}'
. '}');
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
#----------------------------------------------------------------------
# The following macros provide similar customization for titles & toctitles
# in particular for supporting localization for different languages.
# Redefine these if you want to assemble the name (eg. \chaptername), refnum and titles differently
#----------------------------------------------------------------------
# \lx@format@title@@{type}{title}
# Format a title (or caption) appropriately for type.
# Customize by defining \format@title@type{title}
# Default composes \lx@fnum@@{type} space title.
DefMacro('\lx@format@title@@{}{}',
'\lx@@format@title@@{#1}'
. '{{\lx@format@title@font@@{#1}#2}}');
DefMacro('\lx@@format@title@@{}{}',
'{\@ifundefined{format@title@#1}'
. '{\lx@@compose@title{\lx@fnum@@{#1}}{#2}}'
. '{\csname format@title@#1\endcsname{#2}}}');
# \lx@format@toctitle@@{type}{toctitle}
# Similar for toctitle, typically briefer
# Customize by defining \format@toctitle@type{title}
# Default composes \lx@fnum@toc@@{type} space title.
DefMacro('\lx@format@toctitle@@{}{}',
'\lx@@format@toctitle@@{#1}'
. '{{\lx@format@toctitle@font@@{#1}#2}}');
DefMacro('\lx@@format@toctitle@@{}{}',
'{\@ifundefined{format@toctitle@#1}'
. '{\lx@@compose@title{\lx@fnum@toc@@{#1}}{#2}}'
. '{\csname format@toctitle@#1\endcsname{#2}}}');
DefMacro('\lx@@compose@title{}{}', '\lx@tag[][ ]{#1}#2');
DefMacro('\lx@format@title@font@@{}',
'\@ifundefined{format@title@font@#1}{}{\csname format@title@font@#1\endcsname}');
DefMacro('\lx@format@toctitle@font@@{}',
'\@ifundefined{format@toctitle@font@#1}{}{\csname format@toctitle@font@#1\endcsname}');
## NOTE that a 3rd form seems desirable: an concise form that cannot rely on context for the type.
## This would be useful for the titles in links; thus can be plain (unicode) text.
#======================================================================
# TeX Book, Appendix B. p. 356
DefPrimitiveI('\raggedright', undef, undef);
DefPrimitiveI('\raggedleft', undef, undef); # this is actually LaTeX
DefPrimitiveI('\ttraggedright', undef, undef);
DefPrimitiveI('\leavevmode', undef, undef);
DefMacro('\mathhexbox{}{}{}', '\leavevmode\hbox{$\m@th \mathchar"#1#2#3$}');
#----------------------------------------------------------------------
# Actually from LaTeX; Table 3.2. Non-English Symbols, p.39
# The following shouldn't appear in math.
DefPrimitiveI('\OE', undef, "\x{0152}"); # LATIN CAPITAL LIGATURE OE
DefPrimitiveI('\oe', undef, "\x{0153}"); # LATIN SMALL LIGATURE OE
DefPrimitiveI('\AE', undef, UTF(0xC6)); # LATIN CAPITAL LETTER AE
DefPrimitiveI('\ae', undef, UTF(0xE6)); # LATIN SMALL LETTER AE
DefPrimitiveI('\AA', undef, UTF(0xC5)); # LATIN CAPITAL LETTER A WITH RING ABOVE
DefPrimitiveI('\aa', undef, UTF(0xE5)); # LATIN SMALL LETTER A WITH RING ABOVE
DefPrimitiveI('\O', undef, UTF(0xD8)); # LATIN CAPITAL LETTER O WITH STROKE
DefPrimitiveI('\o', undef, UTF(0xF8)); # LATIN SMALL LETTER O WITH STROKE
DefPrimitiveI('\L', undef, "\x{0141}"); # LATIN CAPITAL LETTER L WITH STROKE
DefPrimitiveI('\l', undef, "\x{0142}"); # LATIN SMALL LETTER L WITH STROKE
DefPrimitiveI('\ss', undef, UTF(0xDF)); # LATIN SMALL LETTER SHARP S
# apparently the rest can appear in math.
DefPrimitiveI('\lx@sectionsign', undef, UTF(0xa7), alias => '\S'); # SECTION SIGN
DefPrimitiveI('\lx@paragraphsign', undef, UTF(0xB6), alias => '\P'); # PILCROW SIGN
DefMacroI('\S', undef, '\lx@sectionsign');
DefMacroI('\P', undef, '\lx@paragraphsign');
DefPrimitiveI('\dag', undef, "\x{2020}"); # DAGGER
DefPrimitiveI('\ddag', undef, "\x{2021}"); # DOUBLE DAGGER
DefPrimitiveI('\copyright', undef, UTF(0xA9)); # COPYRIGHT SIGN
DefPrimitiveI('\pounds', undef, UTF(0xA3)); # POUND SIGN
#----------------------------------------------------------------------
# Accents. LaTeX Table 3.1, p.38
#----------------------------------------------------------------------
# All of TeX's accents can (sorta) be handled by Unicode's combining accents
# (which follow the character to be accented).
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
$font, $locator, $reversion); }
# Defines an accent command using a combining char that follows the
# 1st char of the argument. In cases where there is no argument, $standalonechar is used.
sub DefAccent {
my ($accent, $combiningchar, $standalonechar, %options) = @_;
$options{above} = 1 if !(defined $options{above}) && !$options{below};
# Used for converting a char used as an above-accent to a combining char (See \accent)
AssignMapping('accent_combiner_above', $standalonechar => $combiningchar) if $options{above};
AssignMapping('accent_combiner_below', $standalonechar => $combiningchar) unless $options{above};
DefMacroI($accent, "{}",
Tokens(T_CS('\lx@applyaccent'), T_OTHER($accent),
T_OTHER($combiningchar), T_OTHER($standalonechar),
T_BEGIN, T_ARG(1), T_END),
protected => 1);
return; }
DefPrimitiveI('\lx@applyaccent', "DefToken Token Token {}", sub {
my ($stomach, $accent, $combiningchar, $standalonechar, $letter) = @_;
applyAccent($stomach, $letter, $combiningchar->getString, $standalonechar->getString,
Tokens(T_CS($accent->getString), T_BEGIN, $letter, T_END)); },
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
# NOTE: REVERSE LOOKUP in above accent list for the non-spacing accent char
# BUT, \accent always (?) makes an above type accent... doesn't it?
if (my $combiner = LookupMapping('accent_combiner_above', $acc)
|| LookupMapping('accent_combiner_below', $acc)) {
applyAccent($stomach, $letter, $combiner, $acc, $reversion); }
else {
Warn('unexpected', "accent$n", $stomach, "Accent '$n' not recognized");
Box(ToString($letter), undef, undef, $reversion); } });
# Note that these two apparently work in Math? BUT the argument is treated as text!!!
DefMacro('\d{}', '\ifmmode\@math@daccent{#1}\else\@text@daccent{#1}\fi');
DefMacro('\b{}', '\ifmmode\@math@baccent{#1}\else\@text@baccent{#1}\fi');
DefConstructor('\@math@daccent {}',
"<ltx:XMApp><ltx:XMTok role='UNDERACCENT'>\x{22c5}</ltx:XMTok>"
. "?#textarg(<ltx:XMText>#textarg</ltx:XMText>)(<ltx:XMArg>#matharg</ltx:XMArg>)"
. "</ltx:XMApp>",
mode => 'text', alias => '\d',
afterDigest => sub {
my ($stomach, $whatsit) = @_;
my $arg = $whatsit->getArg(1);
if ($arg->isMath) {
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
Let('\sp', T_SUPER);
Let('\sb', T_SUB);
DefPrimitiveI('\lx@thinmuskip', undef, sub {
Box("\x{2009}", undef, undef, T_CS('\,'),
name => 'thinspace', isSpace => 1,
width => LookupRegister('\thinmuskip')); });
DefPrimitiveI('\lx@thinspace', undef, sub {
Box("\x{2009}", undef, undef, T_CS('\,'),
name => 'thinspace', width => Dimension('0.16667em'), isSpace => 1); });
DefMacroI('\,', undef, '\ifmmode\lx@thinmuskip\else\lx@thinspace\fi', protected => 1);
DefPrimitiveI('\!', undef, sub {
Box("\x{200B}", undef, undef, T_CS('\!'), # zero width space
name => 'negthinspace', isSpace => 1,
width => LookupRegister('\thinmuskip')->negate); });
DefPrimitiveI('\>', undef, sub {
Box("\x{2005}", undef, undef, T_CS('\>'),
name => 'medspace', isSpace => 1,
width => LookupRegister('\medmuskip')); });
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
# These are really wrong; I can't find the right Unicode Glyphs.
# These are only fragments intended to be assembled into meaningful(?) symbols.
DefMathI('\mapstochar', undef, "\x{2E20}"); # TeX 3237
DefMathI('\lhook', undef, "\x{2E26}"); # TeX 312C
DefMathI('\rhook', undef, "\x{2E27}"); # TeX 312D
#======================================================================
# TeX Book, Appendix B. p. 359
# Ah, since \ldots can appear in text and math....
DefMacroI('\ldots', undef, '\lx@ldots');
DefConstructorI('\lx@ldots', undef,
"?#isMath(<ltx:XMTok name='ldots' font='#font' role='ID'>\x{2026}</ltx:XMTok>)(\x{2026})",
sizer => "\x{2026}",
reversion => '\ldots',
properties => sub {
(LookupValue('IN_MATH')
? (font => LookupValue('font')->merge(family => 'serif',
series => 'medium', shape => 'upright')->specialize("\x{2026}"))
: ()); }); # Since not DefMath!
# And so can \vdots
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
DefMath('\math@underline{}', UTF(0xAF), operator_role => 'UNDERACCENT',
name => 'underline', alias => '\underline');
DefConstructor('\text@underline{}', "<ltx:text framed='underline' _noautoclose='1'>#1</ltx:text>");
DefMath('\math@overrightarrow{}', "\x{2192}", operator_role => 'OVERACCENT',
name => 'overrightarrow', alias => '\overrightarrow');
DefMath('\math@overleftarrow{}', "\x{2190}", operator_role => 'OVERACCENT',
name => 'overleftarrow', alias => '\overleftarrow');
# Careful: Use \protect so that it doesn't expand too early in alignments, etc.
DefMacro('\underline{}', '\protect\ifmmode\math@underline{#1}\else\text@underline{#1}\fi');
Let('\underbar', '\underline'); # Will anyone notice?
DefMacro('\overrightarrow{}', '\protect\ifmmode\math@overrightarrow{#1}\else$\math@overrightarrow{#1}$\fi');
DefMacro('\overleftarrow{}', '\protect\ifmmode\math@overleftarrow{#1}\else$\math@overleftarrow{#1}$\fi');
DefMacro('\skew{}{}{}', '{#2{#3\mkern#1mu}\mkern-#1mu}{}'); # ignore the subtle spacing for now?
#----------------------------------------------------------------------
# LaTeX; Table 3.10. Delimiters, p.47
#----------------------------------------------------------------------
# The meaning of OPEN/CLOSE tends to depend upon the pairing,
# rather than the individual tokens.
# This meaning is handled in MathParser (for now)
DefMacroI('\{', undef, '\ifmmode\lx@math@lbrace\else\lx@text@lbrace\fi', protected => 1);
DefMacroI('\}', undef, '\ifmmode\lx@math@rbrace\else\lx@text@rbrace\fi', protected => 1);
DefMathI('\lx@math@lbrace', undef, '{', role => 'OPEN', stretchy => 'false', alias => '\{');
DefMathI('\lx@math@rbrace', undef, '}', role => 'CLOSE', stretchy => 'false', alias => '\}');
DefPrimitiveI('\lx@text@lbrace', undef, '{', alias => '\{',
# font => { specialize => "{" });
font => { shape => 'upright' }, bounded => 1); # Since not DefMath!
DefPrimitiveI('\lx@text@rbrace', undef, '}', alias => '\}',
# font => { specialize => "}" }); # Since not DefMath!
font => { shape => 'upright' }, bounded => 1); # Since not DefMath!
Let('\lbrace', '\{');
Let('\lbrack', T_OTHER('['));
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
return $DELIMITER_MAP{$delim}; }
# This is a little messier than you'd think.
# These effectively create a group between the \left,\right.
# And this also gives us a single list of things to parse separately.
# Since \left,\right are TeX, primitives and must be paired up,
# we use a bit of macro trickery to simulate.
# [The \@hidden@bgroup/egroup keep from putting a {} into the UnTeX]
# HOWEVER, an additional complication is that it is a common mistake to omit the balancing \right!
# Using an \egroup (or hidden) makes it hard to recover, so use a special egroup
DefMacro('\left XToken', '\@left #1\@hidden@bgroup');
# Like \@hidden@egroup, but softer about missing \left
DefConstructor('\right@hidden@egroup', '',
afterDigest => sub {
my ($stomach) = @_;
if ($STATE->isValueBound('MODE', 0) # Last stack frame was a mode switch!?!?!
|| $STATE->lookupValue('groupNonBoxing')) { # or group was opened with \begingroup
Error('unexpected', '\right', undef, "Unbalanced \\right, no balancing \\left."); }
else {
$stomach->egroup; } },
reversion => '');
DefMacro('\right XToken', '\right@hidden@egroup\@right #1');
DefConstructor('\@left Token',
"?#char(<ltx:XMTok role='#role' name='#name' stretchy='#stretchy'>#char</ltx:XMTok>)"
. "(?#hint(<ltx:XMHint/>)(#1))",
afterDigest => sub { my ($stomach, $whatsit) = @_;
my $arg = $whatsit->getArg(1);
my $delim = ToString($arg);
if ($delim eq '.') {
$whatsit->setProperty(hint => 1); }
elsif (my $entry = $DELIMITER_MAP{$delim}) {
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
DefConstructor('\mathchoice Digested Digested Digested Digested', sub {
my ($document, $d, $t, $s, $ss, %props) = @_;
my $style = $props{mathstyle};
my $choice = ($style eq 'display' ? $d
: ($style eq 'text' ? $t
: ($style eq 'script' ? $s
: $ss)));
$document->absorb($choice); },
properties => { mathstyle => sub { LookupValue('font')->getMathstyle; } });
DefMacro('\mathpalette{}{}',
'\mathchoice{#1\displaystyle{#2}}{#1\textstyle{#2}}'
. '{#1\scriptstyle{#2}}{#1\scriptscriptstyle{#2}}');
DefConstructor('\phantom{}',
"?#isMath(<ltx:XMHint width='#width' height='#height' depth='#depth' name='phantom'/>)"
. "(<ltx:text class='ltx_phantom'>#1</ltx:text>)", # !?!?!?!
properties => { isSpace => 1 },
afterDigest => sub {
my $whatsit = $_[1];
my ($w, $h, $d) = $whatsit->getArg(1)->getSize;
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
'math',
(keys %attributes ? (attributes => {%attributes}) : ())); # });
Let("\\\\", '\@alignment@newline');
Let('\lx@intercol', '\lx@math@intercol');
Let('\@row@before', '\@empty'); # Disable special row treatment (eg. numbering) unless requested
Let('\@row@after', '\@empty');
});
DefPrimitive('\lx@end@gen@matrix', sub { $_[0]->egroup; });
DefMacro('\lx@gen@plain@matrix{}{}',
'\lx@gen@matrix@bindings{#1}'
. '\lx@gen@plain@matrix@{#1}{\@start@alignment#2\@finish@alignment}'
# . '\lx@gen@plain@matrix@{#1}{\@start@alignment#2\cr\@finish@alignment}'
. '\lx@end@gen@matrix');
# The delimiters on a matrix are presumably just for notation or readability (not an operator);
# the array data itself is the matrix.
DefConstructor('\lx@gen@plain@matrix@ RequiredKeyVals:lx@GEN {}',
"?#needXMDual("
. "<ltx:XMDual>"
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
afterDigest => sub {
my ($stomach, $whatsit) = @_;
my $kv = $whatsit->getArg(1);
if ($kv->getValue('datameaning') || $kv->getValue('delimitermeaning')) {
$whatsit->setProperties(
needXMDual => 1,
xmkey => LaTeXML::Package::getXMArgID()); }
$whatsit->setProperties(alignment => LookupValue('Alignment'));
return; });
DefMacro('\matrix{}',
'\lx@gen@plain@matrix{name=matrix,datameaning=matrix}{#1}');
DefMacro('\bordermatrix{}', # Semantics?
'\lx@hack@bordermatrix{\lx@gen@plain@matrix{name=bordermatrix}{#1}}');
# HACK the newly created border matrix to add columns for the (spanned) parentheses!!!
# Assume (for now) that there's no XMDual structure here.
# What is the semantics, anyway?
DefConstructor('\lx@hack@bordermatrix{}', sub {
my ($document, $matrix) = @_;
$document->absorb($matrix);
my $marray = $document->getNode->lastChild;
my @rows = $document->findnodes('ltx:XMRow', $marray);
my ($h, $d) = (10.0 * $UNITY, 0); # 10pts.
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
['ltx:XMWrap', { depth => $d },
['ltx:XMTok', { role => 'OPEN', height => 0, depth => $d, yoffset => $md, font => $pfont }, '('],
['ltx:XMTok', { height => $h, yoffset => $md, font => $pfont }, ' ']]); # Effectively, a strut
$document->appendTree($coln,
['ltx:XMWrap', {},
['ltx:XMTok', { role => 'CLOSE', height => 0, depth => $d, yoffset => $md, font => $pfont }, ')'],
['ltx:XMTok', { height => $h, yoffset => $md, font => $pfont }, ' ']]);
return; },
reversion => '#1');
DefMacro('\pmatrix{}',
'\lx@gen@plain@matrix{name=pmatrix,datameaning=matrix,left=\@left(,right=\@right)}{#1}');
#----------------------------------------------------------------------
# Cases: Generalized
# keys are
# name : the name of the command (for reversion)
# meaning: the (presumed) meaning of the construct
# style : \textstyle or \displaystyle
# conditionmode : mode of 2nd column, text or math
# left : TeX code for left of cases
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
columns => [
{ before => Tokens($style), after => Tokens(T_CS('\hfil')) },
{ before => Tokens($style,
($condtext ? (T_CS('\lx@cases@condition')) : ())),
after => Tokens(T_CS('\lx@column@trimright'),
($condtext ? (T_CS('\lx@cases@end@condition')) : ()),
T_CS('\hfil')) }]),
'math');
Let("\\\\", '\@alignment@newline');
Let('\lx@intercol', '\lx@math@intercol');
DefMacro('\@row@before', ''); # Don't inherit counter stepping from containing environments
DefMacro('\@row@after', '');
});
DefMacro('\lx@gen@plain@cases{}{}',
'\lx@gen@cases@bindings{#1}'
. '\lx@gen@plain@cases@{#1}{\@start@alignment#2\@finish@alignment}'
. '\lx@end@gen@cases');
DefPrimitive('\lx@end@gen@cases', sub { $_[0]->egroup; });
# The logical structure for cases extracts the columns of the alignment
# to give alternating value,condition (an empty condition is replaced by "otherwise" !?!?!)
DefConstructor('\lx@gen@plain@cases@ RequiredKeyVals:lx@GEN {}',
'<ltx:XMWrap>#left#2#right</ltx:XMWrap>',
properties => sub { %{ $_[1]->getKeyVals }; },
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
$document->replaceTree(['ltx:XMDual', {},
['ltx:XMApp', {}, ['ltx:XMTok', { meaning => 'cases' }], @stuff],
$point],
$point); } },
reversion => sub {
my ($whatsit, $kv, $body) = @_;
my $name = $kv->getValue('name');
(T_CS('\cases'), T_BEGIN, Revert($body), T_END); });
# Note that 2nd column in \cases is in text mode!
DefMacro('\cases{}',
'\lx@gen@plain@cases{meaning=cases,left=\@left\{,conditionmode=text,style=\textstyle}{#1}');
#----------------------------------------------------------------------
DefPrimitive('\openup Dimension', undef);
# What should this do? (needs to work with alignments..)
# see https://www.tug.org/TUGboat/tb07-1/tb14beet.pdf
# use in arXiv:hep-th/0001208
DefMacro('\displaylines{}', '\halign{\hbox to\displaywidth{$\hfil\displaystyle##\hfil$}\crcr#1\crcr}');
DefMacro('\eqalign{}',
'\@@eqalign{\@start@alignment#1\@finish@alignment}');
DefConstructor('\@@eqalign{}',
'#1',
reversion => '\eqalign{#1}', bounded => 1,
beforeDigest => sub { alignmentBindings('rl', 'math',
attributes => { vattach => 'baseline' }); });
DefMacro('\eqalignno{}',
'\@@eqalignno{\@start@alignment#1\@finish@alignment}');
DefConstructor('\@@eqalignno{}',
'#1',
reversion => '\eqalignno{#1}', bounded => 1,
beforeDigest => sub { alignmentBindings('rll', 'math',
attributes => { vattach => 'baseline' }); });
DefMacro('\leqalignno{}',
'\@@leqalignno{\@start@alignment#1\@finish@alignment}');
DefConstructor('\@@leqalignno{}',
'#1',
reversion => '\leqalignno{#1}', bounded => 1,
beforeDigest => sub { alignmentBindings('rll', 'math',
attributes => { vattach => 'baseline' }); });
DefRegister('\pageno' => Number(0));
DefRegister('\headline' => Tokens());
DefRegister('\footline' => Tokens());
DefMacroI('\folio', undef, "1"); # What else?
DefPrimitiveI('\nopagenumbers', undef, undef);
DefMacroI('\advancepageno', undef, '\advance\pageno1\relax');
#======================================================================
# TeX Book, Appendix B. p. 363
DefPrimitive('\raggedbottom', undef);
DefPrimitive('\normalbottom', undef);
# if the mark is not simple, we add it to the content of the note
# otherwise, to the attribute.
DefConstructor('\footnote{}{}',
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
my ($stomach, $whatsit) = @_;
my $mark = $whatsit->getArg(1);
my $change = 0;
foreach my $token (Revert($mark)) {
unless ($token->getCatcode == CC_LETTER || $token->getCatcode == CC_SPACE ||
$token->getCatcode == CC_OTHER) {
$change = 1; last; } }
$whatsit->setProperty(($change ? 'prenote' : 'mark') => $mark);
return; });
# Until we can do the "v" properly:
DefMacro('\vfootnote', '\footnote');
DefMacro('\fo@t', '\ifcat\bgroup\noexpand\next \let\next\f@@t \else\let\next\f@t\fi \next');
DefMacro('\f@@t', '\bgroup\aftergroup\@foot\let\next');
DefMacro('\f@t{}', '#1\@foot');
DefMacro('\@foot', '\strut\egroup');
DefPrimitiveI('\footstrut', undef, undef);
DefRegister('\footins' => Number(0));
DefPrimitiveI('\topinsert', undef, undef);
DefPrimitiveI('\midinsert', undef, undef);
DefPrimitiveI('\pageinsert', undef, undef);
DefPrimitiveI('\endinsert', undef, undef);
# \topins ?
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
MergeFont(mathstyle => 'script');
Box(undef, undef, undef, T_CS('\scriptstyle'), explicit_mathstyle => 1); });
DefPrimitiveI('\scriptscriptstyle', undef, sub {
MergeFont(mathstyle => 'scriptscript');
Box(undef, undef, undef, T_CS('\scriptscriptstyle'), explicit_mathstyle => 1); });
#======================================================================
# Special Characters.
# Try to give them some sense in math...
DefMacroI('\#', undef, '\ifmmode\lx@math@hash\else\lx@text@hash\fi', protected => 1);
DefMacroI('\&', undef, '\ifmmode\lx@math@amp\else\lx@text@amp\fi', protected => 1);
DefMacroI('\%', undef, '\ifmmode\lx@math@percent\else\lx@text@percent\fi', protected => 1);
DefMacroI("\\\$", undef, '\ifmmode\lx@math@dollar\else\lx@text@dollar\fi', protected => 1);
DefMacroI('\_', undef, '\ifmmode\lx@math@underscore\else\lx@text@underscore\fi', protected => 1);
DefPrimitiveI('\lx@text@hash', undef, '#', alias => '\#');
DefPrimitiveI('\lx@text@amp', undef, '&', alias => '\&');
DefPrimitiveI('\lx@text@percent', undef, '%', alias => '\%');
DefPrimitiveI('\lx@text@dollar', undef, "\$", alias => "\\\$");
DefPrimitiveI('\lx@text@underscore', undef, '_', alias => '\_');
DefMathI('\lx@math@hash', undef, '#', alias => '\#');
DefMathI('\lx@math@amp', undef, '&', role => 'ADDOP', meaning => 'and', alias => '\&');
DefMathI('\lx@math@percent', undef, '%', role => 'POSTFIX', meaning => 'percent', alias => '\%');
DefMathI('\lx@math@dollar', undef, "\$", role => 'OPERATOR', meaning => 'currency-dollar',
alias => "\\\$");
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
. '])]',
replace => sub {
my ($document, $node) = @_;
my $replacement = $node->cloneNode(0);
my $content = $node->textContent;
$replacement->appendText($content);
$replacement->setName('ltx:XMTok');
$document->getNode->appendChild($replacement);
});
DefMacro('\hiderel{}', "#1"); # Just ignore, for now...
DefMathI('\to', undef, "\x{2192}", role => 'ARROW'); # RIGHTWARDS ARROW??? a bit more explicitly relation-like?
# TeX's ligatures handled by rewrite regexps.
# Note: applied in reverse order of definition (latest defined applied first!)
# Note also, these area only applied in text content, not in attributes!
DefPrimitive('\@@endash', sub { Box("\x{2013}", undef, undef, T_CS('\@@endash')); });
DefPrimitive('\@@emdash', sub { Box("\x{2014}", undef, undef, T_CS('\@@emdash')); });
sub nonTypewriter {
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
# Seemingly good candidates to trigger AmSTeX ??
foreach my $amstrigger (qw(BlackBoxes NoBlackBoxes
TagsAsMath TagsAsText TagsOnLeft TagsOnRight CenteredTagsOnSplits TopOrBottomTagsOnSplits
LimitsOnInts NoLimitsOnInts LimitsOnNames NoLimitsOnNames LimitsOnSums NoLimitsOnSums
loadbold loadeufb loadeufm loadeurb loadeurm loadeusb
loadeusm loadmathfont loadmsam loadmsbm)) {
DefAutoload($amstrigger, 'AmSTeX.pool.ltxml'); }
# Darn; we need to be even more clever, since we need to simulate an amstex command, as well.
# For example \documentstyle[...]{amsppt} must switch to AMSTeX mode, _NOT_ LaTeX mode!!!!
DefMacro('\documentstyle OptionalSemiverbatim SkipSpaces Semiverbatim', sub {
my ($gullet, $options, $class) = @_;
LoadPool((ToString($class) =~ /^amsppt$/ ? "AmSTeX" : "LaTeX"));
(T_CS('\\documentstyle'),
($options ? (T_OTHER('['), $options->unlist, T_OTHER(']')) : ()),
T_BEGIN, $class->unlist, T_END); });
# Technically should be in LaTeX.pool, but we try to maintain the bookkeeping from the very start,
# in order to avoid partially defined behavior when --preload directives are mixed with \usepackage{} loads
DefMacro('\@pushfilename', '\xdef\@currnamestack{{\@currname}{\@currext}{\the\catcode`\@}\@currnamestack}');
DefMacro('\@popfilename', '\expandafter\@p@pfilename\@currnamestack\@nil');
DefMacro('\@p@pfilename {}{}{} Until:\@nil',
'\gdef\@currname{#1}%
\gdef\@currext{#2}%
\catcode`\@#3\relax
\gdef\@currnamestack{#4}');
DefMacroI(T_CS('\@currnamestack'), undef, Tokens());
Let('\@currname', '\@empty');
Let('\@currext', '\@empty');
#**********************************************************************
# LaTeXML Specific.
# Support for Declarations & Presentation/Semantic Duality
#**********************************************************************
#======================================================================
# Normally definitions disappear; the macros are expanded or have their expected effect.
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
# Ignore $kv for the moment?????
sub I_subscript {
my ($kv, $base, $script) = @_;
return Tokens(T_CS('\lx@subscript'), I_keyvals($kv), T_BEGIN, $base, T_END, T_BEGIN, $script, T_END); }
sub I_superscript {
my ($kv, $base, $script) = @_;
return Tokens(T_CS('\lx@superscript'), I_keyvals($kv), T_BEGIN, $base, T_END, T_BEGIN, $script, T_END); }
# Superscript meaning power
DefMacro('\lx@power{}{}', '\lx@superscript[operator_meaning=power]{#1}{#2}');
# Superscript meaning functional (or applicative) power; iterated function/operator application
DefMacro('\lx@functionalpower{}{}', '\lx@superscript[operator_meaning=functional-power]{#1}{#2}');
# These to be used in presentation side
DefMathI('\lx@ApplyFunction', undef, "\x{2061}", reversion => '', name => '', role => 'APPLYOP');
DefMathI('\lx@InvisibleTimes', undef, "\x{2062}", reversion => '', name => '', meaning => 'times', role => 'MULOP');
DefMathI('\lx@InvisibleComma', undef, "\x{2063}", reversion => '', name => '', role => 'PUNCT');
DefMathI('\lx@InvisiblePlus', undef, "\x{2064}", reversion => '', name => '', meaning => 'plus', role => 'ADDOP');
DefConstructor('\lx@kludged{}',
"?#isMath(<ltx:XMWrap rule='kludge'>#1</ltx:XMWrap>)(#1)",
reversion => '#1');
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
return Tokens(T_CS('\lx@xmarg'),
T_BEGIN, (ref $id ? $id : T_OTHER($id)), T_END, T_BEGIN, $arg, T_END); }
sub I_xmref {
my ($id) = @_;
return Tokens(T_CS('\lx@xmref'), T_BEGIN, (ref $id ? $id : T_OTHER($id)), T_END); }
#----------------------------------------------------------------------
# This group should be renamed to \lx@somethings and deprecated
# NOTE: work through this systematically!
DefMacro('\FCN{}', '\lx@wrap[role=FUNCTION]{#1}');
DefMacro('\ROLE{}{}', '\lx@wrap[role={#1}]{#2}');
DefMacro('\@SYMBOL{}', '\lx@wrap[role=ID]{#1}');
DefMacro('\@CSYMBOL{}', '\lx@symbol[meaning={#1}]{}');
DefMacro('\@APPLY{}', '\lx@apply[]{#1}{}'); # Sorta broken?
DefMacro('\@MAYBEAPPLY{}{}', '\ifx.#2.#1\else\lx@apply{#1}{#2}\fi');
DefMacro('\@WRAP{}', '\lx@wrap[]{#1}');
DefMacro('\@TOKEN{}', '\lx@symbol[name={#1}]{}');
DefMacro('\@SUPERSCRIPT{}{}', '\ifx.#2.#1\else\lx@superscript[]{#1}{#2}\fi');
DefMacro('\@SUBSCRIPT{}{}', '\ifx.#2.#1\else\lx@subscript[]{#1}{#2}\fi');
Let('\@PADDED', '\lx@padded');
Let('\DUAL', '\lx@dual');
Let('\@XMArg', '\lx@xmarg');
Let('\@XMRef', '\lx@xmref');
Let('\@APPLYFUNCTION', '\lx@ApplyFunction');
Let('\@INVISIBLETIMES', '\lx@InvisibleTimes');
Let('\@INVISIBLECOMMA', '\lx@InvisibleComma');
Let('\@INVISIBLEPLUS', '\lx@InvisiblePlus');
# End of stuff to be deprecated.
#----------------------------------------------------------------------
#======================================================================
# We OUGHT to be able to do this using \llap,\rlap,\hss...
DefMacro('\lx@tweaked{}{}', '\ifmmode\lx@math@tweaked{#1}{#2}\else\lx@text@tweaked{#1}{#2}\fi');
DefConstructor('\lx@math@tweaked RequiredKeyVals {}',
"<ltx:XMWrap $XMath_attributes>#2</ltx:XMWrap>",
afterDigest => sub {
my ($stomach, $whatsit) = @_;
my ($kv, $body) = $whatsit->getArgs;
XMath_copy_keyvals($stomach, $whatsit);
$whatsit->setFont($body->getFont);
return; },
reversion => '#2');
DefConstructor('\lx@text@tweaked RequiredKeyVals {}',
"<ltx:text _noautoclose='1' %&GetKeyVals(#1)>#2</ltx:text>",
afterDigest => sub {
my ($stomach, $whatsit) = @_;
my ($kv, $body) = $whatsit->getArgs;
$whatsit->setProperties($kv->getPairs); });
DefMacro('\lx@nounicode {}', '\ifmmode\lx@math@nounicode#1\else\lx@text@nounicode#1\fi');
DefConstructor('\lx@framed[]{}',
"<ltx:text framed='#frame' _noautoclose='1'>#2</ltx:text>",
properties => { frame => sub { ToString($_[1] || 'rectangle'); } });
DefConstructor('\lx@hflipped{}',
"<ltx:text class='ltx_hflipped' _noautoclose='1'>#1</ltx:text>");
sub reportNoUnicode {
my ($cs) = @_;
$cs = ToString($cs);
lib/LaTeXML/Package/TeX.pool.ltxml view on Meta::CPAN
# Inverse operation
sub JoinTokens {
my ($conjunction, @things) = @_;
if (!@things) { return (); }
my @result = (shift(@things));
while (my $thing = shift(@things)) {
push(@result, $conjunction, $thing); }
return Tokens(@result); }
DefMacro('\dump', sub {
Warn('unexpected', 'dump', $_[0], "Do not know how to \\dump yet, sorry"); });
#**********************************************************************
LoadPool('eTeX'); # unless.... ?
LoadPool('pdfTeX'); # unless.... ?
#**********************************************************************
1;
lib/LaTeXML/Package/a4.sty.ltxml view on Meta::CPAN
# | http://dlmf.nist.gov/LaTeXML/ (o o) | #
# \=========================================================ooo==U==ooo=/ #
package LaTeXML::Package::Pool;
use strict;
use warnings;
use LaTeXML::Package;
#**********************************************************************
# Nothing to do here!
#**********************************************************************
DefMacro('\WideMargins', '');
DefRegister('\ExtraWidth' => Dimension(0));
1;
lib/LaTeXML/Package/aa.cls.ltxml view on Meta::CPAN
ProcessOptions();
LoadClass('article');
RequirePackage('aa_support');
# except don't use the \pmatrix from amsmath.sty
# (which gets loaded through aa_support's dependencies)
# see arXiv:astro-ph/0002145 for an example.
# just use the one from TeX.pool, copied here:
DefMacro('\pmatrix{}',
'\lx@gen@plain@matrix{name=pmatrix,datameaning=matrix,left=\@left(,right=\@right)}{#1}');
# also don't use the amsmath cases
DefMacro('\cases{}',
'\lx@gen@plain@cases{meaning=cases,left=\@left\{,conditionmode=text,style=\textstyle}{#1}');
# but allow reloading amsmath.sty if {cases} was really needed (arXiv:astro-ph/0203101)
AssignValue('amsmath.sty.ltxml_loaded', undef, 'global');
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1;
lib/LaTeXML/Package/aa_support.sty.ltxml view on Meta::CPAN
RequirePackage('longtable');
RequirePackage('xspace');
RequirePackage('babel');
RequirePackage('rotating');
#RequirePackage('answers');
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# The Manuscript Header
# Title
DefMacro('\subtitle{}', '\@add@frontmatter{ltx:subtitle}{#1}');
# "Structured" abstract
# Note that they suggest either a 5 or 1 argument version!
# NOT an environment!!!
DefMacro('\abstract@old{}',
'\@add@frontmatter{ltx:abstract}{#1}');
# Apparently args #2--#4 are required non-empty.
DefMacro('\abstract@new{}{}{}{}{}',
'\@add@frontmatter{ltx:abstract}[name={\abstractname}]{'
.'\ifx.#1.\else\textit{Context. }#1\par\fi'
.'\textit{Aims. }#2\par'
.'\textit{Methods. }#3\par'
.'\textit{Results. }#4\par'
.'\ifx.#5.\else\textit{Conclusions. }#5\fi'
.'}');
DefMacro('\abstract{}', sub {
my ($gullet, $arg1) = @_;
$gullet->skipSpaces; # I think?
((T_CS($gullet->ifNext(T_BEGIN)
? '\abstract@new' : '\abstract@old')),
T_BEGIN, $arg1->unlist, T_END); });
# Keywords
DefMacroI('\keywordname', undef, '\sffamily\bfseries Key Words.');
DefMacro('\keywords{}', '\@add@frontmatter{ltx:keywords}[name={\keywordname}]{#1}');
# Formatting the header and running title
DefRegister('\titlerunning', Tokens()); # Ignorable
DefRegister('\authorrunning', Tokens());
#DefRegister('\authrun'=>Box());
#DefRegister('\titrun'=>Box());
DefMacro('\authrun', '');
DefMacro('\titrun', '');
# undocumented ?
DefMacro('\offprints{}', '\@add@frontmatter{ltx:note}[role=offprints]{#1}');
DefConstructor('\@@@email{}', "^ <ltx:contact role='email'>#1</ltx:contact>");
DefMacro('\email Semiverbatim', '\@add@to@frontmatter{ltx:creator}{\@@@email{#1}}');
DefMacro('\journalname{}', '');
DefMacro('\rnotename', '(Research Note)');
DefMacro('\rnotname', '(RN)');
# should add a note?
DefMacro('\headnote{}', '\@add@frontmatter{ltx:note}{#1}');
DefMacro('\dedication{}', '\@add@frontmatter{ltx:note}[role=dedicatory]{#1}');
DefConstructor('\@@@mail{}', "^ <ltx:contact role='email'>#1</ltx:contact>");
DefMacro('\mail Semiverbatim', '\@add@to@frontmatter{ltx:creator}{\@@@mail{#1}}');
DefMacro('\mailname', '\it Correspondence to \/');
DefMacro('\doi{}', '\@add@frontmatter{ltx:classification}[scheme=doi]{#1}');
DefMacro('\idline{}{}', ''); # ?
DefMacro('\msnr{}', ''); # ??
DefMacro('\institutename', ''); # ?
DefMacro('\hugehead', '');
DefMacro('\AALogo', 'Astronomy and Astrophysics');
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# The main text
DefConstructor('\acknowledgements', "<ltx:acknowledgements name='#name'>",
properties => sub { (name => Digest(T_CS('\acknowledgmentsname'))); });
DefConstructor('\endacknowledgements', "</ltx:acknowledgements>");
DefConstructor('\acknowledgement', "<ltx:acknowledgements name='#name'>",
properties => sub { (name => Digest(T_CS('\acknowledgmentsname'))); });
DefConstructor('\endacknowledgement', "</ltx:acknowledgements>");
Tag("ltx:acknowledgements", autoClose => 1);
DefMacro('\acknowledgmentsname', 'Acknowledgements');
DefMacro('\ackname', 'Acknowledgements');
RawTeX(<<'EoTeX');
\newtheorem*{proof}{Proof}{\it}{\rm}
\newtheorem{corollary}[theorem]{Corollary}{\bf}{\it}
\newtheorem{definition}[theorem]{Definition}{\bf}{\rm}
\newtheorem{example}[theorem]{Example}{\it}{\rm}
\newtheorem{exercise}[theorem]{Exercise}{\it}{\rm}
\newtheorem{lemma}[theorem]{Lemma}{\bf}{\it}
\newtheorem{note}[theorem]{Note}{\it}{\rm}
\newtheorem{problem}[theorem]{Problem}{\it}{\rm}
\newtheorem{proposition}[theorem]{Proposition}{\bf}{\it}
\newtheorem{question}[theorem]{Question}{\it}{\rm}
\newtheorem{remark}[theorem]{Remark}{\it}{\rm}
\newtheorem{solution}[theorem]{Solution}{\it}{\rm}
EoTeX
DefMacro('\noteaddname', 'Note added in proof');
DefEnvironment('{noteadd}', "<ltx:note>#body</ltx:note>");
# Undocumented, but something like:
DefMacro('\thesaurus{}', '');
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Redefine equations (bizarrely) to allow $ within
DefEnvironment('{equation}',
"<ltx:equation xml:id='#id'>"
. "#tags"
. "<ltx:Math mode='display'>"
. "<ltx:XMath>"
. "#body"
. "</ltx:XMath>"
lib/LaTeXML/Package/aa_support.sty.ltxml view on Meta::CPAN
Let(T_MATH, T_CS('\@dollar@in@mathmode')); },
afterDigestBody => sub {
afterEquation($_[1]); },
locked => 1);
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Figures
# the usual...
### Let('\sidecaption','\caption'); NO!!!
# Should be something like this
# DefMacro('\sidecaption Until:\caption', ... );
# but let's just ignore it for now.
DefMacro('\sidecaption', '');
# NOTE: Sort this out!!
# I'm a little unclear how this is supposed to be used -- it isn't documented.
# Clearly it provides for sub-numbered figures, but
# are people supposed to put multiple figure environments within {figure}
# or just multiple graphics and multiple captions?
# The latter, probably, but....
DefMacro('\resetsubfig{}', ''); #
DefMacro('\subfigures', '');
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Tables
# the usual...
# Actually not sure exactly what this is,
# \longtab{num}{table}
DefMacro('\longtab{}', ''); # just let it do the table contents as usual.
# variations of footnote used within tables
Let('\tablefoot', '\footnote');
DefMacro('\tablefootmark{}', '\footnotemark[$#1$]');
DefMacro('\tablefoottext{}{}', '\footnotetext[$#1$]{#2}');
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# References
# the usual...
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Typography
DefMacro('\vec{}', '\ensuremath{\@vec{#1}}');
DefMath('\@vec{}', '#1', role => 'ID', font => { forcebold => 1 });
DefMacro('\tens{}', '\ensuremath{\@tens{#1}}');
DefMath('\@tens{}', '\mathsf{#1}', role => 'ID'); # semantics?
# \ion{symbol}{ionization}
# Note that semantics could be useful!
DefMacro('\ion{}{}', '{#1 \textsc{#2}}');
# \element[charge][nucleons][protons][neutrons]{symbol}
DefMacro('\element[][][][]{}', '\ensuremath{\@element[#1][#2][#3][#4]{\mathrm{#5}}}');
DefConstructor('\@element[][][][]{}', sub {
my ($document, $charge, $nucleons, $protons, $neutrons, $element, %props) = @_;
my $level = $props{scriptlevel};
my $node = $document->insertElement('ltx:XMArg', $element);
$node = wrapIsotope($document, $node, $charge, 'post', 'SUPER', $level) if $charge;
$node = wrapIsotope($document, $node, $neutrons, 'post', 'SUB', $level) if $neutrons;
$node = wrapIsotope($document, $node, $nucleons, 'pre', 'SUPER', $level) if $nucleons;
$node = wrapIsotope($document, $node, $protons, 'pre', 'SUB', $level) if $protons;
$node; });
lib/LaTeXML/Package/aa_support.sty.ltxml view on Meta::CPAN
# Various degrees etc.
# Copied from aas_support
DefConstructor('\aas@@fstack{}',
"<ltx:XMApp role='POSTFIX'>"
. "<ltx:XMTok role='SUPERSCRIPTOP' scriptpos='#scriptpos'/>"
. "<ltx:XMTok>.</ltx:XMTok>"
. "<ltx:XMWrap>#1</ltx:XMWrap>"
. "</ltx:XMApp>",
properties => { scriptpos => sub { "mid" . $_[0]->getScriptLevel; } },
mode => 'math', bounded => 1);
DefMacro('\aas@fstack{}', '\ensuremath{\aas@@fstack{#1}}');
DefMacro('\fd', '\aas@fstack{d}');
DefMacro('\fh', '\aas@fstack{h}');
DefMacro('\fm', '\aas@fstack{m}');
DefMacro('\fs', '\aas@fstack{s}');
DefMacro('\fdg', '\aas@fstack{\circ}');
DefMacro('\farcm', '\aas@fstack{\prime}');
DefMacro('\farcs', '\aas@fstack{\prime\prime}');
DefMacro('\fp', '\aas@fstack{p}');
DefConstructor('\mathsc{}', '#1', bounded => 1, requireMath => 1,
font => { family => 'smallcaps', series => 'medium', shape => 'upright' });
# NOTE: Would like to see this used; do these put a \sim or \approx underneath something?
#DefMacro('\udtw','');
#DefMacro('\utw','');
DefConstructor('\squareforqed',
"?#isMath(<ltx:XMTok role='PUNCT'>\x{220E}</ltx:XMTok>)(\x{220E})");
DefMacro('\sq', '\squareforqed');
DefMacro('\qed', '\squareforqed');
DefPrimitiveI('\bbbc', undef, "\x{2102}"); #not sure if ok for the ones NOT of type I$
DefPrimitiveI('\bbbf', undef, "\x{1D53D}");
DefPrimitiveI('\bbbh', undef, "\x{210D}");
DefPrimitiveI('\bbbk', undef, "\x{1D542}");
DefPrimitiveI('\bbbm', undef, "\x{1D544}");
DefPrimitiveI('\bbbn', undef, "\x{2115}");
DefPrimitiveI('\bbbone', undef, "\x{1D7D9}");
DefPrimitiveI('\bbbp', undef, "\x{2119}");
DefPrimitiveI('\bbbq', undef, "\x{211A}");
lib/LaTeXML/Package/aa_support.sty.ltxml view on Meta::CPAN
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Online material
# Support for adsurl URLs containing unescaped % characters, e.g. %26
# in A&A URLs
DefConstructor('\bib@field@default@adsurl Verbatim',
"<ltx:bib-url href='#1'>ADS entry</ltx:bib-url>");
# We could probably do more with these if they were used consistently...
# example use is [\eprint[arXiv]{astro-ph/0212111}], in a bibitem
DefMacro('\eprint[]{}', '{\tt\if!#1!#2\else#1:#2\fi}');
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Astronomical objects
DefConstructor('\object Semiverbatim',
"<ltx:text class='ltx_ast_objectname'>#1</ltx:text>");
DefMacro('\listofobjects', '');
DefMacro('\listobjectname', 'List of Objects');
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Extra stuff
DefMacro('\setitemindent{}', ''); # Ignorable
DefMacro('\setitemitemindent{}', '');
DefMacro('\andname', 'and');
#DefMacro('\lastand','');
DefMacro('\lastandname', ', and');
DefMacro('\AASection{}', ''); # Ignorable
DefMacro('\Online', '');
# Random dimensions, or spacing; would anyone use?
DefRegister('\aftertext' => Dimension('5pt'));
DefRegister('\betweenumberspace' => Dimension('3.33pt'));
DefRegister('\figcapgap' => Dimension('5pt'));
DefRegister('\tabcapgap' => Dimension('10pt'));
DefRegister('\figgap' => Dimension('1cc'));
DefRegister('\headerboxheight' => Dimension('143pt'));
DefRegister('\headlineindent' => Dimension('1.166cm'));
DefRegister('\instindent' => Dimension(0));
DefMacro('\leftlegendglue', '');
DefRegister('\logodepth' => Dimension('1.3cm'));
DefMacro('\capstrut', '');
DefMacro('\captionstyle', '');
DefMacro('\clearelargs', '');
DefMacro('\errorref', '@latex@error{Citations are not allowed in the abstract}');
DefMacro('\floatcounterend', '.');
DefMacro('\sectcounterend', '.');
DefMacro('\floatlegendstyle', '\bf');
DefMacro('\thisbottomragged', '');
DefMacro('\ts', '\thinspace');
DefMacro('\fnmsep', '\unskip$^,$'); # ?
DefMacro('\makeheadbox', '');
#DefMacro('\stripauthor','');
#DefMacro('\theapsection','Appendix \@Alph\c@section:');
#DefMacro('\theapsubsection','\@Alph\c@section.\@arabic\c@subsection.');
#DefMacro('\theapsubsubsection','\theheapsubsection\@arabic\c@subsubsection');
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Journal shorthands
DefMacro('\aj', 'AJ');
DefMacro('\actaa', 'Acta Astron.');
DefMacro('\araa', 'ARA\&A');
DefMacro('\apj', 'ApJ');
DefMacro('\apjl', 'ApJ');
DefMacro('\apjs', 'ApJS');
DefMacro('\ao', 'Appl.~Opt.');
DefMacro('\apss', 'Ap\&SS');
DefMacro('\aap', 'A\&A');
DefMacro('\aapr', 'A\&A~Rev.');
DefMacro('\aaps', 'A\&AS');
DefMacro('\azh', 'AZh');
DefMacro('\baas', 'BAAS');
DefMacro('\bac', 'Bull. astr. Inst. Czechosl.');
DefMacro('\caa', 'Chinese Astron. Astrophys.');
DefMacro('\cjaa', 'Chinese J. Astron. Astrophys.');
DefMacro('\icarus', 'Icarus');
DefMacro('\jcap', 'J. Cosmology Astropart. Phys.');
DefMacro('\jrasc', 'JRASC');
DefMacro('\mnras', 'MNRAS');
DefMacro('\memras', 'MmRAS');
DefMacro('\na', 'New A');
DefMacro('\nar', 'New A Rev.');
DefMacro('\pasa', 'PASA');
DefMacro('\pra', 'Phys.~Rev.~A');
DefMacro('\prb', 'Phys.~Rev.~B');
DefMacro('\prc', 'Phys.~Rev.~C');
DefMacro('\prd', 'Phys.~Rev.~D');
DefMacro('\pre', 'Phys.~Rev.~E');
DefMacro('\prl', 'Phys.~Rev.~Lett.');
DefMacro('\pasp', 'PASP');
DefMacro('\pasj', 'PASJ');
DefMacro('\qjras', 'QJRAS');
DefMacro('\rmxaa', 'Rev. Mexicana Astron. Astrofis.');
DefMacro('\skytel', 'S&T');
DefMacro('\solphys', 'Sol.~Phys.');
DefMacro('\sovast', 'Sov.~Ast.');
DefMacro('\ssr', 'Space~Sci.~Rev.');
DefMacro('\zap', 'ZAp');
DefMacro('\nat', 'Nature');
DefMacro('\iaucirc', 'IAU~Circ.');
DefMacro('\aplett', 'Astrophys.~Lett.');
DefMacro('\apspr', 'Astrophys.~Space~Phys.~Res.');
DefMacro('\bain', 'Bull.~Astron.~Inst.~Netherlands');
DefMacro('\fcp', 'Fund.~Cosmic~Phys.');
DefMacro('\gca', 'Geochim.~Cosmochim.~Acta.');
DefMacro('\grl', 'Geochim.~Res.~Lett.');
DefMacro('\jcp', 'J.~Chem.~Phys.');
DefMacro('\jgr', 'J.~Geophys.~Res.');
DefMacro('\jqsrt', 'J.~Quant.~Spec.~Radiat.~Transf.');
DefMacro('\memsai', 'Mem.~Soc.~Astron.~Italiana');
DefMacro('\nphysa', 'Nucl.~Phys.~A');
DefMacro('\physrep', 'Phys.~Rep');
DefMacro('\physscr', 'Phys.~Scr');
DefMacro('\planss', 'Planet.~Space~Sci.');
DefMacro('\procspie', 'Proc.~SPIE');
Let('\astap', '\aap');
Let('\apjlett', '\ajpl');
Let('\apjsupp', '\ajps');
Let('\applopt', '\ao');
DefMacro('\errorref', '');
DefEnvironment('{stopref}', '#1');
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1;
lib/LaTeXML/Package/aas_macros.sty.ltxml view on Meta::CPAN
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# AAS : American Astronomical Society
# Subset of AAS macros from aasguide
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#======================================================================
# 2.13.4 Abbreviations for Journal Names
Let('\jnl@style', '\rm');
DefMacro('\ref@jnl{}', '{\jnl@style#1}');
DefMacro('\aj', '\ref@jnl{AJ}'); # Astronomical Journal
DefMacro('\actaa', '\ref@jnl{Acta Astron.}'); # Acta Astronomica
DefMacro('\araa', '\ref@jnl{ARA\&A}'); # Annual Review of Astron and Astrophys
DefMacro('\apj', '\ref@jnl{ApJ}'); # Astrophysical Journal
DefMacro('\apjl', '\ref@jnl{ApJ}'); # Astrophysical Journal, Letters
DefMacro('\apjs', '\ref@jnl{ApJS}'); # Astrophysical Journal, Supplement
DefMacro('\ao', '\ref@jnl{Appl.~Opt.}'); # Applied Optics
DefMacro('\apss', '\ref@jnl{Ap\&SS}'); # Astrophysics and Space Science
DefMacro('\aap', '\ref@jnl{A\&A}'); # Astronomy and Astrophysics
DefMacro('\aapr', '\ref@jnl{A\&A~Rev.}'); # Astronomy and Astrophysics Reviews
DefMacro('\aaps', '\ref@jnl{A\&AS}'); # Astronomy and Astrophysics, Supplement
DefMacro('\azh', '\ref@jnl{AZh}'); # Astronomicheskii Zhurnal
DefMacro('\baas', '\ref@jnl{BAAS}'); # Bulletin of the AAS
DefMacro('\bac', '\ref@jnl{Bull. astr. Inst. Czechosl.}'); # Bulletin of the Astronomical Institutes of Czechoslovakia
DefMacro('\caa', '\ref@jnl{Chinese Astron. Astrophys.}'); # Chinese Astronomy and Astrophysics
DefMacro('\cjaa', '\ref@jnl{Chinese J. Astron. Astrophys.}'); # Chinese Journal of Astronomy and Astrophysics
DefMacro('\icarus', '\ref@jnl{Icarus}'); # Icarus
DefMacro('\jcap', '\ref@jnl{J. Cosmology Astropart. Phys}'); # Journal of Cosmology and Astroparticle Physics
DefMacro('\jrasc', '\ref@jnl{JRASC}'); # Journal of the RAS of Canada
DefMacro('\memras', '\ref@jnl{MmRAS}'); # Memoirs of the RAS
DefMacro('\mnras', '\ref@jnl{MNRAS}'); # Monthly Notices of the RAS
DefMacro('\na', '\ref@jnl{New A}'); # New Astronomy
DefMacro('\nar', '\ref@jnl{New A Rev.}'); # New Astronomy Review
DefMacro('\pra', '\ref@jnl{Phys.~Rev.~A}'); # Physical Review A: General Physics
DefMacro('\prb', '\ref@jnl{Phys.~Rev.~B}'); # Physical Review B: Solid State
DefMacro('\prc', '\ref@jnl{Phys.~Rev.~C}'); # Physical Review C
DefMacro('\prd', '\ref@jnl{Phys.~Rev.~D}'); # Physical Review D
DefMacro('\pre', '\ref@jnl{Phys.~Rev.~E}'); # Physical Review E
DefMacro('\prl', '\ref@jnl{Phys.~Rev.~Lett.}'); # Physical Review Letters
DefMacro('\pasa', '\ref@jnl{PASA}'); # Publications of the Astron. Soc. Australia
DefMacro('\pasp', '\ref@jnl{PASP}'); # Publications of the ASP
DefMacro('\pasj', '\ref@jnl{PASJ}'); # Publications of the ASJ
DefMacro('\qjras', '\ref@jnl{QJRAS}'); # Quarterly Journal of the RAS
DefMacro('\rmxaa', '\ref@jnl{Rev. Mexicana Astron. Astrofis.}'); # Revista Mexicana de Astronomia y Astrofisica
DefMacro('\skytel', '\ref@jnl{S\&T}'); # Sky and Telescope
DefMacro('\solphys', '\ref@jnl{Sol.~Phys.}'); # Solar Physics
DefMacro('\sovast', '\ref@jnl{Soviet~Ast.}'); # Soviet Astronomy
DefMacro('\ssr', '\ref@jnl{Space~Sci.~Rev.}'); # Space Science Reviews
DefMacro('\zap', '\ref@jnl{ZAp}'); # Zeitschrift fuer Astrophysik
DefMacro('\nat', '\ref@jnl{Nature}'); # Nature
DefMacro('\iaucirc', '\ref@jnl{IAU~Circ.}'); # IAU Cirulars
DefMacro('\aplett', '\ref@jnl{Astrophys.~Lett.}'); # Astrophysics Letters
DefMacro('\apspr', '\ref@jnl{Astrophys.~Space~Phys.~Res.}'); # Astrophysics Space Physics Research
DefMacro('\bain', '\ref@jnl{Bull.~Astron.~Inst.~Netherlands}'); # Bulletin Astronomical Institute of the Netherlands
DefMacro('\fcp', '\ref@jnl{Fund.~Cosmic~Phys.}'); # Fundamental Cosmic Physics
DefMacro('\gca', '\ref@jnl{Geochim.~Cosmochim.~Acta}'); # Geochimica Cosmochimica Acta
DefMacro('\grl', '\ref@jnl{Geophys.~Res.~Lett.}'); # Geophysics Research Letters
DefMacro('\jcp', '\ref@jnl{J.~Chem.~Phys.}'); # Journal of Chemical Physics
DefMacro('\jgr', '\ref@jnl{J.~Geophys.~Res.}'); # Journal of Geophysics Research
DefMacro('\jqsrt', '\ref@jnl{J.~Quant.~Spec.~Radiat.~Transf.}'); # Journal of Quantitiative Spectroscopy and Radiative Trasfer
DefMacro('\memsai', '\ref@jnl{Mem.~Soc.~Astron.~Italiana}'); # Mem. Societa Astronomica Italiana
DefMacro('\nphysa', '\ref@jnl{Nucl.~Phys.~A}'); # Nuclear Physics A
DefMacro('\physrep', '\ref@jnl{Phys.~Rep.}'); # Physics Reports
DefMacro('\physscr', '\ref@jnl{Phys.~Scr}'); # Physica Scripta
DefMacro('\planss', '\ref@jnl{Planet.~Space~Sci.}'); # Planetary Space Science
DefMacro('\procspie', '\ref@jnl{Proc.~SPIE}'); # Proceedings of the SPIE
Let('\astap', '\aap');
Let('\apjlett', '\apjl');
Let('\apjsupp', '\apjs');
Let('\applopt', '\ao');
#======================================================================
1;
lib/LaTeXML/Package/aas_support.sty.ltxml view on Meta::CPAN
RequirePackage('url');
RequirePackage('longtable');
RequirePackage('xcolor');
RequirePackage('hyperref');
RequirePackage('array');
RequirePackage('lineno');
RequirePackage('ulem');
#======================================================================
# 2.1.3 Editorial Information
DefMacro('\received{}', '\@add@frontmatter{ltx:date}[role=received,name=Received]{#1}');
DefMacro('\revised{}', '\@add@frontmatter{ltx:date}[role=revised,name=Revised]{#1}');
DefMacro('\accepted{}', '\@add@frontmatter{ltx:date}[role=accepted,name=Accepted]{#1}');
# Could add more metadata..
DefMacro('\journalid{}{}', '');
DefMacro('\articleid{}{}', '');
DefMacro('\paperid{}', '');
DefMacro('\msid{}', ''); # Manuscript id.
DefMacro('\added{}', '');
DefMacro('\replaced{}', '');
DefMacro('\deleted{}', '');
DefMacro('\explain{}', '');
DefMacro('\edit{}{}', '');
#\ccc{code}
DefMacro('\ccc{}', ''); # Ignorable?
#\cpright{type}{year} Should be recorded somehow?
# type is AAS, ASP, PD, none
DefMacro('\cpright{}{}', '\@add@frontmatter{ltx:note}[role=copyright]{\copyright #2: #1}');
# Editorial additions?
DefMacro('\journal{}', '');
DefMacro('\volume{}', '');
DefMacro('\issue{}', '');
DefMacro('\SGMLbi{}', '#1');
DefMacro('\SGMLbsc{}', '#1');
DefMacro('\SGMLclc{}', '#1');
DefMacro('\SGMLentity{}', '#1'); # Actually should produce  !!!
DefMacro('\SGML{}', '');
#======================================================================
# 2.1.4 Short Comment
DefMacro('\slugcomment{}', '\@add@frontmatter{ltx:note}[role=slugcomment]{#1}');
#======================================================================
# 2.1.5 Running Heads
DefMacro('\shorttitle{}', '\@add@frontmatter{ltx:toctitle}{#1}');
DefMacro('\shortauthors{}', ''); # not useful?
# Meant to be used redundantly with an \author macro, so just register the correspondence here
DefMacro('\correspondingauthor{}', '\lx@contact{correspondent}{#1}');
# I had thought that \lefthead,\righthead were obsolete forms of \shorttitle,\shortauthors,
# but who knows which goes on which side.... anyway, they get misused too.
# better have them just disappear.
DefMacro('\lefthead{}', ''); # Obsolete form
DefMacro('\righthead{}', ''); # Obsolete form
#======================================================================
# 2.2 Starting the Main Body
# normal LaTeX
#======================================================================
# 2.3 Title and Author Information
AssignMapping('DOCUMENT_CLASSES', ltx_authors_multiline => 1);
DefConstructor('\@@personname[]{}', "<ltx:personname>" .
"?#1(<ltx:ref href='https://orcid.org/#1' class='orcid'>#2</ltx:ref>)(#2)" .
"</ltx:personname>)");
DefMacro('\author[]{}',
'\@add@frontmatter{ltx:creator}[role=author]{\@@personname[#1]{#2}}');
DefConstructor('\@@@affiliation{}', "^ <ltx:contact role='affiliation'>#1</ltx:contact>");
DefMacro('\affiliation{}', '\@add@to@frontmatter{ltx:creator}{\@@@affiliation{#1}}');
DefMacro('\affil', '\affiliation');
DefConstructor('\@@@altaffil{}', "^ <ltx:contact role='affiliation'>#1</ltx:contact>");
DefMacro('\altaffiliation{}', '\@add@to@frontmatter{ltx:creator}{\@@@altaffil{#1}}');
DefConstructor('\@@@authoraddr{}', "^ <ltx:contact role='address'>#1</ltx:contact>");
DefMacro('\authoraddr{}', '\@add@to@frontmatter{ltx:creator}{\@@@authoraddr{#1}}');
DefConstructor('\@@@email{}', "^ <ltx:contact role='email'>#1</ltx:contact>");
DefMacro('\email{}', '\@add@to@frontmatter{ltx:creator}{\@@@email{#1}}');
# Redefine to straight email address after document begin.
AddToMacro(T_CS('\@startsection@hook'), TokenizeInternal('\let\email\@@email'));
DefPrimitive('\and', undef);
DefMacro('\authoremail', '\email'); # Obsolete form
# NOTE: the the footnote machinery in LaTeX.pool will connect these.
# Ideally, we'd like these comma separated!
DefMacro('\altaffilmark{}', sub {
my ($gullet, $marks) = @_;
map { (T_CS('\@altaffilmark'), T_BEGIN, @$_, T_END) } SplitTokens($marks, T_OTHER(',')); });
DefConstructor('\@altaffilmark{}',
"?#1(<ltx:note role='affiliationmark' mark='#1'/> )()");
DefConstructor('\altaffiltext{}{}',
"?#2(<ltx:note role='affiliationtext' mark='#1'>#2</ltx:note>)()");
DefMacro('\software{}', '\@add@frontmatter{ltx:note}[role=software]{#1}');
DefMacro('\submitjournal{}', '\@add@frontmatter{ltx:note}[role=journal]{#1}');
# Alas \doi is not frontmatter.
DefConstructor('\doi{}', '<ltx:ref href="https:/doi.org/#1">#1</ltx:ref>');
DefConstructor('\@@@collaborator{}', "<ltx:note role='collaborator'>#1</ltx:note>");
DefMacro('\collaboration{}{}', '\@add@to@frontmatter{ltx:creator}{\@@@collaborator{#2}}');
DefMacro('\nocollaboration{}', '');
#======================================================================
# 2.4 Abstract
# normal LaTeX
#======================================================================
# 2.5 Keywords
DefMacro('\keywords{}', '\@add@frontmatter{ltx:keywords}[name={\@ifundefined{keywordsname}{}{\keywordsname}}]{#1}');
Let('\subjectheadings', '\keywords');
#======================================================================
# 2.6 Comments to Editors
# Perhaps this should actually disappear?
# DefConstructor('\notetoeditor{}',"<ltx:note role='toeditor'>#1</ltx:note>");
DefMacro('\notetoeditor{}', '');
NewCounter('editornote');
DefMacroI('\theeditornote', undef, 'E\arabic{editornote}');
#======================================================================
# 2.7 Sections
# normal LaTeX
# Except that they apparently allow subsubsubsections! Ugh!
#======================================================================
# 2.8 Figure and Table Placement
# These tell where the table/figure labeled with \label{key} ought to appear;
# the assumption is the tables/figures are at the end of the document.
# Best would be if we moved them to there the \placeXXX is!
# \placetable{key}
# \placefigure{key}
# For now, we ignore them, however.
DefMacro('\placetable{}', '');
DefMacro('\placefigure{}', '');
DefMacro('\placeplate{}', '');
NewCounter('plate');
DefMacroI('\platename', undef, 'Plate');
# Is there any kind of "list of plates" ? Then we'd need @inlists
DefEnvironment('{plate}[]',
"<ltx:float xml:id='#id' inlist='#inlist' ?#1(placement='#1') class='ltx_float_plate'>"
. "#tags"
. "#body"
. "</ltx:float>",
beforeDigest => sub { beforeFloat('plate'); },
afterDigest => sub { afterFloat($_[1]); });
DefEnvironment('{plate*}[]',
"<ltx:float xml:id='#id' inlist='#inlist' ?#1(placement='#1') class='ltx_float_plate'>"
. "#tags"
. "#body"
. "</ltx:float>",
beforeDigest => sub { beforeFloat('plate', double => 1); },
afterDigest => sub { afterFloat($_[1]); });
DefMacro('\platewidth{Dimension}', ''); # Ignorable?
DefMacro('\platenum{}', '\def\theplate{#1}');
DefMacro('\gridline{}', '');
# Can we try to be smart enough and recover a single argument \fig by checking the second?
DefMacro('\fig Semiverbatim Token', sub {
my ($gullet, $arg, $test) = @_;
if (Equals($test, T_BEGIN)) {
$gullet->unread(T_BEGIN, $arg, T_END, $test);
return T_CS('\aas@fig'); }
else {
# see arXiv:astro-ph/0003209 for an example use as \ref
# while also loading aas_support.sty.ltxml. Tricky!!
$gullet->unread(T_BEGIN, $arg, T_END, $test);
return T_CS('\ref'); } });
DefMacro('\aas@fig Semiverbatim {Dimension}{}',
'\begin{figure}\caption{#3}\includegraphics[width=#2]{#1}\end{figure}');
Let('\leftfig', '\fig');
Let('\rightfig', '\fig');
Let('\boxedfig', '\fig');
DefMacro('\rotatefig {Number} Semiverbatim {Dimension}{}',
'\begin{figure}\caption{#4}\includegraphics[width=#3,angle=#1]{#2}\end{figure}');
DefEnvironment('{interactive}{}{}', '#body');
#======================================================================
# 2.9 Acknowledgements
# acts like \section{Acknowledgements}, rather than container.
Tag("ltx:acknowledgements", autoClose => 1);
DefConstructor('\acknowledgements', "<ltx:acknowledgements>");
Let('\acknowledgments', '\acknowledgements');
#======================================================================
# 2.10 Facilities
# Ultimately, this would get some more explicit semantic markup, but..
# \facility{facilityID}
DefConstructor('\facility{}', "<ltx:text class='ltx_ast_facility'>#1</ltx:text>");
DefMacro('\facilities{}', '\@add@frontmatter{ltx:note}[role=facilities]{#1}');
#======================================================================
# 2.11 Appendices
# almost normal LaTeX
DefMacro('\appendix', '\@appendix');
DefPrimitive('\@appendix', sub {
startAppendices('section');
NewCounter('equation', 'section', idprefix => 'E');
DefMacro('\theequation', '\thesection\arabic{equation}', scope => 'global'); });
#======================================================================
# 2.12 Equations
# mostly normal LaTeX
# Basically, {mathletters} is a copy of AMSMath's {subequations}... Isn't it?
DefMacro('\mathletters', '\lx@equationgroup@subnumbering@begin');
DefMacro('\endmathletters', '\lx@equationgroup@subnumbering@end');
# \eqnum{text} specifies equation number inside an equation
# Basically, AMSMath's \tag ?
DefMacro('\eqnum {}', '\lx@equation@settag{\edef\theequation{#2}\lx@make@tags{equation}}');
#======================================================================
# 2.13 Citations and Bibliography
DefMacro('\markcite{}', ''); # apparently like \cite w/o text?
#======================================================================
# 2.13.1 The thebibliography Environment
# normal LaTeX
#======================================================================
# 2.13.2 Specifying Bibliographic and Citation Information
RequirePackage('natbib');
# \bibitem[author(year)]{key} bibdata...
lib/LaTeXML/Package/aas_support.sty.ltxml view on Meta::CPAN
# 2.14.1 Electronic Art
RequirePackage('graphicx');
# \begin{figure}
# \figurenum{text}
# \epsscale{num}
# \plotone{epsfile}
# \plottwo{epsfile}{epsfile}
# \caption{text}
# \end{figure}
DefMacro('\figurenum{}', '\def\thefigure{#1}');
# Note: This needs an UnRefStepCounter('figure');
# or at least, defer the refstep till late enough to skip if needed?
DefMacro('\epsscale{}', '');
DefMacro('\plotone Semiverbatim', '\includegraphics[width=\textwidth]{#1}');
DefMacro('\plottwo Semiverbatim Semiverbatim',
'\hbox{\includegraphics[width=\textwidth]{#1}\includegraphics[width=\textwidth]{#2}}');
# \plotfiddle{epsfile}{vsize}{rot}{hsf}{vsf}{htrans}{vtrans}
# Ugh...
DefMacro('\plotfiddle Semiverbatim {}{}{}{}{}{}',
'\includegraphics[width=#4pt,height=#5pt]{#1}');
#======================================================================
# 2.14.2 Figure Captions
# For figures added externally; Used at end of file.
# \figcaption[filename]{text\label{key}}
# But sometimes used just like \caption!
DefMacro('\@figcaption {}', '\begin{figure}#1\end{figure}');
# Note that the optional [filename] seems unused, so we just read and drop it.
DefMacro('\figcaption OptionalSemiverbatim', sub {
(((LookupValue('current_environment') || '') =~ 'figure')
? T_CS('\caption') : T_CS('\@figcaption')); });
#======================================================================
# 2.15 Tables
RequirePackage('deluxetable');
Let(T_CS('\planotable'), T_CS('\deluxetable'));
Let(T_CS('\endplanotable'), T_CS('\enddeluxetable'));
DefConditional('\ifcolnumberson');
DefConditional('\ifdeluxedecimals');
DefMacro('\deluxedecimals', '\global\deluxedecimalstrue');
RawTeX('\global\deluxedecimalsfalse');
Let(T_CS('\decimals'), T_CS('\deluxedecimals'));
DefMacro('\colnumbers', ''); # TODO
DefMacro('\deluxedecimalcolnumbers', '\deluxedecimalstrue\colnumbersontrue');
Let(T_CS('\decimalcolnumbers'), T_CS('\deluxedecimalcolnumbers'));
# http://tug.ctan.org/tex-archive/macros/latex/contrib/aastex/sample63.pdf
# decimal alignment, 3.1.2
sub build_d_columns {
$LaTeXML::BUILD_TEMPLATE->addColumn(
before => Tokens(T_CS('\hfill'), T_CS('\aas@start@D@column')),
after => Tokens(T_CS('\aas@end@D@column')));
$LaTeXML::BUILD_TEMPLATE->addColumn(
after => Tokens(T_CS('\hfill')));
return; }
DefColumnType('D', \&build_d_columns);
DefColumnType('d', \&build_d_columns);
DefMacro('\aas@start@D@column XUntil:\aas@end@D@column', sub {
my ($gullet, $n) = @_;
my ($m, $f) = SplitTokens($n, T_OTHER('.'));
return ($f ? (@$m,
T_CS('\@ADDCLASS'), T_BEGIN, T_OTHER('ltx_norightpad'), T_END,
T_CS('\@alignment@align'),
T_CS('\@ADDCLASS'), T_BEGIN, T_OTHER('ltx_noleftpad'), T_END,
T_OTHER('.'), @$f)
: ($n,
T_CS('\@ADDCLASS'), T_BEGIN, T_OTHER('ltx_norightpad'), T_END,
T_CS('\@alignment@align')));
lib/LaTeXML/Package/aas_support.sty.ltxml view on Meta::CPAN
Let(T_CS('\endsplitdeluxetable*'), T_CS('\enddeluxetable*'));
DefColumnType('B', sub { # TODO: fake for now, should break table eventually
$LaTeXML::BUILD_TEMPLATE->addColumn(
before => Tokens(T_BEGIN, T_CS('\eatone')),
after => Tokens(T_CS('\endeatone'), T_END));
return; });
DefEnvironment('{longrotatetable}', '#body');
DefMacro('\phn', '\phantom{0}');
DefMacro('\phd', '\phantom{.}');
DefMacro('\phs', '\phantom{+}');
DefMacro('\phm{}', '\phantom{string}');
#======================================================================
# 2.15.4 The table Environment
# normal LaTeX
#======================================================================
# 2.17 Miscellaneous
#======================================================================
# 2.17.1 Celestial Objects and Data Sets
lib/LaTeXML/Package/aas_support.sty.ltxml view on Meta::CPAN
"<ltx:text class='ltx_ast_objectname'>#2 (catalog #1)</ltx:text>");
Let('\object', '\objectname'); # ???
DefConstructor('\dataset OptionalSemiverbatim {} ',
"<ltx:text class='ltx_ast_dataset'>#2 (catalog #1)</ltx:text>");
#======================================================================
# 2.17.2 Ionic Species and Chemical Bonds
# Note that semantics could be useful!
# \ion{element}{level}
DefMacro('\ion{}{}', '{#1~\expandafter\uppercase\expandafter{\romannumeral #2}}');
# NOTE: These are almost totally wrong...
DefPrimitiveI('\sbond', undef, "\x{2212}");
DefPrimitiveI('\dbond', undef, "=");
DefPrimitiveI('\tbond', undef, "\x{2261}");
#======================================================================
# 2.17.3 Fractions
# \case{1}{2} == textstyle fraction
# AND, apparently allowed in text mode!
DefMacro('\case{}{}', '\ensuremath{\text@frac{#1}{#2}}');
DefConstructor('\text@frac ScriptStyle ScriptStyle',
"<ltx:XMApp>"
. "<ltx:XMTok meaning='divide' role='FRACOP' mathstyle='text'/>"
. "<ltx:XMArg>#1</ltx:XMArg><ltx:XMArg>#2</ltx:XMArg>"
. "</ltx:XMApp>",
sizer => sub { fracSizer($_[0]->getArg(1), $_[0]->getArg(2)); });
Let('\slantfrac', '\case');
#======================================================================
# 2.17.4 Astronomical Symbols
# See aassymbols document.
# Table 1: Additional AASTeX symbols
DefPrimitiveI('\micron', undef, UTF(0xB5) . "m");
DefMacro('\Sun', '\sun');
DefMacro('\Sol', '\sun');
DefPrimitiveI('\sun', undef, "\x{2609}");
DefPrimitiveI('\Mercury', undef, "\x{263F}");
DefPrimitiveI('\Venus', undef, "\x{2640}");
DefMacro('\Earth', '\earth');
DefMacro('\Terra', '\earth');
DefPrimitiveI('\earth', undef, "\x{2295}");
DefPrimitiveI('\Mars', undef, "\x{2642}");
DefPrimitiveI('\Jupiter', undef, "\x{2643}");
DefPrimitiveI('\Saturn', undef, "\x{2644}");
DefPrimitiveI('\Uranus', undef, "\x{2645}");
DefPrimitiveI('\Neptune', undef, "\x{2646}");
DefPrimitiveI('\Pluto', undef, "\x{2647}");
DefPrimitiveI('\Moon', undef, "\x{263D}"); # Not sure if this is the right Moon?
DefMacro('\Luna', '\Moon');
DefPrimitiveI('\Aries', undef, "\x{2648}");
DefMacro('\VEq', '\Aries'); # Vernal Equinox
DefPrimitiveI('\Taurus', undef, "\x{2649}");
DefPrimitiveI('\Gemini', undef, "\x{264A}");
DefPrimitiveI('\Cancer', undef, "\x{264B}");
DefPrimitiveI('\Leo', undef, "\x{264C}");
DefPrimitiveI('\Virgo', undef, "\x{264D}");
DefPrimitiveI('\Libra', undef, "\x{264E}");
DefMacro('\AEq', '\Libra'); # Autumnal Equinox
DefPrimitiveI('\Scorpius', undef, "\x{264F}");
DefPrimitiveI('\Sagittarius', undef, "\x{2650}");
DefPrimitiveI('\Capricornus', undef, "\x{2651}");
DefPrimitiveI('\Aquarius', undef, "\x{2652}");
DefPrimitiveI('\Pisces', undef, "\x{2653}");
DefPrimitiveI('\diameter', undef, "\x{2300}");
DefPrimitiveI('\sq', undef, "\x{25A1}");
DefPrimitiveI('\arcdeg', undef, UTF(0xB0));
Let('\degr', '\arcdeg');
DefPrimitiveI('\arcmin', undef, "\x{2032}");
DefPrimitiveI('\arcsec', undef, "\x{2033}");
DefMacro('\nodata', ' ~$\cdots$~ ');
# 1st arg is the original macro so that it can be the reversion for UnTeX!
# 2nd arg is the superscript
DefConstructor('\aas@@fstack Undigested {}',
"<ltx:XMApp role='POSTFIX'>"
. "<ltx:XMTok role='SUPERSCRIPTOP' scriptpos='#scriptpos'/>"
. "<ltx:XMTok>.</ltx:XMTok>"
. "<ltx:XMWrap>#2</ltx:XMWrap>"
. "</ltx:XMApp>",
properties => { scriptpos => sub { "mid" . $_[0]->getScriptLevel; } },
mode => 'math', font => { shape => 'upright' }, bounded => 1, reversion => '#1');
DefMacro('\aas@fstack{}', '\ensuremath{\aas@@fstack{#1}}');
DefMacro('\fd', '\ensuremath{\@fd}');
DefMacro('\fh', '\ensuremath{\@fh}');
DefMacro('\fm', '\ensuremath{\@fm}');
DefMacro('\fs', '\ensuremath{\@fs}');
DefMacro('\fdg', '\ensuremath{\@fdg}');
DefMacro('\farcm', '\ensuremath{\@farcm}');
DefMacro('\farcs', '\ensuremath{\@farcs}');
DefMacro('\fp', '\ensuremath{\@fp}');
DefMath('\@fd', '\aas@@fstack{\fd}{d}', role => 'ID', meaning => 'day', alias => '\fd');
DefMath('\@fh', '\aas@@fstack{\fh}{h}', role => 'ID', meaning => 'hour', alias => '\fh');
DefMath('\@fm', '\aas@@fstack{\fm}{m}', role => 'ID', meaning => 'minute', alias => '\fm');
DefMath('\@fs', '\aas@@fstack{\fs}{s}', role => 'ID', meaning => 'second', alias => '\fs');
DefMath('\@fdg', '\aas@@fstack{\fdg}{\circ}', role => 'ID', meaning => 'degree', alias => '\fdg');
DefMath('\@farcm', '\aas@@fstack{\farcm}{\prime}', role => 'ID', meaning => 'arcminute', alias => '\farcm');
DefMath('\@farcs', '\aas@@fstack{\farcs}{\prime\prime}', role => 'ID', meaning => 'arcsecond', alias => '\farcs');
DefMath('\@fp', '\aas@@fstack{\fp}{p}');
DefMacro('\onehalf', '\ifmmode\case{1}{2}\else\text@onehalf\fi');
DefPrimitiveI('\text@onehalf', undef, UTF(0xBD));
DefMacro('\onethird', '\ifmmode\case{1}{3}\else\text@onethird\fi');
DefPrimitiveI('\text@onethird', undef, "\x{2153}");
DefMacro('\twothirds', '\ifmmode\case{2}{3}\else\text@twothirds\fi');
DefPrimitiveI('\text@twothirds', undef, "\x{2154}");
DefMacro('\onequarter', '\ifmmode\case{1}{4}\else\text@onequarter\fi');
DefPrimitiveI('\text@onequarter', undef, UTF(0xBC));
DefMacro('\threequarters', '\ifmmode\case{3}{4}\else\text@threequarters\fi');
DefPrimitiveI('\text@threequarters', undef, UTF(0xBE));
DefPrimitiveI('\ubvr', undef, "UBVR", bounded => 1, font => { shape => 'italic' });
DefPrimitiveI('\ub', undef, "U\x{2000}B", bounded => 1, font => { shape => 'italic' });
DefPrimitiveI('\bv', undef, "B\x{2000}V", bounded => 1, font => { shape => 'italic' });
DefPrimitiveI('\vr', undef, "V\x{2000}R", bounded => 1, font => { shape => 'italic' });
DefPrimitiveI('\ur', undef, "U\x{2000}R", bounded => 1, font => { shape => 'italic' });
# Remaining tables standard LaTeX or amssymb
RequirePackage('latexsym');
RequirePackage('amssymb');
# \lesssim,\gtrsim in amssymb
Let('\la', '\lesssim');
Let('\ga', '\gtrsim');
# Nominal Conversion Constants
DefMacro('\nomSolarEffTemp', '\leavevmode\hbox{\boldmath$\mathcal{T}^{\rm N}_{\mathrm{eff}\odot}$}');
DefMacro('\nomTerrEqRadius', '\leavevmode\hbox{\boldmath$\mathcal{R}^{\rm N}_{E\mathrm e}$}');
DefMacro('\nomTerrPolarRadius', '\leavevmode\hbox{\boldmath$\mathcal{R}^{\rm N}_{E\mathrm p}$}');
DefMacro('\nomJovianEqRadius', '\leavevmode\hbox{\boldmath$\mathcal{R}^{\rm N}_{J\mathrm e}$}');
DefMacro('\nomJovianPolarRadius', '\leavevmode\hbox{\boldmath$\mathcal{R}^{\rm N}_{J\mathrm p}$}');
DefMacro('\nomTerrMass', '\leavevmode\hbox{\boldmath$(\mathcal{GM})^{\rm N}_{\mathrm E}$}');
DefMacro('\nomJovianMass', '\leavevmode\hbox{\boldmath$(\mathcal{GM})^{\rm N}_{\mathrm J}$}');
DefMacro('\Qnom', '\leavevmode\hbox{\boldmath$\mathcal{Q}^{\rm N}_{\odot}$}');
Let(T_CS('\Qn'), T_CS('\Qnom'));
# Generic commands that can be given an argument:
DefMacro('\nom{}', '\leavevmode\hbox{\boldmath$\mathcal{#1}^{\rm N}_{\odot}$}');
DefMacro('\Eenom{}', '\leavevmode\hbox{\boldmath$\mathcal{#1}^{\rm N}_{Ee}$}');
DefMacro('\Epnom{}', '\leavevmode\hbox{\boldmath$\mathcal{#1}^{\rm N}_{Ep}$}');
DefMacro('\Jenom{}', '\leavevmode\hbox{\boldmath$\mathcal{#1}^{\rm N}_{Je}$}');
DefMacro('\Jpnom{}', '\leavevmode\hbox{\boldmath$\mathcal{#1}^{\rm N}_{Jp}$}');
#======================================================================
# 2.17.5 Hypertext Constructs
# \anchor{href}{text}
RequirePackage('url');
DefConstructor('\anchor Semiverbatim Semiverbatim',
"<ltx:ref href='#href'>#2</ltx:ref>",
properties => sub { (href => ComposeURL(LookupValue('BASE_URL'), $_[1])); });
lib/LaTeXML/Package/aas_support.sty.ltxml view on Meta::CPAN
"<ltx:ref href='#href'>#1</ltx:ref>",
properties => sub { (href => CleanURL("mailto:" . ToString($_[1]))); });
# RequirePackage('verbatim');
#======================================================================
# 2.18 Concluding
# normal LaTeX
# Number equations within sections
DefMacro('\eqsecnum',
'\@addtoreset{equation}{section}'
. '\def\theequation{\arabic{section}-\arabic{equation}}');
#======================================================================
# Random extra bits
DefMacroI('\singlespace', undef, '');
DefMacroI('\doublespace', undef, '');
DefMacroI('\tighten', undef, '');
DefMacroI('\tightenlines', undef, '');
DefMacroI('\nohyphenation', undef, '');
DefMacroI('\offhyphenation', undef, '');
DefMacroI('\ptlandscape', undef, '');
DefMacroI('\refpar', undef, '');
DefMacroI('\traceoutput', undef, '');
DefMacroI('\tracingplain', undef, '');
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
### These commands requested AAS
DefMacro('\noprint {}', '');
DefMacro('\figsetstart', '{\bf Fig. Set}');
DefMacro('\figsetend', '');
DefMacro('\figsetgrpstart', '');
DefMacro('\figsetgrpend', '');
DefMacro('\figsetnum {}', '{\bf #1.}');
DefMacro('\figsettitle {}', '{\bf #1}');
DefMacro('\figsetgrpnum {}', '');
DefMacro('\figsetgrptitle {}', '');
DefMacro('\figsetplot {}', '');
DefMacro('\figsetgrpnote {}', '');
1;
lib/LaTeXML/Package/accents.sty.ltxml view on Meta::CPAN
# | http://dlmf.nist.gov/LaTeXML/ (o o) | #
# \=========================================================ooo==U==ooo=/ #
package LaTeXML::Package::Pool;
use strict;
use warnings;
use LaTeXML::Package;
#======================================================================
DefMath('\ring{}', "\x{030A}", operator_role => 'OVERACCENT');
DefMacro('\lx@acc@size', '\scriptstyle'); # should be \scriptscriptstyle??
DefMacro('\accentset{}{}', '\lx@overaccentset{#1}{#2}');
DefConstructor('\lx@overaccentset ScriptStyle {}',
"<ltx:XMApp><ltx:XMWrap role='OVERACCENT'>#1</ltx:XMWrap><ltx:XMArg>#2</ltx:XMArg></ltx:XMApp>",
sizer => '#1', # Close enough?
alias => '\accentset');
DefMath('\dddot{}', "\x{02D9}\x{02D9}\x{02D9}",
operator_role => 'OVERACCENT'); # DOT ABOVE
DefMath('\ddddot{}', "\x{02D9}\x{02D9}\x{02D9}\x{02D9}",
operator_role => 'OVERACCENT'); # DOT ABOV
# \underaccent{acc}{base}
# Needs to apply the accent as an under, instead of over!!!!
# But acc can be either an accenting command (like \hat)
# or an arbitrary item to place as an accent!!! How to detect that?
# We'll ASS.U.ME that accent commands take a single arg.
DefMacro('\lx@if@isaccent{}{}{}', sub {
my ($gullet, $thing, $true, $false) = @_;
my ($defn, $params);
my ($token, @rest) = $thing->unlist;
return ((!@rest)
&& ($defn = LookupDefinition($token))
&& ($params = $defn->getParameters)
&& ($params->getNumArgs == 1)
? $true : $false); });
DefMacro('\underaccent{}{}',
'\lx@if@isaccent{#1}{\lx@converttounder{#1}{#2}{#1{#2}}}{\lx@underaccentset{#1}{#2}}');
DefConstructor('\lx@underaccentset ScriptStyle {}',
"<ltx:XMApp><ltx:XMWrap role='UNDERACCENT'>#1</ltx:XMWrap><ltx:XMArg>#2</ltx:XMArg></ltx:XMApp>",
sizer => '#1', # Close enough?
alias => '\underaccent');
DefConstructor('\lx@converttounder Undigested Undigested {}', sub {
my ($document, $ignore1, $ignore2, $thing) = @_;
$document->absorb($thing);
# replace role=OVERACCENT with UNDERACCENT
my $node = $document->getNode->lastChild;
lib/LaTeXML/Package/acmart.cls.ltxml view on Meta::CPAN
RequirePackage('refcount');
RequirePackage('textcase');
RequirePackage('hyperxmp');
#RequirePackage('draftwatermark');
#RequirePackage('cmap');
#RequirePackage('pbalance');
RequirePackage('balance');
#======================================================================
# Various bits of frontmatter
DefMacro('\copyrightyear{}', '\@add@frontmatter{ltx:date}[role=copyright]{#1}');
DefMacro('\setcopyright{}', '\@add@frontmatter{ltx:note}[role=copyright]{#1}');
DefMacro('\received[]{}', '\@add@frontmatter{ltx:date}[role=received]{#2}');
DefMacro('\acmJournal{}', '\@add@frontmatter{ltx:note}[role=journal]{#1}');
DefMacro('\acmSubmissionID{}', '\@add@frontmatter{ltx:note}[role=submissionid]{#1}');
DefMacro('\acmConference[]{}{}{}', '\@add@frontmatter{ltx:note}[role=conference]{#2; #3; #4}');
DefMacro('\acmBooktitle{}', '\@add@frontmatter{ltx:note}[role=booktitle]{#1}');
DefMacro('\acmArticle{}', '\@add@frontmatter{ltx:note}[role=article]{#1}');
DefMacro('\acmArticleSeq{}', '\@add@frontmatter{ltx:note}[role=articleseq]{#1}');
DefMacro('\acmDOI{}', '\@add@frontmatter{ltx:note}[role=doi]{#1}');
DefMacro('\acmISBN{}', '\@add@frontmatter{ltx:note}[role=isbn]{#1}');
DefMacro('\acmMonth{}', '\@add@frontmatter{ltx:note}[role=publicationmonth]{#1}');
DefMacro('\acmNumber{}', '\@add@frontmatter{ltx:note}[role=journalnumber]{#1}');
DefMacro('\acmPrice{}', '\@add@frontmatter{ltx:note}[role=price]{#1}');
DefMacro('\acmVolume{}', '\@add@frontmatter{ltx:note}[role=journalvolume]{#1}');
DefMacro('\acmYear{}', '\@add@frontmatter{ltx:note}[role=journalyear]{#1}');
DefMacro('\editor{}', '\@add@frontmatter{ltx:creator}[role=editor]{\@personname{#1}}');
DefMacro('\subtitle{}', '\@add@frontmatter{ltx:subtitle}{#1}');
DefMacro('\keywords{}', '\@add@frontmatter{ltx:keywords}{#1}');
DefMacro('\terms{}', '\@add@frontmatter{ltx:keywords}{#1}');
# Use multiple style, repeating \author, \orcid, \affiliation, \email as needed.
DefConstructor('\@@@affiliation{}', "^ <ltx:contact role='affiliation'>#1</ltx:contact>");
DefMacro('\affiliation{}', '\@add@to@frontmatter{ltx:creator}{\@@@affiliation{#1}}');
DefConstructor('\@@@addaffiliation{}', "^ <ltx:contact role='additional_affiliation'>#1</ltx:contact>");
DefMacro('\additionalaffiliation{}', '\@add@to@frontmatter{ltx:creator}{\@@@addaffiliation{#1}}');
DefConstructor('\@@@email{}', "^ <ltx:contact role='email'>#1</ltx:contact>");
DefMacro('\email [] Semiverbatim', '\@add@to@frontmatter{ltx:creator}{\@@@email{#2}}');
DefMacro('\orcid Semiverbatim', '\@add@to@frontmatter{ltx:creator}{\@@@orcid{\@@orcid{#1}}}');
DefConstructor('\@@orcid{}', '<ltx:ref title="ORCID identifier" href="https://orcid.org/#1">#1</ltx:ref>');
DefConstructor('\@@@orcid{}', "^ <ltx:contact role='orcid'>#1</ltx:contact>");
# Internal structure to affiliation
DefConstructor('\position{}',
"<ltx:text class='ltx_affiliation_position' _noautoclose='1'>#1</ltx:text>");
DefConstructor('\institution{}',
"<ltx:text class='ltx_affiliation_institution' _noautoclose='1'>#1</ltx:text>");
DefConstructor('\department{}',
"<ltx:text class='ltx_affiliation_department' _noautoclose='1'>#1</ltx:text>");
lib/LaTeXML/Package/acmart.cls.ltxml view on Meta::CPAN
DefConstructor('\city{}',
"<ltx:text class='ltx_affiliation_city' _noautoclose='1'>#1</ltx:text>");
DefConstructor('\state{}',
"<ltx:text class='ltx_affiliation_state' _noautoclose='1'>#1</ltx:text>");
DefConstructor('\postcode{}',
"<ltx:text class='ltx_affiliation_postcode' _noautoclose='1'>#1</ltx:text>");
DefConstructor('\country{}',
"<ltx:text class='ltx_affiliation_country' _noautoclose='1'>#1</ltx:text>");
# Ignorable stuff ?
DefMacro('\shortauthors{}', '');
DefMacro('\titlenote{}', '');
DefMacro('\subtitlenote{}', '');
DefMacro('\authornote{}', '');
DefMacro('\authornotemark[]', '');
DefMacro('\authorsaddresses{}', '');
DefMacro('\startPage', '');
DefMacro('\settopmatter{}', '');
DefMacro('\copyrightpermissionfootnoterule', '');
DefMacro('\acmBadgeL', Tokens());
# DefMacro('\acmBadgeR',Tokens());
# basically use natbib
Let('\citeN', '\cite');
Let('\cite', '\citep');
Let('\citeANP', '\citeauthor');
Let('\citeNN', '\citeyearpar');
Let('\citeyearNP', '\citeyear');
Let('\citeyear', '\citeyearpar');
Let('\citeNP', '\citealt');
DefMacro('\shortcite{}', '\citeyear{#1}');
# ??
Let('\citeA', '\citeauthor');
DefRegister('\fulltextwidth', Dimension(0));
DefEnvironment('{printonly}', '');
DefEnvironment('{screenonly}', '#body');
DefEnvironment('{anonsuppress}', '');
DefMacro('\ccsdesc[]{}', '\@add@frontmatter{ltx:note}[role=ccs]{#2}');
# Could embed this as XML in some namespace, or....
# For now, just skip it.
# DefEnvironment('{CCSXML}','#body');
RequirePackage('comment');
defineExcluded(undef, 'CCSXML');
DefMacro('\acknowledgmentsname', 'Acknowledgements');
DefConstructor('\acks', "<ltx:acknowledgements name='#name'>",
properties => sub { (name => Digest(T_CS('\acknowledgmentsname'))); });
DefConstructor('\endacks', "</ltx:acknowledgements>");
DefMacro('\grantsponsor Semiverbatim {} Semiverbatim', 'Sponsor #2 \url{#3}');
DefMacro('\grantnum OptionalSemiverbatim Semiverbatim {}', 'Grant \##3');
DefEnvironment('{teaserfigure}[]',
"<ltx:figure xml:id='#id' inlist='#inlist' class='ltx_teaserfigure' ?#1(placement='#1')>"
. "#tags"
. "#body"
. "</ltx:figure>",
properties => { layout => 'vertical' },
beforeDigest => sub { beforeFloat('figure'); },
afterDigest => sub { afterFloat($_[1]); });
lib/LaTeXML/Package/acmart.cls.ltxml view on Meta::CPAN
DefEnvironment('{margintable}[]',
"<ltx:table xml:id='#id' inlist='#inlist' class='ltx_margintable' ?#1(placement='#1')>"
. "#tags"
. "#body"
. "</ltx:table>",
properties => { layout => 'vertical' },
beforeDigest => sub { beforeFloat('table'); },
afterDigest => sub { afterFloat($_[1]); });
DefMacroI('\sidebarname', undef, 'Sidebar');
DefMacroI('\fnum@sidebar', undef, '\sidebarname\nobreakspace\thesidebar');
DefMacro('\format@title@sidebar{}', '\lx@tag{\fnum@sidebar: }#1');
DefEnvironment('{sidebar}{} Undigested [] {}',
"<ltx:sidebar labels='#label' xml:id='#id'>"
# . "#tags"
# . "<ltx:title font='#titlefont' _force_font='true'>#title</ltx:title>"
# . "<ltx:creator role='author'><ltx:personname href='#bio'>#4</ltx:personname></ltx:creator>"
. "#body"
. "</ltx:sidebar>");
RawTeX(<<'EoTeX');
lib/LaTeXML/Package/acronym.sty.ltxml view on Meta::CPAN
# |---------------------------------------------------------------------| #
# | Bruce Miller <bruce.miller@nist.gov> #_# | #
# | http://dlmf.nist.gov/LaTeXML/ (o o) | #
# \=========================================================ooo==U==ooo=/ #
package LaTeXML::Package::Pool;
use strict;
use warnings;
use LaTeXML::Package;
#======================================================================
DefMacro('\acsfont{}', '#1');
DefMacro('\acffont{}', '#1');
DefMacro('\acfsfont{}', '#1');
DefConditional('\ifAC@footnote');
DefConditional('\ifAC@nohyperlinks');
DefConditional('\ifAC@printonlyused');
DefConditional('\ifAC@withpage');
DefConditional('\ifAC@smaller');
DefConditional('\ifAC@dua'); # dua = don't use acronmyms
DefConditional('\ifAC@nolist');
DefConditional('\ifAC@starred');
DefMacro('\AC@placelabel{}', '');
#======================================================================
# Whether an acronym is used or not
DefPrimitive('\lx@AC@used{}', sub {
AssignValue('ACROUSED@' . ToString($_[1]) => 1, 'global'); });
DefPrimitive('\AC@logged{}', sub { }); # ???
DefMacro('\acused{}', '\AC@logged{#1}');
DefMacro('\acronymused{}', '\AC@logged{#1}');
DefMacro('\acresetall', ''); # ????
DefMacro('\lx@AC@if{}{}{}', sub {
my ($gullet, $id, $short, $long) = @_;
my $key = 'ACROUSED@' . ToString($_[1]);
if (LookupValue($key)) {
$short->unlist; }
else {
AssignValue($key => 1, 'global');
$long->unlist; } });
#======================================================================
# Acronyms in the Text
# NOTE: replacement of acronyms (short, long, whatever) should EXCLUDE \acroextra
# BUT those should be present in an acronym list!
# Acronym lists can (optionally) only include the acronyms actually used in the text!
# \lx@acronym{acronym}{listname}{showform}
DefConstructor('\lx@acronym Undigested {}{}{}',
"<ltx:glossaryref key='#2' inlist='#3' show='#4'/>",
reversion => '#1{#2}');
DefMacro('\AC@acs{}', '\lx@acronym{\acs}{#1}{acronym}{short}');
DefMacro('\AC@acl{}', '\lx@acronym{\acl}{#1}{acronym}{long}');
DefMacro('\AC@acsp{}', '\lx@acronym{\acsp}{#1}{acronym}{short-plural}');
DefMacro('\AC@aclp{}', '\lx@acronym{\aclp}{#1}{acronym}{long-plural}');
DefMacro('\AC@acsi{}', '\lx@acronym{\acsi}{#1}{acronym}{short-indefinite}');
DefMacro('\AC@aclI{}', '\lx@acronym{\aclI}{#1}{acronym}{long-indefinite}');
# Short form
DefMacro('\acs OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\acsa');
DefMacro('\acsa{}', '\@acs{#1}');
DefMacro('\@acs{}', '\acsfont{\AC@acs{#1}}\ifAC@starred\else\AC@logged{#1}\fi');
# Long form
DefMacro('\acl OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\@acl');
DefMacro('\@acl{}', '\acsfont{\AC@acl{#1}}\ifAC@starred\else\AC@logged{#1}\fi');
# Full form: Long (short)
DefMacro('\acf OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\acfa');
DefMacro('\acfa{}', '\@acf{#1}');
DefMacro('\@acf{}',
'\ifAC@footnote\acsfont{\AC@acs{#1}}\footnote{\AC@placelabel{#1} \AC@acl{#1}}
\else\acffont{\AC@placelabel{#1} \AC@acl{#1} \acfsfont{(\acsfont{\AC@acs{#1}})}}\fi
\ifAC@starred\else\lx@AC@used{#1}\fi');
# Italicized long (short)
DefMacro('\acfi OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\acfia');
DefMacro('\acfia{}', '{\itshape\AC@acl{#1} }(\ifAC@starred\acs*{#1}\else\acs{#1}\fi)');
# Auto form
DefMacro('\ac OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\@ac');
DefMacro('\@ac{}',
'\lx@AC@if{#1}{\ifAC@starred\acs*{#1}\else\acs{#1}\fi}{\ifAC@starred\acf*{#1}\else\acf{#1}\fi}');
# Indefinite article form
DefMacro('\iac OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\@iac');
DefMacro('\Iac OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\@Iac');
DefMacro('\@iac{}', '\@iaci{#1} \ifAC@starred\ac*{#1}\else\ac{#1}\fi');
DefMacro('\@Iac{}', '\@firstupper{\@iaci{#1}} \ifAC@starred\ac*{#1}\else\ac{#1}\fi');
# \@firstupper
# \newcommand*{\@iaci}[1]{%
# \ifcsname fn@#1@IL\endcsname
# \ifAC@dua
# \csname fn@#1@IL\endcsname%
# \else
# \expandafter\ifx\csname ac@#1\endcsname\AC@used%
# \csname fn@#1@IS\endcsname%
# \else
# \csname fn@#1@IL\endcsname%
# \fi
# \fi
# \else
# a%
# \fi
# Plural forms
DefMacro('\acsp OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\acspa');
DefMacro('\acspa{}', '\@acsp{#1}');
DefMacro('\@acsp{}', '\acsfont{\AC@acsp{#1}}\ifAC@starred\else\AC@logged{#1}\fi');
DefMacro('\aclp OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\@aclp');
DefMacro('\@aclp{}', '\AC@aclp{#1}\ifAC@starred\else\AC@logged{#1}\fi');
DefMacro('\acfp OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\acfpa');
DefMacro('\acfpa{}', '\@acfp{#1}');
DefMacro('\@acfp{}',
'\ifAC@footnote\acsfont{\AC@acsp{#1}}\footnote{\AC@placelabel{#1} \AC@aclp{#1}}
\else\acffont{\AC@placelabel{#1} \AC@aclp{#1} \acfsfont{(\acsfont{\AC@acsp{#1}})}}\fi
\ifAC@starred\else\AC@logged{#1}\fi');
DefMacro('\acp OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\@acp');
DefMacro('\@acp{}', '\lx@AC@if{#1}{\AC@acsp{#1}}{\AC@aclp{#1}}\ifAC@starred\else\AC@logged{#1}\fi');
DefMacro('\acsu OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\acsua');
DefMacro('\acsua{}', '\ifAC@starred\acs*{#1}\else\acs{#1}\fi\acused{#1}');
DefMacro('\aclu OptionalMatch:*', '\ifx.#1.\AC@starredfalse\else\AC@starredtrue\fi\aclua');
DefMacro('\aclua{}', '\ifAC@starred\acl*{#1}\else\acl{#1}\fi\acused{#1}');
#======================================================================
# Defining Acronyms
DefEnvironment('{acronym}[]',
"<ltx:glossary lists='acronym' class='ltx_acronym'>"
. "<ltx:glossarylist>"
. "#body"
. "</ltx:glossarylist>"
. "</ltx:glossary>",
beforeDigest => sub { Let('\acro', '\lx@acro@item');
Let('\acrodef', '\lx@acro@item'); },
afterDigest => sub { noteBackmatterElement($_[1], 'ltx:glossary'); },
beforeConstruct => sub { adjustBackmatterElement($_[0], $_[1]); });
DefMacro('\acroextra{}', '#1');
# \lx@acro@item{key}{short}{long}
DefMacro('\lx@acro@item{}[]{}',
'\lx@acro@@item{#1}{\ifx.#2.#1\else#2\fi}{#3}');
DefMacro('\lx@acro@@item{}{}{}',
'\lx@acro@@@item{#1}{#2}{#3}{{\let\acroextra\@gobble #2}}{{\let\acroextra\@gobble #3}}');
DefConstructor('\lx@acro@@@item{}{}{}{}{}',
"<ltx:glossaryentry inlist='acronym' key='#1'>"
. "<ltx:glossaryphrase role='label'>#2</ltx:glossaryphrase>"
. "<ltx:glossaryphrase role='short'>#4</ltx:glossaryphrase>"
. "<ltx:glossaryphrase role='long'>#5</ltx:glossaryphrase>"
. "<ltx:glossaryphrase role='definition'>#3</ltx:glossaryphrase>"
. "</ltx:glossaryentry>");
Tag('ltx:glossaryentry', afterClose => sub { GenerateID(@_, ''); });
DefMacro('\acrodef{}[]{}',
'\lx@acro@@def{#1}{\ifx.#2.#1\else#2\fi}{#3}');
DefMacro('\lx@acro@@def{}{}{}',
'\lx@acro@@@def{#1}{#2}{#3}{{\let\acroextra\@gobble #2}}{{\let\acroextra\@gobble #3}}');
DefConstructor('\lx@acro@@@def{}{}{}{}{}',
"<ltx:glossarydefinition inlist='acronym' key='#1'>"
. "<ltx:glossaryphrase role='label'>#2</ltx:glossaryphrase>"
. "<ltx:glossaryphrase role='short'>#4</ltx:glossaryphrase>"
. "<ltx:glossaryphrase role='long'>#5</ltx:glossaryphrase>"
. "<ltx:glossaryphrase role='definition'>#3</ltx:glossaryphrase>"
. "</ltx:glossarydefinition>");
Tag('ltx:glossarydefinition', afterClose => sub { GenerateID(@_, ''); });
# Should these be allowed inside ltx:glossarylist, or float outside it?
Let('\newacro', '\acrodef');
Let('\acro', '\acrodef');
# The following define additional forms of the acronym expansions.
# They should be recorded in the document & scanned in post-processing,
# but need not appear within the acronym glossary.
# Non-standard definite articles
DefMacro('\lx@acro@phrase{}{}{}', '{\let\acroextra\@gobble\lx@@acro@phrase{#1}{#2}{#3}}');
# Let this float up, since it can be used within a glossarylist, but shouldn't end up there.
DefConstructor('\lx@@acro@phrase{}{}{}',
"^ <ltx:glossarydefinition inlist='acronym' key='#1'>"
. "<ltx:glossaryphrase role='#2'>#3</ltx:glossaryphrase>"
. "</ltx:glossarydefinition>");
DefMacro('\acrodefindefinite{}{}{}',
'\lx@acro@phrase{#1}{short-indefinite}{#2}\lx@acro@phrase{#1}{long-indefinite}{#3}');
Let('\acroindefinite', '\acrodefindefinite');
Let('\newacroindefinite', '\acrodefindefinite');
# Non-standard plural forms
DefMacro('\acrodefplural{}[]{}',
'\lx@acro@phrase{#1}{short-plural}{\ifx.#2.#1\else#2\fi}\lx@acro@phrase{#1}{long-plural}{#3}');
Let('\acroplural', '\acrodefplural');
Let('\newacroplural', '\acrodefplural');
#======================================================================
1;
lib/LaTeXML/Package/adjustbox.sty.ltxml view on Meta::CPAN
# (undoubtedly more needed)
# and, of course, not all directives have an effect...
# Some Issues:
# * some resizing combos set BOTH size & scale; does that double the effect?
# * some constructs are creating ltx:inline-block,
# when *sometimes* they should just create ltx:text; Can we detect when???
# collectbox's approach to starting a block for environments isn't quite working; Force a \par
Let('\lx@save@@adjustbox', '\@adjustbox');
DefMacro('\@adjustbox', '\ifcollectboxenv\par\fi\lx@save@@adjustbox');
# Redefined so the frame contains \BOXCONTENT, rather than (attempted) \hskip overlap
# \adjbox@@frame{setframecolor}{fboxrule}{fboxsep}{???}
DefMacro('\adjbox@@frame{}{}{}{}',
'\ifx\@nnil#2\@nnil\else\adjsetlength\fboxrule{#2}\fi'
. '\ifx\@nnil#3\@nnil\else\adjsetlength\fboxsep{#3}\fi'
. '\@framebox{\BOXCONTENT}');
# Since adjustbox is adapting the already digested content in \BOXCONTENT,
# and we encode color & bgcolor in the font, which is already incorporated into the box
# we need to RE-digest the box, to apply the changed color!
DefMacro('\@bgcolorbox{}', '{\let\color\pagecolor\hbox{#1\lx@RE@BOXCONTENT}}');
DefPrimitive('\lx@RE@BOXCONTENT', sub {
if (my $cbox = LookupRegister(T_CS('\collectedbox'))) {
if (my $box = LookupValue('box' . $cbox->valueOf)) {
return Digest(Tokens(Revert($box))); } }
return; });
1;
lib/LaTeXML/Package/aipproc.cls.ltxml view on Meta::CPAN
RequirePackage('calc');
RequirePackage('varioref');
RequirePackage('times');
RequirePackage('graphicx');
RequirePackage('textcomp');
RequirePackage('url');
RequirePackage('textcase');
RequirePackage('natbib');
#======================================================================
# Frontmatter
DefMacro('\layoutstyle{}', '');
# keywords: address, altaddress, email
DefMacro('\author{} RequiredKeyVals', sub {
my ($gullet, $author, $kvx) = @_;
my $kv = GetKeyVals($kvx);
my @stuff = (Invocation(T_CS('\lx@author'), $author));
if (my $addr = $$kv{address}) {
push(@stuff, Invocation(T_CS('\lx@contact', T_OTHER('address'), $addr))); }
if (my $altaddr = $$kv{altaddress}) {
push(@stuff, Invocation(T_CS('\lx@contact', T_OTHER('altaddress'), $altaddr))); }
if (my $email = $$kv{email}) {
push(@stuff, Invocation(T_CS('\lx@contact', T_OTHER('email'), $email))); }
return Tokens(@stuff); });
DefMacroI('\keywordsname', undef, 'Keywords');
DefMacro('\keywords{}', '\@add@frontmatter{ltx:keywords}[name={\keywordsname}]{#1}');
DefMacro('\classification{}', '\@add@frontmatter{ltx:classification}{#1}');
DefEnvironment('{theacknowledgments}', "<ltx:acknowledgements>#body</ltx:acknowledgements>");
#======================================================================
DefConstructor('\eqref Semiverbatim', "(<ltx:ref labelref='#label' _force_font='true'/>)",
properties => sub { (label => CleanLabel($_[1])); });
#======================================================================
DefMacro('\source{}', '\lx@note{source}{#1}');
DefMacro('\spaceforfigure{}{}', '');
DefMacro('\tablehead {}{}{}{}', '\multicolumn{#1}{#2}{\parbox{#3}{#4}}');
DefMacro('\tablenote OptionalMatch:* {}', '\footnote{#1}');
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1;
lib/LaTeXML/Package/aipproc.sty.ltxml view on Meta::CPAN
use LaTeXML::Package;
RequirePackage('revtex3_support');
# actually, unlock text when used through here,
# see arXiv:astro-ph/0003282
AssignValue("\\text:locked" => undef, 'global');
RequirePackage('longtable');
RequirePackage('psfig');
DefMacro('\lefthead{}', ''); # Obsolete form
DefMacro('\righthead{}', ''); # Obsolete form
1;
lib/LaTeXML/Package/algorithm2e.sty.ltxml view on Meta::CPAN
# The naive (and clever attempts) to reproduce the behaviour w/o true modes,
# always results in blank (but numbered!) lines.
#
# The alternative, to implement the package completely from scratch,
# is undesirable since we'd have to duplicate all the command definitions,
# languages, etc.
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
RequirePackage('float');
#DefMacro('\algocf@new@command DefToken', '\renewcommand{#1}', locked => 1);
# To start, load algorithm2e...
# BUT! the stock algorithm2e is in latin1 encoding!
# We probably don't handle encodings entirely correctly,
# but (eg using turkish along with \usepackage[utf8]{inputenc})
# this can cause problems even for regular latex!
my $saved_encoding = LookupValue('PERL_INPUT_ENCODING');
AssignValue(PERL_INPUT_ENCODING => 'latin1');
InputDefinitions('algorithm2e', type => 'sty', noltxml => 1);
AssignValue(PERL_INPUT_ENCODING => $saved_encoding);
Let('\@mathsemicolon', '\;');
#NewCounter('algorithm');
NewCounter('algorithm', ToString(Digest(T_CS('\algocf@within'))));
RawTeX(<<'EoTeX');
\expandafter\ifx\csname algocf@within\endcsname\relax
\else\def\thealgorithm{\csname the\algocf@within\endcsname.\@arabic\c@algorithm}\fi
EoTeX
DefMacro('\fnum@algorithm', '\algorithmcfname\nobreakspace\thealgorithm');
DefMacro('\fnum@font@algorithm', '\bf');
DefMacro('\ext@algorithm', 'loa');
# {algorithm*}: same as {algorithm}, but used in a two columns text, so just map to original
for my $env (qw(algorithm2e algorithm algorithm*)) {
DefEnvironment("{$env}[]",
"<ltx:float xml:id='#id' class='ltx_algorithm'>"
. "#tags"
. "<ltx:listing class='ltx_lst_numbers_left'>"
. "<ltx:listingline>"
. "#body"
. "</ltx:listingline>"
lib/LaTeXML/Package/algorithm2e.sty.ltxml view on Meta::CPAN
DigestIf(T_CS('\algocf@linesnumbered'));
Let('\par', '\lx@algo@par');
Let('\parbox', '\lx@algo@parbox');
Let("\\\\", '\lx@algo@par');
Let('\strut', '\lx@algo@strut');
# AssignCatcode("\r" => CC_SPACE); # NOT CC_EOL, so newlines don't turn to \par!
# AssignCatcode("\r" => 13);
# Let(T_ACTIVE("\r"), '\relax'); # More appropriate than \par, I think?
# Let('\vtop','\relax'); # ?
DefMacro('\;', '\ifmmode\@mathsemicolon\else\@endalgoln\fi');
beforeFloat('algorithm');
},
afterDigest => sub {
if (ToString(DigestIf(T_CS('\algocf@style'))) =~ /box/) {
$_[1]->setProperty(frame => 'boxed'); }
afterFloat($_[1]); },
afterConstruct => sub { addFloatFrames($_[0], $_[1]->getProperty('frame')); }
);
}
DefMacro('\lx@algo@parbox[]{}{}', '#3');
# NEUTRALIZE most \par's that are built into agorythmic2e
DefMacro('\lx@algo@strut SkipMatch:\par', '');
#####DefMacro('\@marker{}',' \textit{#1} ');
DefMacro('\@marker{}', ''); # Debugging!
DefMacro('\lx@algo@par', '\@marker{PREPAR}\lx@algo@endline\lx@algo@startline\@marker{PAR}');
#DefMacro('\lx@algo@pars', '\@marker{PREPARs}\lx@algo@endline\lx@algo@startline \@marker{PARs}');
DefMacro('\lx@algo@parx', '\@marker{PREPARx}\lx@algo@endline\lx@algo@startline \@marker{PARx}');
DefMacro('\lx@algo@parb', '\@marker{PREPARb}\lx@algo@endline\lx@algo@startline \@marker{PARb}');
####\let\par\relax
DefConditional('\if@lx@algo@par SkipSpaces', sub { $STATE->getPrefix('didpar'); });
DefPrimitiveI('\lx@algo@setpar', undef, sub { $STATE->setPrefix('didpar'); return; }, isPrefix => 1);
DefMacro('\lx@algo@newpar{}{}', '\if@lx@algo@par\@marker{SKIP#1}\else\@marker{pre#1 }#2\@marker{post#1}\fi\lx@algo@setpar');
DefMacro('\lx@algo@par', '\lx@algo@newpar{PAR}{\lx@algo@endline\lx@algo@startline}');
#DefMacro('\lx@algo@pars', '\lx@algo@newpar{PARs}{\lx@algo@endline\lx@algo@startline}');
DefMacro('\lx@algo@parx', '\lx@algo@newpar{PARx}{\lx@algo@endline\lx@algo@startline}');
DefMacro('\lx@algo@parb', '\lx@algo@newpar{PARb}{\lx@algo@endline\lx@algo@startline}');
DefMacro('\algocf@Vline{}', '\lx@algo@endline\lx@algo@startline \@marker{V.L}\lx@algo@advline \lx@strippar{#1}\lx@algo@pop@indentation \@marker{ENDVLINE}');
DefMacro('\algocf@Vsline{}', '\lx@algo@endline\lx@algo@startline \@marker{VsL}\lx@algo@advline \lx@strippar{#1}\lx@algo@pop@indentation \@marker{ENDVsLINE}');
DefMacro('\algocf@Noline{}', '\lx@algo@endline\lx@algo@startline \@marker{NoL}\lx@algo@advlevel \lx@strippar{#1} \@marker{ENDNoLINE}');
#DefMacro('\@endalgocfline', 'EOL');
DefMacro('\algocf@endline', sub {
return LookupValue('algorithm_dont_print_semicolon') ? () : (T_OTHER(';')); },
locked => 1);
#DefMacro('\lx@algo@lastpar', 'PRELASTPAR\the\everypar\lx@algo@@endline');
#DefMacro('\@endalgoln', '\@endalgocfline\lx@algo@par');
DefMacro('\@endalgoln', '\@endalgocfline');
#DefMacro('\@endalgocfline', '\algocf@endline\@marker{EOL}\lx@algo@par\let\lx@algo@parx\relax');
DefMacro('\@endalgocfline', '\algocf@endline\@marker{EOL}\lx@algo@par');
DefMacro('\PrintSemicolon', sub {
AssignValue('algorithm_dont_print_semicolon', 0, 'global');
return (); }, locked => 1);
DefMacro('\DontPrintSemicolon', sub {
AssignValue('algorithm_dont_print_semicolon', 1, 'global');
return (); }, locked => 1);
# Annoying: sometimes these are ended by authors \; (which ends the line)
# sometimes the author omits that.
# And sometimes the enclosing caller appends a \par afterwards!
# So, how to we assure that we end the line ONLY ONCE!
DefMacro('\lx@strippar{}', sub {
my ($gullet, $tokens) = @_;
my @tokens = $tokens->unlist;
# return (@tokens,T_CS('\lx@algo@parx'));
return (@tokens, T_CS('\lx@algo@parx'), T_CS('\lx@algo@parx'), T_CS('\lx@algo@parx')); });
#DefMacro('\algocf@@@block{}{}','#1\bgroup\lx@algo@startline#2\lx@algo@endline\egroup');
#DefMacro('\algocf@@@block{}{}','BLOCK:#1ENDBLOCK END#2');
#DefMacro('\algocf@group{}','#1\bgroup\typeout{Block:#1}\egroup');
DefMacro('\algocf@group{}', '\@marker{GRP} #1 \@marker{ENDGRP}');
#DefMacro('\algocf@group{}', '\lx@prepend@indentation GRP #1 ENDGRP');
#DefMacro('\algocf@@@block{}{}','BLK #1 ENDBLOCK END#2 ENDEND\par');
#DefMacro('\algocf@@@block{}{}', '\@marker{BLK} #1 \@marker{ENDBLOCK}\lx@algo@parb\@marker{END}#2\@marker{ENDEND}\lx@algo@parb');
DefMacro('\algocf@@@block{}{}', '\@marker{BLK} #1 \@marker{ENDBLOCK}\@marker{END}#2\@marker{ENDEND}\lx@algo@parb');
#DefMacro('\algocf@@@block{}{}', '\lx@prepend@indentation BLK #1 ENDBLOCK END#2 ENDEND\par');
DefRegister('\lx@algo@indentation' => Tokens());
DefMacro('\lx@algo@push@indentation{}',
'\expandafter\lx@algo@indentation\expandafter{\the\lx@algo@indentation#1}');
DefMacro('\lx@algo@pop@indentation', sub {
my @toks = LookupRegister('\lx@algo@indentation')->unlist;
pop(@toks);
AssignRegister('\lx@algo@indentation', Tokens(@toks));
return; });
DefMacro('\lx@algo@advlevel', '\lx@algo@push@indentation{\lx@algo@indent}');
DefMacro('\lx@algo@advline', '\lx@algo@push@indentation{\lx@algo@indentline}');
#DefMacro('\lx@algo@startline', '\lx@algo@@startline\the\lx@algo@indentation');
DefMacro('\lx@algo@startline', '\lx@algo@@startline');
DefMacro('\lx@algo@endline', '\lx@prepend@indentation\the\everypar\lx@algo@@endline');
#DefMacro('\lx@algo@startline', '\bgroup\lx@algo@@startline');
#DefMacro('\lx@algo@endline', '\lx@prepend@indentation\the\everypar\lx@algo@@endline\egroup');
DefMacro('\lx@algo@indent', '\hskip\skiprule\hskip\skiptext');
DefMacro('\lx@algo@indentline', '\hskip\skiprule\lx@algo@rule\hskip\skiptext');
DefConstructor('\lx@algo@rule', "<ltx:rule width='1px' height='100%'/>");
DefConstructor('\lx@algo@@startline', "<ltx:listingline xml:id='#id' refnum='#refnum'>"
. "?&defined(#refnum)(<ltx:tags><ltx:tag>#refnum</ltx:tag></ltx:tags>)()",
properties => sub {
# RefStepCounter('AlgoLine'); # ?
my $refnum = Digest(T_CS('\theAlgoLine'));
my $id = Digest(T_CS('\theAlgoLine@ID'));
# (id => $id, refnum => $refnum); }
(); }
);
DefConstructor('\lx@algo@@endline', "</ltx:listingline>");
# DefConstructor('\lx@algo@@startline Digested',
# "<ltx:listingline xml:id='#id' refnum='#refnum'>#body</ltx:listingline>");
DefConstructor('\algocf@printnl{}', "<ltx:tags>ltx:tag>#1</ltx:tag></ltx:tags>");
DefMacro('\lx@prepend@indentation',
'\lx@prepend@indentation@{\the\lx@algo@indentation}');
DefConstructor('\lx@prepend@indentation@{}', sub {
my ($doc, $indentation) = @_;
# PREPEND an <ltx:tag> to the current ltx:listingline
my $savenode = $doc->floatToElement('ltx:tags');
my $line = $doc->getNode;
my @oldcontent = $line->childNodes;
map { $line->removeChild($_) } @oldcontent; # Remove old content
$doc->absorb($indentation);
map { $line->appendChild($_) } @oldcontent; # put old content back.
lib/LaTeXML/Package/algorithmic.sty.ltxml view on Meta::CPAN
# (deeply incompatible)
if (IsDefined(T_CS('\algorithmic'))) {
Warn("unexpected", "\\algorithmic",
"Another package has already defined \\algorithmic, will not load algorithmic.sty");
return 1; }
# Read in the LaTeX definitions and redefine a few things strategically.
InputDefinitions('algorithmic', type => 'sty', noltxml => 1);
Let('\lx@orig@algorithmic', '\algorithmic');
DefMacro('\algorithmic', '\lx@setup@algorithmic\lx@orig@algorithmic');
DefPrimitive('\lx@setup@algorithmic', sub {
ResetCounter('ALC@line');
# If we are not within an algorithm environment, step the counter for its id's
if (!grep { $_ eq 'algorithm'; } $STATE->lookupStackedValues('current_environment')) {
RefStepID('algorithm'); }
Let('\list', '\lx@algorithmic@beginlist');
Let('\endlist', '\lx@algorithmic@endlist');
Let('\item', '\lx@algorithmic@item');
Let('\hfill', '\lx@algorithmic@hfill');
});
lib/LaTeXML/Package/algorithmic.sty.ltxml view on Meta::CPAN
DefConstructor('\lx@algorithmic@beginlist{}{}', "<ltx:listing>",
beforeConstruct => sub { $_[0]->maybeCloseElement('ltx:p'); },
afterDigest => sub { Let('\list', '\lx@algorithmic@beginlist@inner'); }); # NOT nested list!
DefConstructor('\lx@algorithmic@endlist', "</ltx:listing>",
beforeConstruct => sub { $_[0]->maybeCloseElement('ltx:listingline'); });
DefConstructor('\lx@algorithmic@beginlist@inner{}{}', "",
afterDigest => sub { Let('\endlist', '\relax'); }); # NOT nested list!
DefMacro('\lx@algorithmic@item OptionalUndigested',
'\lx@algorithmic@item@@ [#1]\hskip\ALC@tlm\relax');
# This imitates \item; just opens the ltx:listingline, but somebody's got to close it.
DefConstructor('\lx@algorithmic@item@@ OptionalUndigested',
"<ltx:listingline xml:id='#id' itemsep='#itemsep'>"
. "#tags",
properties => sub {
my $id = Digest(T_CS('\theALC@line@ID'));
my $tags = Digest(Invocation(T_CS('\lx@make@tags'), T_OTHER('ALC@line')));
(id => $id, tags => $tags); },
beforeConstruct => sub { $_[0]->maybeCloseElement('ltx:listingline'); });
NewCounter('algorithm', undef, idprefix => 'alg');
NewCounter('ALC@line', 'algorithm', idprefix => 'l'); # Assuming we're inside an {algorithm}!
DefMacro('\fnum@ALC@line', '\ALC@lno');
# Hopefully this will only get used for right justifying a comment;
# the ltx:text should autoclose at end of line?
DefConstructor('\lx@algorithmic@hfill',
"<ltx:text cssstyle='float:right'>");
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1;
lib/LaTeXML/Package/algorithmicx.sty.ltxml view on Meta::CPAN
# (deeply incompatible)
if (IsDefined(T_CS('\algorithmic'))) {
Warn("unexpected", "\\algorithmic",
"Another package has already defined \\algorithmic, will not load algorithmicx.sty");
return 1; }
# Load core, make a few redefinitions
InputDefinitions('algorithmicx', type => 'sty', noltxml => 1);
Let('\lx@orig@algorithmic', '\algorithmic');
DefMacro('\algorithmic', '\lx@setup@algorithmicx\lx@orig@algorithmic');
DefPrimitive('\lx@setup@algorithmicx', sub {
ResetCounter('ALG@line');
# If we are not within an algorithm environment, step the counter for its id's
if (!grep { $_ eq 'algorithm'; } $STATE->lookupStackedValues('current_environment')) {
RefStepID('algorithm'); }
Let('\list', '\lx@algorithmicx@beginlist');
Let('\endlist', '\lx@algorithmicx@endlist');
Let('\item', '\lx@algorithmicx@item');
Let('\hfill', '\lx@algorithmicx@hfill');
});
# IGNORE \list 1st arg (we'll handle counter stepping in \item)
DefMacro('\lx@algorithmicx@beginlist{}{}', '\lx@algorithmicx@beginlist@{#2}');
DefConstructor('\lx@algorithmicx@beginlist@{}', "<ltx:listing>");
DefConstructor('\lx@algorithmicx@endlist', "</ltx:listing>",
beforeConstruct => sub { $_[0]->maybeCloseElement('ltx:listingline'); });
# Empty lines still get an \item, but they're followed by \nointerlineskip!
# We do NOT want to generate a listingline in those cases.
# (but this seems a little brittle?)
DefMacro('\lx@algorithmicx@item []',
'\@ifnextchar\nointerlineskip{}{\lx@algorithmicx@@item}');
# This imitates \item; just opens the ltx:listingline, but somebody's got to close it.
DefConstructor('\lx@algorithmicx@@item',
"<ltx:listingline xml:id='#id' itemsep='#itemsep'>"
. "#tags",
properties => sub {
my $step = Digest(T_BEGIN, T_CS('\ALG@step'), T_END); # returns formatted line number
my $id = Digest(T_CS('\theALG@line@ID'));
my $tags = Digest(T_BEGIN,
lib/LaTeXML/Package/algorithmicx.sty.ltxml view on Meta::CPAN
# BUT algorithm package isn't required, so define it here!
NewCounter('algorithm', undef, idprefix => 'alg');
NewCounter('ALG@line', 'algorithm', idprefix => 'l'); # Assuming we're inside an {algorithm}!
# Hopefully this will only get used for right justifying a comment;
# the ltx:text should autoclose at end of line?
DefConstructor('\lx@algorithmicx@hfill',
"<ltx:text cssstyle='float:right'>");
# Protect against obsolete versions of algorithmicx source
DefMacro('\ALG@g{}', '');
DefMacro('\endALG@g', '');
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1;
lib/LaTeXML/Package/ams_support.sty.ltxml view on Meta::CPAN
# amssymb,
# amsmidx for multiple-indexes,
# graphicx,
# longtable,
# upref makes references upcase?, upright?
# xypic,
# #======================================================================
# # Sec. 4. Top Matter
# # FrontMatter:
DefMacro('\shorttitle{}', '\@add@frontmatter{ltx:toctitle}{#1}');
DefMacro('\shortauthor{}', Tokens()); # Not useful?
DefMacro('\authors{}', Tokens());
DefMacro('\shortauthors{}', Tokens());
DefMacro('\addresses{}', Tokens());
DefMacro('\publname{}', Tokens());
DefMacro('\publname{}', Tokens());
DefMacro('\title[]{}',
'\if.#1.\else\def\shorttitle{#1}\@add@frontmatter{ltx:toctitle}{#1}\fi'
. '\@add@frontmatter{ltx:title}{#2}');
DefMacro('\lx@author@sep', ',\ ');
DefMacro('\lx@author@conj', '\ and\ '); # \@@and
DefMacro('\author[]{}',
'\if.#1.\else\def\shortauthor{#1}\fi'
. '\def\@author{#2}\lx@author{#2}');
DefMacroI('\datename', undef, '\textit{Date}:');
DefMacro('\contrib[]{}',
'\@add@frontmatter{ltx:creator}[role=contributor]{\@personname{#2}}');
DefMacro('\commby{}',
'\@add@frontmatter{ltx:creator}[role=communicator]{\@personname{#1}}');
DefConstructor('\@@@address{}', "^ <ltx:contact role='address'>#1</ltx:contact>");
DefMacro('\address[]{}', '\@add@to@frontmatter{ltx:creator}{\@@@address{#2}}');
DefConstructor('\@@@curraddr{}', "^ <ltx:contact role='current_address'>#1</ltx:contact>");
DefMacro('\curraddr{}', '\@add@to@frontmatter{ltx:creator}{\@@@curraddr{#1}}');
DefConstructor('\@@@email{}', "^ <ltx:contact role='email'>#1</ltx:contact>");
DefMacro('\email[]{}', '\@add@to@frontmatter{ltx:creator}{\@@@email{#2}}');
DefConstructor('\@@@urladdr{}', "^ <ltx:contact role='url'>#1</ltx:contact>");
DefMacro('\urladdr{}', '\@add@to@frontmatter{ltx:creator}{\@@@urladdr{#1}}');
DefConstructor('\@@@dedicatory{}', "^ <ltx:contact role='dedicatory'>#1</ltx:contact>");
DefMacro('\dedicatory{}', '\@add@to@frontmatter{ltx:creator}{\@@@dedicatory{#1}}');
# \date{}
DefMacro('\dateposted{}', '\@add@frontmatter{ltx:date}[role=posted]{#1}');
# \thanks{} ( == ack, not latex's \thanks, not in author)
# make a throwaway optional argument available for OmniBus use
DefMacro('\thanks[]{}',
'\@add@frontmatter{ltx:acknowledgements}[name={\@ifundefined{thanksname}{}{\thanksname}}]{#2}');
DefMacro('\translator[]{}',
'\@add@frontmatter{ltx:creator}[role=translator]{\@personname{#2}}');
DefMacroI('\keywordsname', undef, 'Key words and phrases');
DefMacro('\keywords{}',
'\@add@frontmatter{ltx:keywords}[name={\keywordsname}]{#1}');
# Non-standard but makes it easier to create bindings for variations on AMS classes;
# just redefine this macro
DefMacroI('\@subjclassyear', undef, '1991');
DefMacroI('\subjclassname', undef, '\textup{\@subjclassyear} Mathematics Subject Classification');
DefMacro('\subjclass[Default:\@subjclassyear]{}',
'\ifx.#1.\else\xdef\@subjclassyear{#1}\fi'
. '\@add@frontmatter{ltx:classification}[scheme={#1 Mathematics Subject Classification},'
. 'name={\subjclassname}]{#2}');
DefMacro('\copyrightinfo{}{}',
'\@add@frontmatter{ltx:note}[role=copyright]{\copyright #1: #2}');
DefMacro('\pagespan{}{}', ''); # ?
DefMacro('\PII{}',
'\@add@frontmatter{ltx:classification}[scheme=PII]{#1}');
DefMacro('\ISSN{}',
'\@add@frontmatter{ltx:classification}[scheme=ISSN]{#1}');
DefMacroI('\currentvolume', undef, Tokens());
DefMacroI('\currentissue', undef, Tokens());
DefMacroI('\currentmonth', undef, Tokens());
DefMacroI('\currentyear', undef, Tokens());
DefMacroI('\volinfo', undef, Tokens());
DefMacro('\issueinfo{}{}{}{}',
'\def\currentvolume{#1}\def\currentissue{#2}\def\currentmonth{#3}\def\currentyear{#4}'
. '\def\volinfo{Volume \currentvolume, Number \number0\currentissue, \currentmonth\ \currentyear}'
. '\@add@frontmatter{ltx:note}[role=volume-info]{\volinfo}');
# abstract otherwise defined in LaTeX.pool
DefMacroI('\abstractname', undef, '\textsc{Abstract}');
# #======================================================================
# # Sec. 5. Document Body
# Mostly normal LaTeX
# For multiple indexes:
# \usepackage{amsmidex}
# \makeindex{name of index file}
# \makeindex{name of index file}
# \index{name of index}{index term} ...
# \Printindex{name of index}{title of index} ...
DefMacro('\format@title@abstract{}', '#1. ');
DefMacro('\format@title@section{}', '\lx@tag[][.\space]{\thesection}#1');
DefMacro('\format@title@subsection{}', '\lx@tag[][.\space]{\thesubsection}#1');
DefMacro('\format@title@subsubsection{}', '\lx@tag[][.\space]{\thesubsubsection}#1');
DefMacro('\format@title@description{}', '\lx@tag[][:\space]{#1}');
DefMacro('\descriptionlabel{}', '\normalfont\bfseries #1:\space');
#======================================================================
# Sec 6. Floating objects: Figures and tables
# Normal LaTeX
# For compatibility
if (LookupValue('2.09_COMPATIBILITY')) {
DefMacroI('\defaultfont', undef, '\normalfont');
DefMacroI('\rom', undef, '\textup');
# RawTeX('\newenvironment{pf}{\begin{@proof}[\proofname]}{\end{@proof}}');
RawTeX('\newenvironment{pf}{\begin{@proof}}{\end{@proof}}');
RawTeX('\newenvironment{pf*}[1]{\begin{@proof}[#1]}{\end{@proof}}');
}
DefMacro('\format@title@figure{}', '\lx@tag[][. ]{\lx@fnum@@{figure}}#1');
DefMacro('\format@title@table{}', '\lx@tag[][. ]{\lx@fnum@@{table}}#1');
# Excersise environments ??:
# xca "must be defined with \theoremstyle{definition} and \newtheorem ???
# xcb only for monographs, at end of chapter
# #======================================================================
# # Sec 7. Bibliographic References
# \bibliographicstyle{} amsplain or amsalpha
# \bibliography{bibfile}
# Normal LaTeX
DefConstructor('\bysame', ' by same author');
DefMacroI('\bibsetup', undef, Tokens());
# #======================================================================
# # Sec 8 Monograph Formatting:
# \documentclass{..}
# preamble
# \begin{document}
# \frontmatter
# frontmatter stuff
# \maketitle
# \include various preface, introduction, etc
# \mainmatter
# \include various chapters, appendices
# \backmatter
# commands for bibliography, indices
# \end{document}
# TOC's should be built by latexml... ?
DefMacro('\tocpart{}{}{}', Tokens());
DefMacro('\tocchapter{}{}{}', Tokens());
DefMacro('\tocsection{}{}{}', Tokens());
DefMacro('\tocsubsection{}{}{}', Tokens());
DefMacro('\tocsubsubsection{}{}{}', Tokens());
DefMacro('\tocparagraph{}{}{}', Tokens());
DefMacro('\tocsubparagraph{}{}{}', Tokens());
DefMacro('\tocappendix{}{}{}', Tokens());
DefMacroI('\contentsnamefont', undef, '\scshape');
DefMacroI('\labelenumi', undef, '(\theenumi)');
DefMacroI('\labelenumii', undef, '(\theenumii)');
DefMacroI('\labelenumiii', undef, '(\theenumiii)');
DefMacroI('\labelenumiv', undef, '(\theenumiv)');
DefRegister('\normaltopskip' => Glue('10pt'));
DefRegister('\linespacing' => Dimension('1pt'));
DefRegister('\normalparindent' => Dimension('12pt'));
DefRegister('\abovecaptionskip' => Glue('12pt'));
DefRegister('\belowcaptionskip' => Glue('12pt'));
DefRegister('\captionindent' => Glue('3pc'));
DefPrimitiveI('\nonbreakingspace', undef, UTF(0xA0));
DefMacroI('\fullwidthdisplay', undef, Tokens());
DefRegister('\listisep' => Glue(0));
DefMacroI('\calclayout', undef, Tokens());
DefMacroI('\indentlabel', undef, Tokens());
# #======================================================================
DefMacroI('\@True', undef, '00');
DefMacroI('\@False', undef, '01');
DefMacro('\newswitch[]{}', sub {
my ($gullet, $value, $switch) = @_;
Let("\\?\@" . ToString($switch), "\\\@" . ToString($value || 'False')); });
DefMacro('\setFalse{}', sub { Let("\\?\@" . ToString($_[1]), "\\\@False"); });
DefMacro('\setTrue{}', sub { Let("\\?\@" . ToString($_[1]), "\\\@True"); });
# funny control structures, using above switches
# \except
# \for
# \forany
DefMacroI('\Mc', undef, 'Mc');
# Generated comma and "and" separated lists...
# \andify, \xandlist, \nxandlist
# #======================================================================
DefMacro('\URLhref{}', '');
DefMacroI('\URL', undef, sub {
my ($gullet) = @_;
my ($init, $body);
{ local $STATE = LaTeXML::Core::State->new(catcodes => 'none');
$init = $gullet->readToken;
$init = $gullet->readToken if ToString($init) eq '*'; # Should I bother handling \verb* ?
$body = $gullet->readUntil($init); }
Invocation(T_CS('\@ams@url'), Tokens($init), $body)->unlist; });
DefConstructor('\@ams@url {}',
"<ltx:ref href='#href'>#1</ltx:ref>",
properties => sub { (href => CleanURL(ToString($_[1]))); });
DefMacro('\MR{}', 'MR #1');
DefMacro('\MRhref{}', '');
# \newcommand\MR[1]{\relax\ifhmode\unskip\spacefactor3000 \space\fi
# \def\@tempa##1:##2:##3\@nil{%
# \ifx @##2\@empty##1\else\textbf{##1:}##2\fi}%
# \MRhref{#1}{MR \@tempa#1:@:\@nil}}
# \let\MRhref\@gobble
# #======================================================================
1;
lib/LaTeXML/Package/amsbook.cls.ltxml view on Meta::CPAN
# \include various preface, introduction, etc
# \mainmatter
DefPrimitive('\mainmatter', undef);
# \include various chapters, appendices
# \backmatter
DefPrimitive('\backmatter', undef);
# commands for bibliography, indices
# \end{document}
# Couple of internals that get used in arXiv:
DefMacro('\@listI', '\leftmargin\leftmargini \parsep\z@skip
\topsep\listisep \itemsep\z@skip
\listparindent\normalparindent');
Let('\@listi', '\@listI');
Let('\enddescription', '\endlist');
Let('\upn', '\textup');
RawTeX(<<'EOL');
\newskip\listisep
\listisep\smallskipamount
EOL
lib/LaTeXML/Package/amscd.sty.ltxml view on Meta::CPAN
# Note that the amscd authors themselves point out that amcsd is limited,
# only covering array-like commutative diagrams, and they suggest
# diagram, xypic or kuvio as alternatives.
#
# However, it is just that simplicity that mkes it possible to represent
# the commutative diagram in straight latexml math, w/o resorting to
# the more general svg(-like) problems.
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
RequirePackage('amsgen');
DefMacro('\CD', '\lx@ams@CD{name=CD,datameaning=commutative-diagram}');
DefMacro('\lx@ams@CD RequiredKeyVals:lx@GEN',
'\lx@gen@matrix@bindings{#1}\lx@ams@CD@bindings\lx@ams@matrix@{#1}\@start@alignment');
DefMacro('\endCD', '\@finish@alignment\lx@end@gen@matrix');
DefPrimitive('\lx@ams@CD@bindings', sub {
Let("\\\\", '\@alignment@newline@noskip');
$STATE->assignMathcode('@' => 0x8000);
Let('@', '\cd@'); });
DefMacro('\cd@ Token', sub {
my ($gullet, $token) = @_;
(T_CS('@' . ToString($token))); });
DefMacroI(T_CS('@>'), 'Until:> Until:>',
'\hidden@align\cd@stack{>}{\rightarrowfill@}{#1}{#2}\hidden@align');
DefMacroI(T_CS('@)'), 'Until:) Until:)',
'\hidden@align\cd@stack{)}{\rightarrowfill@}{#1}{#2}\hidden@align');
DefMacroI(T_CS('@<'), 'Until:< Until:<',
'\hidden@align\cd@stack{<}{\leftarrowfill@}{#1}{#2}\hidden@align');
DefMacroI(T_CS('@('), 'Until:( Until:(',
'\hidden@align\cd@stack{(}{\leftarrowfill@}{#1}{#2}\hidden@align');
DefMacroI(T_CS('@A'), 'Until:A Until:A',
'\cd@adjacent{A}{\Big\uparrow}{#1}{#2}\hidden@align\hidden@align');
DefMacroI(T_CS('@V'), 'Until:V Until:V',
'\cd@adjacent{V}{\Big\downarrow}{#1}{#2}\hidden@align\hidden@align');
DefMacroI(T_CS('@='), undef,
'\hidden@align\@cd@equals@\hidden@align');
DefMacroI(T_CS('@|'), undef,
'\Big\Vert\hidden@align\hidden@align');
DefMacroI(T_CS('@\vert'), undef,
'\Big\Vert\hidden@align\hidden@align');
DefMacroI(T_CS('@.'), undef,
'\hidden@align\hidden@align');
# Horizontal
DefMath('\@cd@equals@', "=", role => 'ARROW', stretchy => 'true', reversion => '@=');
# Vertical
DefMath('\@cd@bar@', "|", role => 'ARROW', font => { size => 'Big' }, reversion => '@|');
DefMath('\@cd@vert@', "\x{2225}", role => 'ARROW', font => { size => 'Big' }, reversion => '@\vert');
DefRegister('\minaw@' => Dimension('11.111pt'));
lib/LaTeXML/Package/amsfonts.sty.ltxml view on Meta::CPAN
# \=========================================================ooo==U==ooo=/ #
package LaTeXML::Package::Pool;
use strict;
use warnings;
use LaTeXML::Package;
#
# See amsfndoc
#
DefConstructor('\mathbb{}', '#1', bounded => 1, requireMath => 1, scope => 'global',
font => { family => 'blackboard', series => 'medium', shape => 'upright' });
DefMacro('\Bbb{}', '\mathbb{#1}');
DefMacro('\bold{}', '\mathbb{#1}');
# Also defined in eufrak
DefConstructor('\mathfrak{}', '#1', bounded => 1, requireMath => 1, scope => 'global',
font => { family => 'fraktur', series => 'medium', shape => 'upright' });
DefMacro('\frak{}', '\mathfrak{#1}');
# Not necessarily math
DefPrimitiveI('\checkmark', undef, "\x{2713}"); # CHECK MARK
DefPrimitiveI('\circledR', undef, UTF(0xAE)); # REGISTERED SIGN
DefPrimitiveI('\maltese', undef, "\x{2720}"); # MALTESE CROSs
DefPrimitiveI('\yen', undef, UTF(0xA5)); # YEN SIGN
# Math
# These are delimiters, but open or close??