Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Amscd #2449

Merged
merged 4 commits into from
Dec 18, 2024
Merged

Amscd #2449

Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 33 additions & 25 deletions lib/LaTeXML/Package/amscd.sty.ltxml
Original file line number Diff line number Diff line change
Expand Up @@ -43,38 +43,34 @@ DefMacro('\cd@ Token', sub {
my ($gullet, $token) = @_;
(T_CS('@' . ToString($token))); });

# Horizontal connectors
DefMacroI(T_CS('@>'), 'Until:> Until:>',
'\lx@hidden@align\cd@stack{>}{\rightarrowfill@}{#1}{#2}\lx@hidden@align');
'\lx@hidden@align\lx@amscd@stack{>}{\lx@amscd@rightarrow}{#1}{#2}\lx@hidden@align');
DefMacroI(T_CS('@)'), 'Until:) Until:)',
'\lx@hidden@align\cd@stack{)}{\rightarrowfill@}{#1}{#2}\lx@hidden@align');
'\lx@hidden@align\lx@amscd@stack{)}{\lx@amscd@rightarrow}{#1}{#2}\lx@hidden@align');
DefMacroI(T_CS('@<'), 'Until:< Until:<',
'\lx@hidden@align\cd@stack{<}{\leftarrowfill@}{#1}{#2}\lx@hidden@align');
'\lx@hidden@align\lx@amscd@stack{<}{\lx@amscd@leftarrow}{#1}{#2}\lx@hidden@align');
DefMacroI(T_CS('@('), 'Until:( Until:(',
'\lx@hidden@align\cd@stack{(}{\leftarrowfill@}{#1}{#2}\lx@hidden@align');
'\lx@hidden@align\lx@amscd@stack{(}{\lx@amscd@leftarrow}{#1}{#2}\lx@hidden@align');
DefMacroI(T_CS('@='), undef,
'\lx@hidden@align\lx@amscd@equals\lx@hidden@align');

# Vertical connectors
DefMacroI(T_CS('@A'), 'Until:A Until:A',
'\cd@adjacent{A}{\Big\uparrow}{#1}{#2}\lx@hidden@align\lx@hidden@align');
'\lx@amscd@adjacent{A}{\Big\uparrow}{#1}{#2}\lx@hidden@align\lx@hidden@align');
DefMacroI(T_CS('@V'), 'Until:V Until:V',
'\cd@adjacent{V}{\Big\downarrow}{#1}{#2}\lx@hidden@align\lx@hidden@align');
'\lx@amscd@adjacent{V}{\Big\downarrow}{#1}{#2}\lx@hidden@align\lx@hidden@align');

DefMacroI(T_CS('@='), undef,
'\lx@hidden@align\@cd@equals@\lx@hidden@align');
DefMacroI(T_CS('@|'), undef,
'\Big\Vert\lx@hidden@align\lx@hidden@align');
DefMacroI(T_CS('@\vert'), undef,
'\Big\Vert\lx@hidden@align\lx@hidden@align');
DefMacroI(T_CS('@.'), undef,
'\lx@hidden@align\lx@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'));

DefConstructor('\cd@stack Undigested {} ScriptStyle ScriptStyle', sub {
DefConstructor('\lx@amscd@stack Undigested {} ScriptStyle ScriptStyle', sub {
my ($document, $reversion, $op, $over, $under, %props) = @_;
my $scriptpos = $props{scriptpos};
if (!IsEmpty($under)) {
Expand All @@ -101,22 +97,34 @@ DefConstructor('\cd@stack Undigested {} ScriptStyle ScriptStyle', sub {
properties => { scriptpos => sub { "mid" . $_[0]->getScriptLevel; } },
reversion => '@#1{#3}#1{#4}#1');

# Temporary...
# Later deal with vertically centering the side things, parser issues...

DefConstructor('\cd@adjacent Undigested {} ScriptStyle ScriptStyle', sub {
DefConstructor('\lx@amscd@adjacent Undigested {} ScriptStyle ScriptStyle', sub {
my ($document, $reversion, $op, $left, $right, %props) = @_;
# Make the left & right parts width=0, so they don't affect centering
$document->openElement('ltx:XMWrap', role => 'ARROW'); # Role?
$document->insertElement('ltx:XMArg', $left) unless IsEmpty($left);
$document->insertElement('ltx:XMArg', $left, width => Dimension(0)) unless IsEmpty($left);
$document->insertElement('ltx:XMArg', $op);
$document->insertElement('ltx:XMArg', $right) unless IsEmpty($right);
$document->insertElement('ltx:XMArg', $right, width => Dimension(0)) unless IsEmpty($right);
$document->closeElement('ltx:XMWrap'); },
reversion => '@#1{#3}#1{#4}#1');

# This isn't really having the desired effect when transformed to MathML and
# displayed in Firefox.... have I got it right; has Firefox???
DefMath('\leftarrowfill@', "\x{2190}", role => 'ARROW', stretchy => 'true');
DefMath('\rightarrowfill@', "\x{2192}", role => 'ARROW', stretchy => 'true');
# These, in case used...
DefMacro('\leftarrowfill@ {}', '\lx@amscd@leftarrow');
DefMacro('\rightarrowfill@ {}', '\lx@amscd@rightarrow');
DefMacro('\leftrightarrowfill@ {}', '\lx@amscd@leftrightarrow');

# These are stretchy, widenned version; should be \minCDarrowsidth or \minaw@ wide
DefPrimitive('\lx@amscd@leftarrow', sub {
Box("\x{2190}", undef, undef, '\leftarrow',
role => 'ARROW', stretchy => 'true', meaning => 'rightarrow', width => Dimension('30pt')); });
DefPrimitive('\lx@amscd@rightarrow', sub {
Box("\x{2192}", undef, undef, '\rightarrowf',
role => 'ARROW', stretchy => 'true', meaning => 'rightarrow', width => Dimension('30pt')); });
DefPrimitive('\lx@amscd@leftrightarrow', sub {
Box("\x{2194}", undef, undef, '\leftrightarrow',
role => 'ARROW', stretchy => 'true', meaning => 'leftrightarrow', width => Dimension('30pt')); });
DefPrimitive('\lx@amscd@equals', sub {
Box("=", undef, undef, T_OTHER('='),
role => 'ARROW', stretchy => 'true', meaning => 'equals', width => Dimension('30pt')); });
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a clarifying question:

What is the intended meaning of an XMTok that has a set positive width (30pt here), with stretchy="true" at the same time?

Does the XMath width act as min-width in this circumstance?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha! Good question! So, the way it gets converted to MathML (wrapped in an mover with a wide mspace, in this PR) allows for the expectation that other table cells might be wider and cause the arrow to stretch even further, so that it would act as a min-width. However, the current MathML-Core apparently only does horizontal stretch within mover/munder, so it would never see those other cells' widths. So, in practice (currently) it would act as the width.


DefRegister('\minCDarrowwidth' => Dimension('2.5pc'));

Expand Down
9 changes: 8 additions & 1 deletion lib/LaTeXML/Post/MathML.pm
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,14 @@ sub pmml_maybe_resize {
my $depth = $node->getAttribute('depth') || ($parent && $parent->getAttribute('depth'));
my $xoff = $node->getAttribute('xoffset') || ($parent && $parent->getAttribute('xoffset'));
my $yoff = $node->getAttribute('yoffset') || ($parent && $parent->getAttribute('yoffset'));
if ($width || $height || $depth || $xoff || $yoff) {
my $role = $node->getAttribute('role') || ($parent && $parent->getAttribute('role'));
my $unstretchy = (($node->getAttribute('stretchy') || ($parent && $parent->getAttribute('stretchy'))) || 'yes') eq 'no';

# First, special case hack for stretchy arrows, with specified width
# Stretchiness (currently) only has effect within munder/mover!!!!!
if ($width && (($role || '') eq 'ARROW') && !$unstretchy) { # SPECIAL CASE HACK
$result = ['m:mover', {}, $result, ['m:mspace', { width => $width }]]; }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if a well-named class attribute for this special case won't be useful in the future. Would make it a little clearer for people inspecting the markup, and easy to check when it gets refactored as MathML Core improves.

Maybe <mover class="ltx_math_stretched"> ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The $unstretchy check may not be booleany enough. If we go with strecthy="true" by default, and when explicit, then everything else is false (including invalid values), then:

  my $stretchy_attr = $node->getAttribute('stretchy') || ($parent && $parent->getAttribute('stretchy')) || "true";
  my $unstretchy = $strechy_attr neq "true";

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Somehow I knew you'd suggest that, so why didn't I just head you off by implementing it? But actually, something like \ltx_horizontally_stretched might be even better; I was a little concerned about the code doing something weird with vertically stretching cases. (Alas, no visible distinction in MathML)

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, if a class is going to be used to detect the "special case", then we can drop the test of stretchy completely.

elsif ($width || $height || $depth || $xoff || $yoff) {
if ($$result[0] eq 'm:mpadded') { }
elsif ($$result[0] eq 'm:mrow') {
$$result[0] = 'm:mpadded'; }
Expand Down
Binary file modified t/ams/cd.pdf
Binary file not shown.
6 changes: 3 additions & 3 deletions t/ams/cd.tex
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
\end{equation}
\begin{equation}
\begin{CD}
\cov(\mathcal{L}) @>>> \non(\mathcal{K}) @>>> \cf(\mathcal{K}) @>>> \cf(\mathcal{L})\\
@VVV @AAA @AAA @VVV\\
\add(\mathcal{L}) @>>> \add(\mathcal{K}) @>>> \cov(\mathcal{K}) @>>> \non(\mathcal{L})
\cov(\mathcal{L}) @>i>j> \non(\mathcal{K}) @)i)) \cf(\mathcal{K}) @>>j> \cf(\mathcal{L})\\
@VVV @| @\vert @AAA\\
\add(\mathcal{L}) @<<< \add(\mathcal{K}) @((( \cov(\mathcal{K}) @<<< \non(\mathcal{L})
\end{CD}
\end{equation}
\end{document}
44 changes: 30 additions & 14 deletions t/ams/cd.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<tag>(1)</tag>
<tag role="refnum">1</tag>
</tags>
<Math mode="display" tex="\begin{CD}S^{{\mathcal{W}}_{\Lambda}}\otimes T@&gt;{j}&gt;{}&gt;T\\&#10;@V{}V{}V@V{}V{\operatorname{End}P}V\\&#10;(S\otimes T)/I@=(Z\otimes T)/J\end{CD}" text="commutative-diagram@(Array[[S ^ (W _ Lambda) tensor-product T, rightarrowfill@ ^ j, T], [downarrow, , absent downarrow End@(P), , ], [(S tensor-product T) / I, @cd@equals@, (Z tensor-product T) / J]])" xml:id="S0.E1.m1">
<Math mode="display" tex="\begin{CD}S^{{\mathcal{W}}_{\Lambda}}\otimes T@&gt;{j}&gt;{}&gt;T\\&#10;@V{}V{}V@V{}V{\operatorname{End}P}V\\&#10;(S\otimes T)/I=(Z\otimes T)/J\end{CD}" text="commutative-diagram@(Array[[S ^ (W _ Lambda) tensor-product T, rightarrow ^ j, T], [downarrow, , absent downarrow End@(P), , ], [(S tensor-product T) / I, =, (Z tensor-product T) / J]])" xml:id="S0.E1.m1">
<XMath>
<XMDual>
<XMApp>
Expand All @@ -39,7 +39,7 @@
<XMCell align="center">
<XMApp>
<XMTok role="SUPERSCRIPTOP" scriptpos="mid5"/>
<XMTok name="rightarrowfill@" role="ARROW" stretchy="true">→</XMTok>
<XMTok meaning="rightarrow" role="ARROW" stretchy="true" width="30.0pt">→</XMTok>
<XMTok font="italic" fontsize="70%" role="UNKNOWN">j</XMTok>
</XMApp>
</XMCell>
Expand All @@ -56,7 +56,7 @@
<XMApp role="ARROW">
<XMTok fontsize="160%" name="downarrow" role="ARROW">↓</XMTok>
<XMTok meaning="absent"/>
<XMApp>
<XMApp width="0.0pt">
<XMTok fontsize="70%" role="OPFUNCTION" scriptpos="post">End</XMTok>
<XMTok font="italic" fontsize="70%" role="UNKNOWN">P</XMTok>
</XMApp>
Expand Down Expand Up @@ -85,7 +85,7 @@
</XMApp>
</XMCell>
<XMCell align="center">
<XMTok name="@cd@equals@" role="ARROW" stretchy="true">=</XMTok>
<XMTok meaning="equals" role="ARROW" stretchy="true" width="30.0pt">=</XMTok>
</XMCell>
<XMCell align="center">
<XMApp>
Expand Down Expand Up @@ -116,7 +116,7 @@
<tag>(2)</tag>
<tag role="refnum">2</tag>
</tags>
<Math mode="display" tex="\begin{CD}\operatorname{cov}(\mathcal{L})@&gt;{}&gt;{}&gt;\operatorname{non}(\mathcal{K%&#10;})@&gt;{}&gt;{}&gt;\operatorname{cf}(\mathcal{K})@&gt;{}&gt;{}&gt;\operatorname{cf}(\mathcal{L})%&#10;\\&#10;@V{}V{}V@A{}A{}A@A{}A{}A@V{}V{}V\\&#10;\operatorname{add}(\mathcal{L})@&gt;{}&gt;{}&gt;\operatorname{add}(\mathcal{K})@&gt;{}&gt;{}&gt;%&#10;\operatorname{cov}(\mathcal{K})@&gt;{}&gt;{}&gt;\operatorname{non}(\mathcal{L})\end{CD}" text="commutative-diagram@(Array[[cov@(L), rightarrowfill@, non@(K), rightarrowfill@, cf@(K), rightarrowfill@, cf@(L)], [downarrow, , uparrow, , uparrow, , downarrow, , ], [add@(L), rightarrowfill@, add@(K), rightarrowfill@, cov@(K), rightarrowfill@, non@(L)]])" xml:id="S0.E2.m1">
<Math mode="display" tex="\begin{CD}\operatorname{cov}(\mathcal{L})@&gt;{i}&gt;{j}&gt;\operatorname{non}(\mathcal%&#10;{K})@){i}){})\operatorname{cf}(\mathcal{K})@&gt;{}&gt;{j}&gt;\operatorname{cf}(\mathcal%&#10;{L})\\&#10;@V{}V{}V\Big{\|}\Big{\|}@A{}A{}A\\&#10;\operatorname{add}(\mathcal{L})@&lt;{}&lt;{}&lt;\operatorname{add}(\mathcal{K})@({}({}(%&#10;\operatorname{cov}(\mathcal{K})@&lt;{}&lt;{}&lt;\operatorname{non}(\mathcal{L})\end{CD}" text="commutative-diagram@(Array[[cov@(L), (rightarrow ^ i) _ j, non@(K), rightarrow ^ i, cf@(K), rightarrow _ j, cf@(L)], [downarrow, , ||, , ||, , uparrow, , ], [add@(L), rightarrow, add@(K), rightarrow, cov@(K), rightarrow, non@(L)]])" xml:id="S0.E2.m1">
<XMath>
<XMDual>
<XMApp>
Expand All @@ -142,7 +142,15 @@
</XMDual>
</XMCell>
<XMCell align="center">
<XMTok name="rightarrowfill@" role="ARROW" stretchy="true">→</XMTok>
<XMApp role="ARROW">
<XMTok role="SUBSCRIPTOP" scriptpos="mid5"/>
<XMApp>
<XMTok role="SUPERSCRIPTOP" scriptpos="mid5"/>
<XMTok meaning="rightarrow" role="ARROW" stretchy="true" width="30.0pt">→</XMTok>
<XMTok font="italic" fontsize="70%" role="UNKNOWN">i</XMTok>
</XMApp>
<XMTok font="italic" fontsize="70%" role="UNKNOWN">j</XMTok>
</XMApp>
</XMCell>
<XMCell align="center">
<XMDual>
Expand All @@ -161,7 +169,11 @@
</XMDual>
</XMCell>
<XMCell align="center">
<XMTok name="rightarrowfill@" role="ARROW" stretchy="true">→</XMTok>
<XMApp>
<XMTok role="SUPERSCRIPTOP" scriptpos="mid5"/>
<XMTok meaning="rightarrow" role="ARROW" stretchy="true" width="30.0pt">→</XMTok>
<XMTok font="italic" fontsize="70%" role="UNKNOWN">i</XMTok>
</XMApp>
</XMCell>
<XMCell align="center">
<XMDual>
Expand All @@ -180,7 +192,11 @@
</XMDual>
</XMCell>
<XMCell align="center">
<XMTok name="rightarrowfill@" role="ARROW" stretchy="true">→</XMTok>
<XMApp role="ARROW">
<XMTok role="SUBSCRIPTOP" scriptpos="mid5"/>
<XMTok meaning="rightarrow" role="ARROW" stretchy="true" width="30.0pt">→</XMTok>
<XMTok font="italic" fontsize="70%" role="UNKNOWN">j</XMTok>
</XMApp>
</XMCell>
<XMCell align="center">
<XMDual>
Expand All @@ -205,15 +221,15 @@
</XMCell>
<XMCell/>
<XMCell align="center">
<XMTok fontsize="160%" name="uparrow" role="ARROW">↑</XMTok>
<XMTok fontsize="160%" name="||" role="VERTBAR">∥</XMTok>
</XMCell>
<XMCell/>
<XMCell align="center">
<XMTok fontsize="160%" name="uparrow" role="ARROW">↑</XMTok>
<XMTok fontsize="160%" name="||" role="VERTBAR">∥</XMTok>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name="||" got me curious, so I checked the DefMath, which indeed uses that name for \|.

DefMathI('\|',        undef, "\x{2225}", role => 'VERTBAR',  name    => '||');

In the TeXbook, I see its definition marked with "vertical line" in Appendix E, p. 420:

\def\|{\leavevmode\hbox{\tt\char‘\|}} % vertical line

Would vertical-lines be a better name in this case?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be, but name is a bit of an orphan: it's somewhere between the content, reversion and meaning; it probably shouldn't even exist at all, but it does get used for various checks.
At some point in the not too distant future, a scan of all uses needs to be analyzed and figure out where to go with it. Perhaps it should end up being part of intent infrastructure? So: Hold onto that thought!

</XMCell>
<XMCell/>
<XMCell align="center">
<XMTok fontsize="160%" name="downarrow" role="ARROW"></XMTok>
<XMTok fontsize="160%" name="uparrow" role="ARROW"></XMTok>
</XMCell>
<XMCell/>
<XMCell/>
Expand All @@ -236,7 +252,7 @@
</XMDual>
</XMCell>
<XMCell align="center">
<XMTok name="rightarrowfill@" role="ARROW" stretchy="true">→</XMTok>
<XMTok meaning="rightarrow" role="ARROW" stretchy="true" width="30.0pt">←</XMTok>
</XMCell>
<XMCell align="center">
<XMDual>
Expand All @@ -255,7 +271,7 @@
</XMDual>
</XMCell>
<XMCell align="center">
<XMTok name="rightarrowfill@" role="ARROW" stretchy="true">→</XMTok>
<XMTok meaning="rightarrow" role="ARROW" stretchy="true" width="30.0pt">←</XMTok>
</XMCell>
<XMCell align="center">
<XMDual>
Expand All @@ -274,7 +290,7 @@
</XMDual>
</XMCell>
<XMCell align="center">
<XMTok name="rightarrowfill@" role="ARROW" stretchy="true">→</XMTok>
<XMTok meaning="rightarrow" role="ARROW" stretchy="true" width="30.0pt">←</XMTok>
</XMCell>
<XMCell align="center">
<XMDual>
Expand Down
Loading