LaTeXML
view release on metacpan or search on metacpan
lib/LaTeXML/Post/MathML.pm view on Meta::CPAN
my $rop = realize($op);
my $style =
$rop->getAttribute('mathstyle') || $op->getAttribute('mathstyle');
my $ostyle = $LaTeXML::MathML::STYLE;
local $LaTeXML::MathML::STYLE
= ($style && $stylestep{$style} ? $style : $LaTeXML::MathML::STYLE);
my $result = &{ lookupPresenter('Apply', getOperatorRole($rop), $rop->getAttribute('meaning'))
}($op, @args);
$result = pmml_maybe_resize($node, $result);
my $needsmathstyle = needsMathstyle($result);
my %styleattr = %{ ($style && ($needsmathstyle
? $stylemap{$ostyle}{$style}
: $stylemap2{$ostyle}{$style})) || {} };
$result = ['m:mstyle', {%styleattr}, $result] if keys %styleattr;
return $result; } }
elsif ($tag eq 'ltx:XMTok') {
return &{ lookupPresenter('Token', $role, $node->getAttribute('meaning')) }($node); }
elsif ($tag eq 'ltx:XMHint') {
return &{ lookupPresenter('Hint', $role, $node->getAttribute('meaning')) }($node); }
elsif ($tag eq 'ltx:XMArray') {
my $width = $node->getAttribute('width');
my $style = $node->getAttribute('mathstyle');
my $vattach = $node->getAttribute('vattach');
my $rowsep = $node->getAttribute('rowsep') || '0pt';
my $colsep = $node->getAttribute('colsep') || '5pt';
$vattach = 'axis' if !$vattach || ($vattach eq 'middle'); # roughly MathML's axis?
$vattach = 'bottom1' if $vattach && ($vattach eq 'top');
my $ostyle = $LaTeXML::MathML::STYLE;
local $LaTeXML::MathML::STYLE
= ($style && $stylestep{$style} ? $style : $LaTeXML::MathML::STYLE);
my @rows = ();
my $nrows = 0;
my $ncols = 0;
my @spanned = (); # record columns to be skipped
foreach my $row (element_nodes($node)) {
my @cols = ();
my $nc = 0;
$nrows++;
foreach my $col (element_nodes($row)) {
$nc++;
$spanned[$nc - 1]-- if $spanned[$nc - 1];
next if $spanned[$nc - 1]; # Omit this mtd, if spanned by another!
my $a = $col->getAttribute('align');
my $b = $col->getAttribute('border');
my $bc = ($b ? join(' ', map { 'ltx_border_' . $_ } split(/\s/, $b)) : $b);
my $th = $col->getAttribute('thead');
my $hc = ($th ? join(' ', map { 'ltx_th_' . $_ } split(/\s/, $th)) : '');
my $cl = $col->getAttribute('class');
my $c = ($bc ? ($hc ? "$bc $hc" : $bc) : $hc);
my $cs = $col->getAttribute('colspan');
my $rs = $col->getAttribute('rowspan');
my @cell = filter_row(map { pmml($_) } element_nodes($col));
if ($rs || $cs) { # Note following cells to be omitted from MathML
for (my $i = 0 ; $i < ($cs || 1) ; $i++) {
$spanned[$nc - 1 + $i] = ($rs || 1); } }
push(@cols, ['m:mtd', { ($a && ($a ne 'center')
? (columnalign => $a, class => 'ltx_align_' . $a) : ()),
($c || $cl ? (class => ($c && $cl ? "$c $cl" : $c || $cl)) : ()),
($cs ? (columnspan => $cs) : ()),
($rs ? (rowspan => $rs) : ()) },
@cell]); }
$ncols = $nc if $nc > $ncols;
push(@rows, ['m:mtr', {}, @cols]); }
$rowsep = undef if $nrows < 2;
$colsep = undef if $ncols < 2;
my $result = ['m:mtable', { ($vattach ne 'axis' ? (align => $vattach) : ()),
($rowsep ? (rowspacing => $rowsep) : ()),
($colsep ? (columnspacing => $colsep) : ()),
($width ? (width => $width) : ()),
# Mozilla seems to need some encouragement?
($LaTeXML::MathML::STYLE eq 'display' ? (displaystyle => 'true') : ()) },
@rows];
my $needsmathstyle = needsMathstyle($result);
my %styleattr = %{ ($style && ($needsmathstyle
? $stylemap{$ostyle}{$style}
: $stylemap2{$ostyle}{$style})) || {} };
$result = ['m:mstyle', {%styleattr}, $result] if keys %styleattr;
$result = pmml_maybe_resize($node, $result);
return $result; }
elsif ($tag eq 'ltx:XMText') {
my @c = $node->childNodes;
my $result;
if (!$$self{nestmath}) {
$result = pmml_row(map { pmml_text_aux($_) } @c); }
else {
$result = ['m:mtext', {}, $self->convertXMTextContent($doc, 1, @c)]; }
return pmml_maybe_resize($node, $result); }
elsif ($tag eq 'ltx:ERROR') {
my $cl = $node->getAttribute('class');
return ['m:merror', { class => join(' ', grep { $_ } 'ltx_ERROR', $cl) },
['m:mtext', {}, $node->textContent]]; }
else {
my $text = $node->textContent; # Spaces are significant here
$text =~ s/^\s+/$NBSP/;
$text =~ s/\s+$/$NBSP/;
return ['m:mtext', {}, $text]; } }
sub needsMathstyle {
no warnings 'recursion';
my ($node) = @_;
if (ref $node eq 'ARRAY') {
my ($tag, $attr, @children) = @$node;
return 1 if $tag eq 'm:mfrac';
return 1 if $$attr{_largeop};
return 0 if ($tag eq 'm:mstyle') && defined $$attr{displaystyle};
return 1 if grep { needsMathstyle($_) } @children; }
return; }
# Use mpadded instead of mrow if size has been given
# And maybe this is a convenient place to deal with frames?
sub pmml_maybe_resize {
my ($node, $result) = @_;
return $result unless ref $node;
my $parent;
# There MAY be relevant attributes on a containing XMDual (if any)!!!
if ((ref $node) && ($node->nodeType == XML_ELEMENT_NODE)
&& ($parent = $node->parentNode) && (getQName($parent) eq 'ltx:XMDual')) { }
else { $parent = undef; }
my $width = $node->getAttribute('width') || ($parent && $parent->getAttribute('width'));
( run in 2.213 seconds using v1.01-cache-2.11-cpan-2398b32b56e )