LaTeXML

 view release on metacpan or  search on metacpan

lib/LaTeXML/Package/amsmath.sty.ltxml  view on Meta::CPAN

# \! == \negthinspace
# \negmedspace
# \negthickspace
# these are now native to LaTeX (see section C.7.7 Spacing)

DefConstructor('\mspace{MuDimension}', "<ltx:XMHint name='mspace' width='#1'/>");

#======================================================================
# Section 4.3 Dots
# Nice idea, but not sure what I really should do about it.
# In principle, a processor has access to the context....
DefMathI('\dotsc', undef, "\x{2026}", role => 'ID', alias => '\dotsc');
DefMathI('\dotsb', undef, "\x{22EF}", role => 'ID', alias => '\dotsb');
DefMathI('\dotsm', undef, "\x{22EF}", role => 'ID', alias => '\dotsm');
DefMathI('\dotsi', undef, "\x{22EF}", role => 'ID', alias => '\dotsi');
DefMathI('\dotso', undef, "\x{2026}", role => 'ID', alias => '\dotso');

# Not really clear when these get set to something other than \relax, in amsfonts.sty
DefMacroI('\DOTSB', undef, Tokens());
DefMacroI('\DOTSI', undef, Tokens());
DefMacroI('\DOTSX', undef, Tokens());
Let('\hdots', '\lx@ldots');

DefMacro('\hdotsfor Number', sub {
    (map { T_CS('\hdots') } 1 .. $_[1]->valueOf); });

# The basic idea is simple enough (in TeX world);
# Peek to see what follows (\futurelet) and if mathbin or mathrel, use cdots.
# That corresponds to the @role of the following token (once in XML),
# but we're always too early to check it!
# Using a Digested arg seems a little risky, especially "$", but usually can see @role
# This currently doesn't see deeply enough into $after, eg. \boldsymbol{+}
DefPrimitive('\lx@math@dots Digested', sub {
    my ($stomach, $after) = @_;
    my $role   = $after && $after->getProperty('role');
    my %binops = (ADDOP => 1, BINOP => 1, MULOP => 1, RELOP => 1);
    return (Box(($role && $binops{$role} ? "\x{22EF}" : "\x{2026}"),
        undef, undef, T_CS('\dots'), mode => 'math', name => 'dots', role => 'ID'),
      $after); });
DefMacro('\dots', '\ifmmode\lx@math@dots\else\lx@ldots\fi', robust => 1);

#======================================================================
# Section 4.4 Nonbreaking dashes
# \nobreakdash
DefMacro('\nobreakdash', '');    # Ignorable
#======================================================================
# Section 4.5 Accents in math
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 ABOVE

# In amsxtra
#  \sphat \sptilde

#======================================================================
# Section 4.6 Roots
# It would be nice to carry this info through to mathml, but ignore for now.
DefMacro('\leftroot{}', '');
DefMacro('\uproot{}',   '');

#======================================================================
# Section 4.7 Boxed formulas
DefMacro('\boxed{}', '\ifmmode\boxed@math{#1}\else\boxed@text{#1}\fi', robust => 1);
DefConstructor('\boxed@math{}',
  "<ltx:XMArg enclose='box'>#1</ltx:XMArg>",
  alias => '\boxed');

DefConstructor('\boxed@text{}',
  "<ltx:Math mode='display' framed='rectangle'>"
    . "<ltx:XMath>"
    . "#1"
    . "</ltx:XMath>"
    . "</ltx:Math>",
  mode         => 'math', bounded => 1,
  beforeDigest => sub {
    Let("\\\\", '\lx@newline'); },
  alias => '\boxed');

DefMath('\implies',   "\x{27F9}", role => 'ARROW', meaning => 'implies');
DefMath('\impliedby', "\x{27F8}", role => 'ARROW', meaning => 'implied-by');

DefMath('\And', '&', role => 'ADDOP', meaning => 'and');

#======================================================================
# Section 4.8 Over and under arrows

# Should be in LaTeX (& TeX): \overrightarrow, \overleftarrow
# Note that the arrow is treated as an accent over/under the argument!
DefMath('\underrightarrow{}',     "\x{2192}", operator_role => 'UNDERACCENT');
DefMath('\underleftarrow{}',      "\x{2190}", operator_role => 'UNDERACCENT');
DefMath('\overleftrightarrow{}',  "\x{2194}", operator_role => 'OVERACCENT');
DefMath('\underleftrightarrow{}', "\x{2194}", operator_role => 'UNDERACCENT');

#======================================================================
# Section 4.9 Extensible arrows
#  \xleftarrow, \xrightarrow

# set up a general macro to support variations on xarrows macros (see mathtools)
# \lx@long@arrow{token}{arrow}[under]{over}
DefConstructor('\lx@long@arrow DefToken {}[]{}',
  "?#3("
    . "<ltx:XMApp role='ARROW'>"
    . "<ltx:XMWrap role='UNDERACCENT'>#3</ltx:XMWrap>"
    . "<ltx:XMApp role='ARROW'>"
    . "<ltx:XMWrap role='OVERACCENT'>#4</ltx:XMWrap>"
    . "#2"
    . "</ltx:XMApp>"
    . "</ltx:XMApp>"
    . ")("
    . "<ltx:XMApp role='ARROW'>"
    . "<ltx:XMWrap role='OVERACCENT'>#4</ltx:XMWrap>"
    . "#2"
    . "</ltx:XMApp>"
    . ")",
  reversion => sub {
    my ($whatsit, $cs, $arrow, $under, $over) = @_;
    ($cs, ($under ? (T_OTHER('['), Revert($under), T_OTHER(']')) : ()), T_BEGIN, Revert($over), T_END); },
  # specialize to ldots ???
  properties => { font => sub { LookupValue('font')->specialize("\x{2026}"); } });

DefMacro('\xrightarrow', '\lx@long@arrow{\xrightarrow}{\rightarrow}');
DefMacro('\xleftarrow',  '\lx@long@arrow{\xleftarrow}{\leftarrow}');

lib/LaTeXML/Package/amsmath.sty.ltxml  view on Meta::CPAN

  alias        => '\cfrac',
  beforeDigest => sub {
    $_[0]->bgroup;
    MergeFont(mathstyle => LookupValue('cfracmathstyle')); },
  afterDigest => sub {
    $_[0]->egroup;
    $_[1]->setProperties(name => (LookupValue('CFRACSTYLE') eq 'inline' ? 'cfrac-inline' : 'cfrac'),
      mathstyle => LookupValue('cfracmathstyle')); });

AssignValue(CFRACSTYLE => 'display');
# This should get incorporated into any \cfrac's that are constructed in scope.
DefConstructor('\cfracstyle{}', '',
  afterDigest => sub {
    my $style = ToString($_[1]->getArg(1));
    $style = ($style eq 'd' ? 'display' : ($style eq 'i' ? 'inline' : $style));
    AssignValue(CFRACSTYLE => $style); });

#======================================================================
# Section 4.13 Smash options
DefConstructor('\smash[]{}', "#2");    # well, what?

#======================================================================
# Section 4.14 Delimiters

# Section 4.14.1 Delimiter sizes
# Redefinitions(?) of \bigl, \bigr, \Bigl,\Bigr, \biggl, \biggr, \Biggl, \Biggr

# Section 4.14.2 Vertical bar notations
DefMath('\lvert', '|',        role => 'OPEN',  stretchy => 'false');
DefMath('\lVert', "\x{2225}", role => 'OPEN',  stretchy => 'false');    # PARALLEL TO
DefMath('\rvert', '|',        role => 'CLOSE', stretchy => 'false');
DefMath('\rVert', "\x{2225}", role => 'CLOSE', stretchy => 'false');    # PARALLEL TO

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Section 5  Operator names
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

#======================================================================
# Section 5.1 Defining new operator names

# See package amsopn (included by default)

#======================================================================
# Section 5.2 \mod and it's relatives
# \bmod, \pmod which are already in LaTeX
DefMath('\mod',   'mod',  role => 'MODIFIEROP', meaning => 'modulo');
DefMath('\pod{}', '(#1)', role => 'MODIFIER',   meaning => 'modulo');    # Well, sorta postfix..

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Section 6 The \text command
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# See package amstext, included by default.

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Section 7 Integrals and sums
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

#======================================================================
# Section 7.1 Multiline subscripts and superscripts
#  \substack, \begin{subarray}
# These make the combining operator be list, but often formulae would be better
DefMacro('\substack{}', '\begin{subarray}{c}#1\end{subarray}');
DefMacro('\subarray{}',
'\lx@ams@matrix{name=subarray,style=\scriptsize,datameaning=list,rowsep=0pt,alignment=#1,alignment-required=true}');
DefMacro('\endsubarray', '\lx@end@ams@matrix');
#======================================================================
# Section 7.2 the \sideset command

# This is intended to be a modifier for \sum or \prod
# NOTE that there can be at most one subscript in each of the pre & post, ditto for superscript.
# Thus, our representation is: sideset(presub,presup,postsub,postsup,object)
# Note, also, that this is quite ugly, but since it is a rather peculiar special case.... ?
DefConstructor('\sideset{}{}{}', sub {
    my ($document, $pre, $post, $base, %props) = @_;
    my @scripts = (undef, undef, undef, undef);

    # Just to be "safe", scan for any NON scripts in the pre-scripts
    # They work with \sideset, although it isn't clear what they should mean.
    # we'll just insert them in front of the whole mess.
    foreach my $script ($pre->unlist) {
      if (!IsScript($script)) {
        Warn('expected', '<sub/supserscript>', $document,
          "Expected a sub/superscript in the prescripts of \\sideset",
          "Got " . Stringify($script));
        $document->insertElement('ltx:XMWrap', $script); } }    # Stick any non-scripts FRONT!

    my $node = $document->insertElement('ltx:XMArg', $base);
    my $ch   = $document->getFirstChildElement($node);
    my ($opx, $ignore)
      = ($ch && $ch->getAttribute('scriptpos') || 'post') =~ /^(pre|mid|post)?(\d+)?$/;
    my $level0 = $props{scriptlevel} || 0;
    my $level  = $level0;
    foreach my $script (reverse $pre->unlist) {
      # If it's a script, handle it (non-scripts dealt with above & below)
      if (my $scriptop = IsScript($script)) {
        $node = sidesetWrap($document, $node, 'pre', $$scriptop[1], $level, $script);
        $level++ if $$scriptop[0] eq 'FLOATING';                # After node is seen!
    } }
    my @after = ();
    foreach my $script ($post->unlist) {
      # If it's a script, handle it (non-scripts dealt with above & below)
      if (my $scriptop = IsScript($script)) {
        $level++ if $$scriptop[0] eq 'FLOATING';                # Before node is seen!
        $node = sidesetWrap($document, $node, 'post', $$scriptop[1], $level, $script); }
      else {
        push(@after, $script); } }                              # Save non-scripts
    $document->setAttribute($node, scriptpos => $opx . $level0) if $opx;

    # Put any garbage in the post-scripts AFTER
    foreach my $nonscript (@after) {
      Warn('expected', '<sub/supserscript>', $document,
        "Expected a sub/superscript in the postscripts of \\sideset",
        "Got " . Stringify($nonscript));
      $document->insertElement('ltx:XMWrap', $nonscript); }    # Append, afterwards
});

sub sidesetWrap {
  my ($document, $node, $x, $y, $level, $script) = @_;
  my $new = $document->openElement('ltx:XMApp');
  $document->insertElement('ltx:XMTok', undef, role => $y . 'OP', scriptpos => "$x$level");
  $new->appendChild($node);



( run in 0.550 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )