# -*- mode: Perl -*-
# /=====================================================================\ #
# | cases | #
# | Implementation for LaTeXML | #
# |=====================================================================| #
# | Part of LaTeXML: | #
# | Public domain software, produced as part of work done by the | #
# | United States Government & not subject to copyright in the US. | #
# |---------------------------------------------------------------------| #
# | Bruce Miller <bruce.miller@nist.gov> #_# | #
# \=========================================================ooo==U==ooo=/ #
package LaTeXML::Package::Pool;
use strict;
use warnings;
use LaTeXML::Package;
#======================================================================
# cases provides a top-level equationgroup environment representing an
# ams-like cases statement, but with each case numbered.
# TODO: get the display right!
# Currently, we're simply reproducing the LHS as individual equations, but aligned;
# this is probably an understandable display, but not the author's intent.
# We SHOULD have a single LHS with a large \{ enclosing the RHS's & conditions.
# I think this will be fixable with a little work & support from the XSLT.
# Basically, we need
# * 1st LHS column needs rowspan= the number of equations
# * remaining LHS columns should be empty (and omitted from html!)
# * do NOT wrap (& ID) each equation in tbody (it breaks the rowspan!)
# (but since each equation is single row, we can put the ID on the tr)
# A couple of other notes:
# * since the LHS is currently repeated, it's easy to move into the semantic side
# of the MathFork; but will need to be cloned.
# * the \{ probably will need a size or strut of the total height of the RHS's
#======================================================================
DefMacro('\numcases{}',
'\@numcases@bindings{#1}\@@numcases'
. '\@equationgroup@numbering{numbered=1,preset=1,deferretract=1,grouped=1,aligned=1}'
. '\@start@alignment\@numcases@LHS',
locked => 1);
DefMacroI('\endnumcases', undef,
'\@finish@alignment\end@numcases',
locked => 1);
# Needs sub-numbering turned on!
DefMacro('\subnumcases{}',
'\@numcases@bindings{#1}\lx@numcases@subnumbering@begin\@@numcases'
. '\@equationgroup@numbering{numbered=1,preset=1,deferretract=1,grouped=1,aligned=1}'
. '\@start@alignment\@numcases@LHS',
locked => 1);
DefMacroI('\endsubnumcases', undef,
'\@finish@alignment\end@numcases\lx@numcases@subnumbering@end',
locked => 1);
# Somehow, I haven't generalized equation numbering setup enough???
DefPrimitive('\lx@numcases@subnumbering@begin', sub {
my %eqn = RefStepCounter('equation');
my $eqnum = Expand(T_CS('\theequation'));
AssignValue(SAVED_EQUATION_NUMBER => LookupRegister('\c@equation'));
ResetCounter('equation');
DefMacro('\theequation', UnTeX($eqnum) . '\alph{equation}');
DefMacro('\theequation@ID', UnTeX($eqn{id}) . '.\@equation@ID'); });
DefPrimitive('\lx@numcases@subnumbering@end', sub {
AssignRegister('\c@equation', LookupValue('SAVED_EQUATION_NUMBER'), 'global'); });
DefPrimitive('\@numcases@bindings{}', sub {
numcasesBindings($_[1]); });
sub numcasesBindings {
my ($lhs) = @_;
# 3 columns: math right, math left, text left
my $col1 = { before => Tokens(T_CS('\hfil'), T_MATH, T_CS('\@hidden@bgroup'), T_CS('\displaystyle')),
after => Tokens(T_CS('\@hidden@egroup'), T_MATH) };
my $col2 = { before => Tokens(T_MATH, T_CS('\@hidden@bgroup'), T_CS('\displaystyle')),
after => Tokens(T_CS('\@hidden@egroup'), T_MATH, T_CS('\hfil')) };
my $col3 = { before => Tokens(T_CS('\@hidden@bgroup')),
after => Tokens(T_CS('\@hidden@egroup'), T_CS('\hfil')) };
my %attributes = (
'class' => 'ltx_eqn_numcases',
'colsep' => LookupDimension('\arraycolsep')->multiply(2));
my $cur_jot = LookupDimension('\jot');
if ($cur_jot && ($cur_jot->valueOf != LookupDimension('\lx@default@jot')->valueOf)) {
$attributes{rowsep} = $cur_jot; }
AssignValue(Alignment => LaTeXML::Core::Alignment->new(
template => LaTeXML::Core::Alignment::Template->new(columns => [$col1, $col2, $col3]),
openContainer => sub { my %attr = RefStepID('@equationgroup');
$attr{'xml:id'} = $attr{id}; delete $attr{id};
$attr{class} = 'ltx_eqn_eqnarray';
$_[0]->openElement('ltx:equationgroup', %attr, @_[1 .. $#_]); },
closeContainer => sub { $_[0]->closeElement('ltx:equationgroup'); },
openRow => sub {
my ($doc, %props) = @_;
my $tags = $props{tags}; delete($props{tags});
$doc->openElement('ltx:equation', %props);
$doc->absorb($tags) if $tags; },
closeRow => sub { $_[0]->closeElement('ltx:equation'); },
openColumn => sub { $_[0]->openElement('ltx:_Capture_', @_[1 .. $#_]); },
closeColumn => sub { $_[0]->closeElement('ltx:_Capture_'); },
properties => { preserve_structure => 1, attributes => {%attributes} }));
DefMacroI('\@numcases@LHS', undef, Tokens($lhs, T_ALIGN));
# Let(T_ALIGN, '\@alignment@align');
Let("\\\\", '\@numcases@newline');
Let('\@row@before', '\eqnarray@row@before');
Let('\@row@after', '\eqnarray@row@after');
return; }
DefMacro('\@numcases@newline[]',
'\ifx.#1.\@alignment@newline\else\@alignment@newline[#1]\fi\@numcases@LHS');
DefMacro('\@numcases@cr', '\@alignment@cr\@numcases@LHS');
DefConstructor('\@@numcases SkipSpaces DigestedBody',
'#1',
beforeDigest => sub { $_[0]->bgroup; },
afterConstruct => sub { rearrangeNumcases($_[0], $_[0]->getNode->lastChild); });
DefPrimitiveI('\end@numcases', undef, sub { $_[0]->egroup; });
sub rearrangeNumcases {
my ($document, $equationgroup) = @_;
foreach my $equation ($document->findnodes('ltx:equation', $equationgroup)) {
if (my @cells = $document->findnodes('ltx:_Capture_', $equation)) {
my @cell1cont = $document->getChildElements($cells[0]);
# Check if this equation is really an intertext
if ((scalar(@cells) == 1) && (scalar(@cell1cont) == 1)
&& (($cell1cont[0]->getAttribute('class') || '') =~ /\b(ltx_intertext)\b/)) {
$equation->replaceNode($cell1cont[0]); } # Replace equation with the block.
elsif ((scalar(@cells) == 1) && (scalar(@cell1cont) == 0)) { # Empty row? Remove it!
$equationgroup->removeChild($equation); }
else {
equationgroupJoinCols($document, 3, $equation); } } }
return; }
#======================================================================
1;