1# -*- mode: Perl -*- 2# /=====================================================================\ # 3# | AmSTeX.pool | # 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# This is the `pool' for AmSTeX (_not_ AMS LaTeX) 24# It should be loaded by LoadPool("AmSTeX"), or 25# indirectly via \input amstex 26# (from TeX mode, ie. before and without LaTeX.pool being loaded) 27# This should put LaTeXML into "amstex mode" 28# 29# Since amstex uses \documentstyle, we _must_ define it here to 30# keep TeX.pool from anticipating LaTeX mode and loading LaTeX.pool! 31#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 32RequireResource('ltx-amsart.css'); # hopefully close enough... 33 34DefConstructorI('\AmSTeX', undef, 'AMSTeX'); 35DefMacro('\fmtname', 'AmS-TeX'); 36DefMacro('\fmtversion', '2.1'); 37Let('\plainfmtversion', '\fmtversion'); 38 39DefPrimitive('\define SkipSpaces Token UntilBrace {}', sub { 40 my ($stomach, $cs, $params, $body) = @_; 41 $params = parseDefParameters($cs, $params); # in TeX.pool 42 if (LookupDefinition($cs)) { 43 Info('ignore', $cs, $stomach, 44 "Ignoring redefinition (\\define) of '" . ToString($cs) . "'"); 45 return; } 46 DefMacroI($cs, $params, $body); 47 return; }); 48 49DefPrimitive('\redefine SkipSpaces Token UntilBrace {}', sub { 50 my ($stomach, $cs, $params, $body) = @_; 51 $params = parseDefParameters($cs, $params); # in TeX.pool 52 DefMacroI($cs, $params, $body); 53 return; }); 54 55DefPrimitive('\predefine Token Token', sub { 56 Let($_[1], $_[2]); }); 57 58DefPrimitive('\undefine Token', sub { 59 my ($stomach, $cs) = @_; 60 Let($_[1], '\relax'); }); 61 62#====================================================================== 63# Style choices 64 65DefConstructor('\documentstyle Semiverbatim', 66 "<?latexml class='#1' amstex='true'?>", 67 afterDigest => sub { 68 my ($stomach, $whatsit) = @_; 69 my $style = ToString($whatsit->getArg(1)); 70 # Load the package, but note that we're pretending it's a class (to some extent!) 71 RequirePackage($style, type => 'sty', notex => 1, as_class => 1) 72 || RequirePackage('amsppt'); 73 return; }); 74 75DefMacro('\NoPageNumbers', ''); 76 77DefMacro('\BlackBoxes', ''); # These control whether overfull boxes show black; Ignorable 78DefMacro('\NoBlackBoxes', ''); 79 80DefMacro('\TagsAsMath', ''); 81DefMacro('\TagsAsText', ''); 82 83DefMacro('\TagsOnLeft', ''); 84DefMacro('\TagsOnRight', ''); 85 86DefMacro('\CenteredTagsOnSplits', ''); 87DefMacro('\TopOrBottomTagsOnSplits', ''); 88 89DefMacro('\LimitsOnInts', ''); 90DefMacro('\NoLimitsOnInts', ''); 91DefMacro('\LimitsOnNames', ''); 92DefMacro('\NoLimitsOnNames', ''); 93DefMacro('\LimitsOnSums', ''); 94DefMacro('\NoLimitsOnSums', ''); 95 96# These presumably load fonts (or commands?) 97DefMacro('\UseAMSsymbols', ''); 98DefMacro('\loadbold', ''); 99DefMacro('\loadeufb', ''); 100DefMacro('\loadeufm', ''); 101DefMacro('\loadeurb', ''); 102DefMacro('\loadeurm', ''); 103DefMacro('\loadeusb', ''); 104DefMacro('\loadeusm', ''); 105DefMacro('\loadmathfont', ''); 106DefMacro('\loadmsam', ''); 107DefMacro('\loadmsbm', ''); 108Let('\font@', '\font'); # Close enough? 109 110DefMacro('\boldnotloaded{}', ''); 111 112DefMacro('\galleys', ''); 113DefMacro('\flushpar', '\par\noindent'); 114 115DefMacro('\pagewidth{Dimension}', ''); 116DefMacro('\pageheight{Dimension}', ''); 117DefMacro('\hcorrection{Dimension}', ''); 118DefMacro('\vcorrection{Dimension}', ''); 119 120#====================================================================== 121# The Document 122DefConstructor('\document', "<ltx:document>", 123 afterDigest => sub { AssignValue(inPreamble => 0); }); 124DefConstructor('\enddocument', "</ltx:document>", 125 beforeDigest => sub { 126 $_[0]->getGullet->flush; 127 return; }); 128 129#====================================================================== 130# Front Matter 131 132DefMacro('\topmatter', ''); 133DefMacro('\endtopmatter', ''); 134DefMacro('\title Until:\endtitle', '\@add@frontmatter{ltx:title}{#1}'); 135DefConstructor('\@personname{}', "<ltx:personname>#1</ltx:personname>", 136 bounded => 1, mode => 'text'); 137DefMacro('\author Until:\endauthor', '\@add@frontmatter{ltx:creator}[role=author]{\@personname{#1}}'); 138DefConstructor('\@institute{}', "<ltx:contact role='institute'>#1</ltx:contact>", bounded => 1); 139DefMacro('\thanks Until:\endthanks', '\@add@to@frontmatter{ltx:creator}{\@institute{#1}}'); 140DefMacro('\abstract Until:\endabstract', '\@add@frontmatter{ltx:abstract}{#1}'); 141 142#====================================================================== 143# Document structure 144# See amsppt.sty or ... 145DefMacro('\nofrills', ''); 146 147DefPrimitive('\comment', sub { 148 my ($stomach, $line) = @_; 149 my $gullet = $stomach->getGullet; 150 $gullet->readRawLine; # IGNORE 1st line (after the \begin{$name} !!! 151 while (defined($line = $gullet->readRawLine) && ($line ne '\endcomment')) { 152 } 153 return; }); 154 155Let('\plainproclaim', '\proclaim'); 156Let('\plainfootnote', '\footnote'); 157RawTeX('\newbox\tocbox@'); 158#====================================================================== 159# Text level stuff 160 161DefMacro('\newline', "\n"); 162 163DefPrimitiveI('\textfonti', undef, '', 164 font => { family => 'serif', series => 'medium', shape => 'upright' }); 165DefPrimitiveI('\textfontii', undef, '', 166 font => { family => 'serif', series => 'medium', shape => 'upright', size => 9 }); 167 168DefConstructor('\spreadlines {Dimension}', ''); 169 170DefPrimitive('\pagebreak', undef); 171DefPrimitive('\nopagebreak', undef); 172DefPrimitive('\smallpagebreak', undef); 173DefPrimitive('\medpagebreak', undef); 174DefPrimitive('\bigpagebreak', undef); 175 176DefPrimitive('\allowlinebreak', undef); 177DefPrimitive('\allowmathbreak', undef); 178DefPrimitive('\linebreak', undef); 179DefPrimitive('\nolinebreak', undef); 180DefPrimitive('\mathbreak', undef); 181DefPrimitive('\nomathbreak', undef); 182DefPrimitive('\allowdisplaybreaks', undef); 183DefPrimitive('\allowdisplaybreak', undef); 184 185DefMacro('\tie', '\unskip\nobreak\ '); 186Let('\graveaccent', "\\`"); 187Let('\acuteaccent', "\\'"); 188Let('\tildeaccent', "\\~"); 189Let('\hataccent', "\\^"); 190Let('\underscore', "\\_"); 191Let('\B', "\\="); 192Let('\D', "\\."); 193 194DefMacro('\.', '. '); 195 196#====================================================================== 197# Math stuff. 198 199# We'd like to be able to leverage the ams (LaTeX) packages we've already written. 200# However, they were written in the context of LaTeX, and assume LaTeX.pool was loaded. 201# We either need to duplicate them, or alter them to be aware of LaTeX vs AMSTeX mode! 202# Especially, DefEnvironment is to be avoided! (or usurped!!) 203 204# We need stuff from amsmath, BUT it shouldn't define "environments", 205# rather \foo ... \endfoo.... 206# But, of course, DefEnvironment, DOES do that! 207# Will this work???? 208# The question is whether AMSTeX's \foo..\endfoo incorporates \begingroup/\endgroup pairs? 209# MOST Likely, all of amsmath will need to be redone here, since the argument patterns are 210# so different! The rest are probably OK. 211RequirePackage('amsmath'); 212RequirePackage('amssymb'); 213RequirePackage('amsfonts'); 214RequirePackage('amsopn'); 215RequirePackage('amsxtra'); 216RequirePackage('amscd'); 217 218Let('\dsize', '\displaystyle'); 219Let('\tsize', '\textstyle'); 220Let('\ssize', '\scriptstyle'); 221Let('\sssize', '\scriptscriptstyle'); 222Let('\tag', '\eqno'); 223DefMath('\and', '\&', role => 'ADDOP', meaning => 'and'); 224DefConstructor("\\\\", 225 "?#isMath(<ltx:XMHint name='newline'/>)(<ltx:break/>)", 226 reversion => Tokens(T_CS("\\\\"), T_CR)); 227 228# This is an analog to \align's template, but hopefully we can just ignore it??? 229DefMacro("\\format Until:\\\\", ''); 230 231DefConstructor('\text {}', 232 "<ltx:text _noautoclose='1'>#1</ltx:text>", mode => 'text'); 233 234DefConstructor('\overset Until:\to {}', 235 "<ltx:XMApp>" 236 . "<ltx:XMWrap role='OVERACCENT'>#1</ltx:XMWrap>" 237 . "<ltx:XMArg>#2</ltx:XMArg>" 238 . "</ltx:XMApp>"); 239DefConstructor('\underset Until:\to {}', 240 "<ltx:XMApp>" 241 . "<ltx:XMWrap role='UNDERACCENT'>#1</ltx:XMWrap>" 242 . "<ltx:XMArg>#2</ltx:XMArg>" 243 . "</ltx:XMApp>"); 244 245DefMacro('\oversetbrace Until:\to {}', '\overbrace{#2}^{#1}'); 246DefMacro('\undersetbrace Until:\to {}', '\underbrace{#2}^{#1}'); 247 248Let('\overarrow', '\overrightarrow'); 249Let('\underarrow', '\underrightarrow'); 250 251DefConstructor('\frac InFractionStyle InFractionStyle', 252 "<ltx:XMApp>" 253 . "<ltx:XMTok meaning='divide' role='FRACOP' mathstyle='#mathstyle'/>" 254 . "<ltx:XMArg>#1</ltx:XMArg><ltx:XMArg>#2</ltx:XMArg>" 255 . "</ltx:XMApp>", 256 sizer => sub { fracSizer($_[0]->getArg(1), $_[0]->getArg(2)); }, 257 properties => { mathstyle => sub { LookupValue('font')->getMathstyle; } }); 258 259DefConstructor('\Cal{}', '#1', bounded => 1, requireMath => 1, 260 font => { family => 'caligraphic', series => 'medium', shape => 'upright' }); 261 262# \bold in amsfonts 263DefConstructor('\roman{}', '#1', bounded => 1, requireMath => 1, 264 font => { family => 'serif', series => 'medium', shape => 'upright' }); 265DefConstructor('\italic{}', '#1', bounded => 1, requireMath => 1, 266 font => { shape => 'italic', series => 'medium', shape => 'upright' }); 267DefConstructor('\slanted{}', '#1', bounded => 1, requireMath => 1, 268 font => { shape => 'slanted', series => 'medium', shape => 'upright' }); 269DefConstructor('\boldkey{}', '#1', bounded => 1, requireMath => 1, 270 font => { series => 'bold', family => 'typewriter', series => 'medium', shape => 'upright' }); 271 272# holy cow... 273DefMacro('\thickfrac', sub { 274 ($_[0]->ifNext('\thickness') ? T_CS('\@thickfrac') : T_CS('\frac')); }); 275DefMacro('\@thickfrac Token Number {}{}', '\genfrac{}{}{#2}{}{#3}{#4}'); 276 277DefMacro('\thickfracwithdelims{}{}', sub { 278 (($_[0]->ifNext('\thickness') ? T_CS('\@thickfracwithdelims') : T_CS('\fracwithdelims')), $_[1], $_[2]); }); 279DefMacro('\@thickfracwithdelims {}{} Token Number {}{}', '\genfrac{#1}{#2}{#4}{}{#5}{#6}'); 280 281DefMacro('\spcheck', '^{\vee}'); 282DefMacro('\sptilde', '^{\sim}'); 283DefMacro('\spacute', "^{'}"); 284DefMacro('\spgrave', "^{`}"); 285DefMacro('\spdot', "^{.}"); 286DefMacro('\spddot', "^{..}"); 287DefMacro('\spdddot', "^{...}"); 288DefMacro('\spddddot', "^{....}"); 289DefMacro('\spbreve', "^{\\hbox{\\u{}}}"); 290DefMacro('\spbar', "^{-}"); 291DefMacro('\spvec', "^{\\rightarrow}"); 292 293# \boldsymbol{} 294# Note this is really messed up. \boldsymbol doesn't necessarily just expand, 295# it recognizes certain arguments specially. Among other things this allows perversities like: 296# \redefine\cdot{\boldsymbol\cdot} 297DefMathI('\lx@ams@boldsymbol@cdot', undef, "\x{22C5}", role => 'MULOP', 298 bounded => 1, font => { forcebold => 1 }); 299DefMathI('\lx@ams@boldsymbol@prime', undef, "\x{2032}", role => 'SUPOP', locked => 1, 300 bounded => 1, font => { forcebold => 1 }); 301DefMathI('\lx@ams@boldsymbol@lbrack', undef, '[', role => 'OPEN', stretchy => 'false', 302 bounded => 1, font => { forcebold => 1 }); 303DefMathI('\lx@ams@boldsymbol@rbrack', undef, ']', role => 'CLOSE', stretchy => 'false', 304 bounded => 1, font => { forcebold => 1 }); 305DefMathI('\lx@ams@boldsymbol@lbrace', undef, '{', role => 'OPEN', stretchy => 'false', alias => '\{', 306 bounded => 1, font => { forcebold => 1 }); 307DefMathI('\lx@ams@boldsymbol@rbrace', undef, '}', role => 'CLOSE', stretchy => 'false', alias => '\}', 308 bounded => 1, font => { forcebold => 1 }); 309DefMathI('\lx@ams@boldsymbol@surd', undef, "\x{221A}", role => 'OPERATOR', meaning => 'square-root', 310 bounded => 1, font => { forcebold => 1 }); 311DefMathI('\lx@ams@boldsymbol@S', undef, UTF(0xa7), 312 bounded => 1, font => { forcebold => 1 }); 313DefMathI('\lx@ams@boldsymbol@P', undef, UTF(0xB6), 314 bounded => 1, font => { forcebold => 1 }); 315DefMathI('\lx@ams@boldsymbol@dag', undef, "\x{2020}", 316 bounded => 1, font => { forcebold => 1 }); 317DefMathI('\lx@ams@boldsymbol@ddag', undef, "\x{2021}", 318 bounded => 1, font => { forcebold => 1 }); 319 320DefConstructor('\lx@ams@boldsymbol@{}', '#1', 321 bounded => 1, requireMath => 1, font => { forcebold => 1 }); 322 323DefMacro('\boldsymbol DefToken', sub { 324 my ($gullet, $token) = @_; 325 my $name = ToString($token); $name =~ s/^\\//; 326 my $btoken = T_CS('\lx@ams@boldsymbol@' . $name); 327 return (IsDefined($btoken) ? ($btoken) : (T_CS('\lx@ams@boldsymbol@'), $token)); }); 328 329# Ignore these? 330DefRegister('\buffer' => Dimension(0)); 331DefMacro('\ChangeBuffer Dimension', '\buffer#2\relax'); 332DefMacro('\ResetBuffer', ''); 333DefMacro('\shave{}', '#1'); 334DefMacro('\botshave{}', '#1'); 335DefMacro('\topshave{}', '#1'); 336 337DefMacro('\minCDarrowwidth Dimension', ''); 338DefMacro('\pretend Until:\haswidth {}', '#1'); 339 340DefMacro('\snug', ''); 341DefConstructor('\topsmash{}', "#1"); 342DefConstructor('\botsmash{}', "#1"); 343 344DefConstructor('\spreadmatrixlines Dimension', ''); 345 346DefMacro('\MultlineGap Dimension', ''); 347DefMacro('\multlinegap Dimension', ''); 348DefMacro('\nomultlinegap', ''); 349 350DefMacro('\innerhdotsfor Number Match:\after {}', sub { 351 (map { '\hdots' } 1 .. $_[1]->valueOf); }); 352DefMacro('\spacehdots Number Match:\for Number', sub { 353 (map { '\hdots' } 1 .. $_[1]->valueOf); }); 354DefMacro('\spaceinnerhdots Number Match:\for Number Match:\after {}', sub { 355 (map { '\hdots' } 1 .. $_[1]->valueOf); }); 356 357DefMacro('\foldedtext', sub { 358 my ($gullet) = @_; 359 if ($gullet->ifNext('\foldedwidth')) { 360 $gullet->readToken; $gullet->readDimension; } # ignore? 361 T_CS('\text'); }); 362 363Let('\topfoldedtext', '\foldedtext'); 364Let('\botfoldedtext', '\foldedtext'); 365 366# Maybe? 367DefMacro('\Sb Until:\endSb', '_{\substack{#1}}'); 368DefMacro('\Sp Until:\endSp', '^{\substack{#1}}'); 369Let('\endSb', '\relax'); 370Let('\endSp', '\relax'); 371 372DefMacro('\thetag', sub { T_OTHER(LookupValue('EQUATIONROW_NUMBER')); }); # ? 373 374DefMacro('\topaligned', '\aligned[t]'); 375Let('\endtopaligned', '\endaligned'); 376DefMacro('\botaligned', '\aligned[b]'); 377Let('\endbotaligned', '\endaligned'); 378 379# close enough? 380DefMacro('\accentedsymbol{}{}', '\def#1{#2}'); 381 382# Tricky: 383# \cfrac, \lcfrac, \endcfrac 384DefConstructor('\cfrac', '', 385 afterDigest => sub { 386 my ($stomach) = @_; 387 $stomach->bgroup; 388 Let(T_CS("\\\\"), T_CS('\lx@cfrac')); }); 389DefConstructor('\endcfrac', '', 390 afterDigest => sub { 391 my ($stomach) = @_; 392 $stomach->egroup; }); 393 394# These really need a way to pass denomalign=left|right to the MathML! 395Let('\lcfrac', '\cfrac'); 396Let('\rcfrac', '\cfrac'); 397 398DefMacro('\lx@cfrac', 399 '\lx@generalized@over{\\\\}{meaning=continued-fraction,role=MULOP}\displaystyle'); 400 401#====================================================================== 402# Bibliography 403# See amsppt.sty 404 405#====================================================================== 406# Dubious 407RawTeX(<<'EoTeX'); 408\def\vspace@{\def\vspace##1{\crcr\noalign{\vskip##1\relax}}} 409\newdimen\captionwidth@ 410\newdimen\smallcaptionwidth@ 411\newdimen\ex@ 412\newdimen\buffer@ 413\newdimen\spreadmlines@ 414\newdimen\lwidth@ 415\newdimen\rwidth@ 416\newdimen\maxlwidth@ 417\newdimen\maxrwidth@ 418\newdimen\totwidth@ 419\newdimen\lineht@ 420\newdimen\gwidth@ 421\newdimen\gmaxwidth@ 422\newdimen\glineht@ 423\newdimen\multlinegap@ 424\newdimen\multlinetaggap@ 425\newdimen\mwidth@ 426\newdimen\mlineht@ 427\newdimen\ltwidth@ 428\newdimen\rtwidth@ 429\newdimen\accentdimen@ 430\newdimen\minaw@ 431\newdimen\minCDaw@ 432\newdimen\bigaw@ 433\newdimen\pmbraise@ 434\newtoks\hashtoks@ 435EoTeX 436 437DefMacro('\printoptions', ''); 438DefMacro('\showallocations', ''); 439DefMacro('\syntax', ''); 4401; 441