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