# -*- mode: Perl -*- # /=====================================================================\ # # | xy | # # | Implementation for LaTeXML | # # |=====================================================================| # # | Part of LaTeXML: | # # | Public domain software, produced as part of work done by the | # # | United States Government & not subject to copyright in the US. | # # |---------------------------------------------------------------------| # # | Bruce Miller #_# | # # | http://dlmf.nist.gov/LaTeXML/ (o o) | # # \=========================================================ooo==U==ooo=/ # package LaTeXML::Package::Pool; use strict; use warnings; use LaTeXML::Package; # Load the raw TeX implementation # But IMPORTANTLY: do NOT reassign the catcode of @, # as it fouls up all xy's catcode management! InputDefinitions('xy', type => 'tex', noltxml => 1, at_letter => 0); # Redefine \xyoption to avoid other drivers Let('\lx@xy@xyoption@orig', '\xyoption'); # Prevent loading of incompatible drivers our %xy_other_drivers = map { ($_ => 1); } qw(16textures 17oztex dvidrv dvips dvitops oztex pdf textures dvi); our %xy_unsupported = map { ($_ => 1); } qw(barr movie necula smart); DefMacro('\xyoption{}', sub { my ($gullet, $option) = @_; $option = Tokens(Expand($option)); my $option_s = ToString($option); if ($xy_other_drivers{$option_s}) { Info('xy', 'ignored', $gullet, "Ignoring xy driver $option_s (using latexml)"); return; } elsif ($xy_unsupported{$option}) { Warn('xy', 'unsupported', $gullet, "The xy extension/feature $option_s may not be supported"); } my $cache_key = "loaded_xyoption_$option_s"; if (LookupValue($cache_key)) { Info('xy', 'ignored', "xyoption $option_s was requested twice, not reloading"); return (); } else { Note("loading xyoption $option_s."); AssignValue($cache_key, 1, 'global'); return Tokens(T_CS('\lx@xy@xyoption@orig'), T_BEGIN, $option, T_END); } }, locked => 1); # Redefine so we get more tracable/debugable info DefPrimitive('\xywarning@{}', sub { Info('xy', 'warning', $_[0], ToString($_[1])); }); DefPrimitive('\xyerror@{}{}', sub { Info('xy', 'error', $_[0], ToString($_[1]), ToString($_[2])); }); # Is this safe for non-LaTeX ?? # We need to defer till AFTER extensions/features are loaded! # ORR we need to implement the activate machinery! RawTeX('\AtBeginDocument{\xyoption{latexml}}'); # ORRRRR is \activatedriver (or related) the right place to load/turn on???? ###################################################################### # Cribbed from Deyan's version # TODO: Reconsider if this is the best we can do about the XY fonts? # At least, avoid the warning... foreach ('dash', 'atip', 'btip', 'bsql', 'circ') { DefPrimitiveI( "\\xy$_" . "font", undef, undef, font => { family => 'nullfont' }, locked => 1 ); } # Note that xy heavily uses grouping to limit scope of image data # and \edef to smuggle recorded data out of the groups. # We can use the Digested parameter type here to capture a Box, # since \xy starts with an \hbox \bgroup, and \endxy contains a matching \egroup. # However, we have to take steps to capture the size before that group ends! DefConstructor('\lx@xy@svgnested Digested', "#1", properties => sub { my ($x0, $y0, $x1, $y1) = @{ LookupValue('saved_xy_range') || [Dimension(0), Dimension(0), Dimension(0), Dimension(0)] }; Debug("Nested XY: " . ToString($x0) . ' ' . ToString($y0) . ' ' . ToString($x1) . ' ' . ToString($y1)) if $LaTeXML::DEBUG{xy}; my $w = $x1->subtract($x0); my $h = $y1->subtract($y0); my $x = $x0->larger(Dimension(0)); # negate here, not below! my $y = Dimension(0); if (LookupValue('IN_MATH')) { # Vertically center, when in math $y = $y->subtract($h->multiply(0.5)); } my $transform = "matrix(1 0 0 1 " . $x->pxValue . ' ' . $y->pxValue . ')'; return (width => $w, height => $y1, depth => $y0->negate, transform => $transform); }); DefConstructor('\lx@xy@svg Digested', "" . "#1" . "", properties => sub { my ($x0, $y0, $x1, $y1) = @{ LookupValue('saved_xy_range') || [Dimension(0), Dimension(0), Dimension(0), Dimension(0)] }; Debug("XY: " . ToString($x0) . ' ' . ToString($y0) . ' ' . ToString($x1) . ' ' . ToString($y1)) if $LaTeXML::DEBUG{xy}; my $w = $x1->subtract($x0); my $h = $y1->subtract($y0); my $x = $x0->negate->larger(Dimension(0)); my $yma = Dimension(LookupValue('IN_MATH') ? '2.5pt' : 0); # math-axis; fontdimen 22 my $y = $y1->add($yma->subtract($y0->larger(Dimension(0)))); my $transform = "matrix(1 0 0 -1 " . $x->pxValue . ' ' . $y->pxValue . ')'; Debug("XY size: " . ToString($w) . ' x ' . ToString($h) . ' + ' . 0 . ' @ ' . ToString($x) . ' x ' . ToString($y)) if $LaTeXML::DEBUG{xy}; return (width => $w, height => $h, pxwidth => $w->pxValue, pxheight => $h->pxValue, transform => $transform); }); DefPrimitive('\lx@xy@capturerange', sub { my ($stomach) = @_; AssignValue('saved_xy_range' => [map { LookupRegister($_); } '\X@min', '\Y@min', '\X@max', '\Y@max'], 'global'); }); Let(T_CS('\lx@xy@original'), T_CS('\xy')); Let(T_CS('\end@lx@xy@original'), T_CS('\endxy')); DefMacro('\xy', '\if\inxy@\lx@xy@svgnested\else\lx@xy@svg\fi\lx@xy@original'); DefMacro('\endxy', '\relax\lx@xy@capturerange\end@lx@xy@original'); #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1;