1# -*- mode: Perl -*-
2# /=====================================================================\ #
3# |  amscd                                                              | #
4# | Implementation for LaTeXML                                          | #
5# |=====================================================================| #
6# | Part of LaTeXML:                                                    | #
7# |  Public domain software, produced as part of work done by the       | #
8# |  United States Government & not subject to copyright in the US.     | #
9# |---------------------------------------------------------------------| #
10# | Thanks to the arXMLiv group for initial implementation              | #
11# |    http://arxmliv.kwarc.info/                                       | #
12# | Released to the Public Domain                                       | #
13# |---------------------------------------------------------------------| #
14# | Bruce Miller <bruce.miller@nist.gov>                        #_#     | #
15# | http://dlmf.nist.gov/LaTeXML/                              (o o)    | #
16# \=========================================================ooo==U==ooo=/ #
17package LaTeXML::Package::Pool;
18use strict;
19use warnings;
20use LaTeXML::Package;
21
22#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
23# Note that the amscd authors themselves point out that amcsd is limited,
24# only covering array-like commutative diagrams, and they suggest
25# diagram, xypic or kuvio as alternatives.
26#
27# However, it is just that simplicity that mkes it possible to represent
28# the commutative diagram in straight latexml math, w/o resorting to
29# the more general svg(-like) problems.
30#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31RequirePackage('amsgen');
32
33DefMacro('\CD', '\lx@ams@CD{name=CD,datameaning=commutative-diagram}');
34DefMacro('\lx@ams@CD RequiredKeyVals:lx@GEN',
35  '\lx@gen@matrix@bindings{#1}\lx@ams@CD@bindings\lx@ams@matrix@{#1}\@start@alignment');
36DefMacro('\endCD', '\@finish@alignment\lx@end@gen@matrix');
37DefPrimitive('\lx@ams@CD@bindings', sub {
38    Let("\\\\", '\@alignment@newline@noskip');
39    $STATE->assignMathcode('@' => 0x8000);
40    Let('@', '\cd@'); });
41
42DefMacro('\cd@ Token', sub {
43    my ($gullet, $token) = @_;
44    (T_CS('@' . ToString($token))); });
45
46DefMacroI(T_CS('@>'), 'Until:> Until:>',
47  '\hidden@align\cd@stack{>}{\rightarrowfill@}{#1}{#2}\hidden@align');
48DefMacroI(T_CS('@)'), 'Until:) Until:)',
49  '\hidden@align\cd@stack{)}{\rightarrowfill@}{#1}{#2}\hidden@align');
50DefMacroI(T_CS('@<'), 'Until:< Until:<',
51  '\hidden@align\cd@stack{<}{\leftarrowfill@}{#1}{#2}\hidden@align');
52DefMacroI(T_CS('@('), 'Until:( Until:(',
53  '\hidden@align\cd@stack{(}{\leftarrowfill@}{#1}{#2}\hidden@align');
54
55DefMacroI(T_CS('@A'), 'Until:A Until:A',
56  '\cd@adjacent{A}{\Big\uparrow}{#1}{#2}\hidden@align\hidden@align');
57DefMacroI(T_CS('@V'), 'Until:V Until:V',
58  '\cd@adjacent{V}{\Big\downarrow}{#1}{#2}\hidden@align\hidden@align');
59
60DefMacroI(T_CS('@='), undef,
61  '\hidden@align\@cd@equals@\hidden@align');
62DefMacroI(T_CS('@|'), undef,
63  '\Big\Vert\hidden@align\hidden@align');
64DefMacroI(T_CS('@\vert'), undef,
65  '\Big\Vert\hidden@align\hidden@align');
66DefMacroI(T_CS('@.'), undef,
67  '\hidden@align\hidden@align');
68
69# Horizontal
70DefMath('\@cd@equals@', "=", role => 'ARROW', stretchy => 'true', reversion => '@=');
71# Vertical
72DefMath('\@cd@bar@', "|", role => 'ARROW', font => { size => 'Big' }, reversion => '@|');
73DefMath('\@cd@vert@', "\x{2225}", role => 'ARROW', font => { size => 'Big' }, reversion => '@\vert');
74
75DefRegister('\minaw@' => Dimension('11.111pt'));
76
77DefConstructor('\cd@stack Undigested {} ScriptStyle ScriptStyle', sub {
78    my ($document, $reversion, $op, $over, $under, %props) = @_;
79    my $scriptpos = $props{scriptpos};
80    if ($under->unlist) {
81      $document->openElement('ltx:XMApp', role => 'ARROW');    # Role?
82      $document->insertElement('ltx:XMTok', undef, role => 'SUBSCRIPTOP', scriptpos => $scriptpos);
83      if ($over->unlist) {
84        $document->openElement('ltx:XMApp');                   # Role?
85        $document->insertElement('ltx:XMTok', undef, role => 'SUPERSCRIPTOP', scriptpos => $scriptpos);
86        $document->insertElement('ltx:XMArg', $op);
87        $document->insertElement('ltx:XMArg', $over);
88        $document->closeElement('ltx:XMApp'); }
89      else {
90        $document->insertElement('ltx:XMArg', $op); }
91      $document->insertElement('ltx:XMArg', $under);
92      $document->closeElement('ltx:XMApp'); }
93    elsif ($over->unlist) {
94      $document->openElement('ltx:XMApp');                     # Role?
95      $document->insertElement('ltx:XMTok', undef, role => 'SUPERSCRIPTOP', scriptpos => $scriptpos);
96      $document->insertElement('ltx:XMArg', $op);
97      $document->insertElement('ltx:XMArg', $over);
98      $document->closeElement('ltx:XMApp'); }
99    else {
100      $document->insertElement('ltx:XMArg', $op); } },
101  properties => { scriptpos => sub { "mid" . $_[0]->getScriptLevel; } },
102  reversion  => '@#1{#3}#1{#4}#1');
103
104# Temporary...
105# Later deal with vertically centering the side things, parser issues...
106
107DefConstructor('\cd@adjacent Undigested {} ScriptStyle ScriptStyle', sub {
108    my ($document, $reversion, $op, $left, $right, %props) = @_;
109    $document->openElement('ltx:XMWrap', role => 'ARROW');    # Role?
110    $document->insertElement('ltx:XMArg', $left) if $left->unlist;
111    $document->insertElement('ltx:XMArg', $op);
112    $document->insertElement('ltx:XMArg', $right) if $right->unlist;
113    $document->closeElement('ltx:XMWrap'); },
114  reversion => '@#1{#3}#1{#4}#1');
115
116# This isn't really having the desired effect when transformed to MathML and
117# displayed in Firefox.... have I got it right; has Firefox???
118DefMath('\leftarrowfill@',  "\x{2190}", role => 'ARROW', stretchy => 'true');
119DefMath('\rightarrowfill@', "\x{2192}", role => 'ARROW', stretchy => 'true');
120
121DefRegister('\minCDarrowwidth' => Dimension('2.5pc'));
122
123#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
124
1251;
126