1# /=====================================================================\ # 2# | LaTeXML::Common::Glue | # 3# | Representation of Stretchy dimensions | # 4# |=====================================================================| # 5# | Part of LaTeXML: | # 6# | Public domain software, produced as part of work done by the | # 7# | United States Government & not subject to copyright in the US. | # 8# |---------------------------------------------------------------------| # 9# | Bruce Miller <bruce.miller@nist.gov> #_# | # 10# | http://dlmf.nist.gov/LaTeXML/ (o o) | # 11# \=========================================================ooo==U==ooo=/ # 12package LaTeXML::Common::Glue; 13use LaTeXML::Global; 14use strict; 15use warnings; 16use base qw(LaTeXML::Common::Dimension); 17use base qw(Exporter); 18our @EXPORT = (qw(&Glue)); 19 20#====================================================================== 21# Exported constructor. 22 23sub Glue { 24 my ($scaledpoints, $plus, $pfill, $minus, $mfill) = @_; 25 return LaTeXML::Common::Glue->new($scaledpoints, $plus, $pfill, $minus, $mfill); } 26 27#====================================================================== 28 29my %fillcode = (fil => 1, fill => 2, filll => 3); # [CONSTANT] 30my @FILL = ('', 'fil', 'fill', 'filll'); # [CONSTANT] 31 32my $num_re = qr/\d*\.?\d*/; # [CONSTANT] 33my $unit_re = qr/[a-zA-Z][a-zA-Z]/; # [CONSTANT] 34my $fill_re = qr/fil|fill|filll|[a-zA-Z][a-zA-Z]/; # [CONSTANT] 35my $plus_re = qr/\s+plus\s*($num_re)($fill_re)/; # [CONSTANT] 36my $minus_re = qr/\s+minus\s*($num_re)($fill_re)/; # [CONSTANT] 37our $GLUE_re = qr/(\+?\-?$num_re)($unit_re)($plus_re)?($minus_re)?/; # [CONSTANT] 38 39sub new { 40 my ($class, $sp, $plus, $pfill, $minus, $mfill) = @_; 41 $sp = ToString($sp) if ref $sp; 42 $plus = ToString($plus) if ref $plus; 43 $pfill = ToString($pfill) if ref $pfill; 44 $minus = ToString($minus) if ref $minus; 45 $mfill = ToString($mfill) if ref $mfill; 46 if ((!defined $plus) && (!defined $pfill) && (!defined $minus) && (!defined $mfill)) { 47 if ($sp =~ /^(\d*\.?\d*)$/) { } 48 elsif ($sp =~ /^$GLUE_re$/) { 49 my ($f, $u, $p, $pu, $m, $mu) = ($1, $2, $4, $5, $7, $8); 50 $sp = $f * $STATE->convertUnit($u); 51 if (!$pu) { } 52 elsif ($fillcode{$pu}) { $plus = $p; $pfill = $pu; } 53 else { $plus = $p * $STATE->convertUnit($pu); $pfill = 0; } 54 if (!$mu) { } 55 elsif ($fillcode{$mu}) { $minus = $m; $mfill = $mu; } 56 else { $minus = $m * $STATE->convertUnit($mu); $mfill = 0; } 57 } } 58 return bless [$sp || "0", $plus || "0", $pfill || 0, $minus || "0", $mfill || 0], $class; } 59 60#sub getStretch { $_[0]->[1]; } 61#sub getShrink { $_[0]->[2]; } 62 63sub toString { 64 my ($self) = @_; 65 my ($sp, $plus, $pfill, $minus, $mfill) = @$self; 66 my $string = LaTeXML::Common::Dimension::pointformat($sp); 67 $string .= ' plus ' . ($pfill 68 ? $plus . $FILL[$pfill] 69 : LaTeXML::Common::Dimension::pointformat($plus)) 70 if $plus != 0; 71 $string .= ' minus ' . ($mfill 72 ? $minus . $FILL[$mfill] 73 : LaTeXML::Common::Dimension::pointformat($minus)) 74 if $minus != 0; 75 return $string; } 76 77sub toAttribute { 78 my ($self) = @_; 79 my ($sp, $plus, $pfill, $minus, $mfill) = @$self; 80 my $string = LaTeXML::Common::Dimension::attributeformat($sp); 81 $string .= ' plus ' . ($pfill 82 ? $plus . $FILL[$pfill] 83 : LaTeXML::Common::Dimension::attributeformat($plus)) 84 if $plus != 0; 85 $string .= ' minus ' . ($mfill 86 ? $minus . $FILL[$mfill] 87 : LaTeXML::Common::Dimension::attributeformat($minus)) 88 if $minus != 0; 89 return $string; } 90 91sub negate { 92 my ($self) = @_; 93 my ($pts, $p, $pf, $m, $mf) = @$self; 94 return (ref $self)->new(-$pts, -$p, $pf, -$m, $mf); } 95 96sub add { 97 my ($self, $other) = @_; 98 my ($pts, $p, $pf, $m, $mf) = @$self; 99 if (ref $other eq 'LaTeXML::Common::Glue') { 100 my ($pts2, $p2, $pf2, $m2, $mf2) = @$other; 101 $pts += $pts2; 102 if ($pf == $pf2) { $p += $p2; } 103 elsif ($pf < $pf2) { $p = $p2; $pf = $pf2; } 104 if ($mf == $mf2) { $m += $m2; } 105 elsif ($mf < $mf2) { $m = $m2; $mf = $mf2; } 106 return (ref $self)->new($pts, $p, $pf, $m, $mf); } 107 else { 108 return (ref $self)->new($pts + $other->valueOf, $p, $pf, $m, $mf); } } 109 110sub multiply { 111 my ($self, $other) = @_; 112 my ($pts, $p, $pf, $m, $mf) = @$self; 113 $other = $other->valueOf if ref $other; 114 return (ref $self)->new($pts * $other, $p * $other, $pf, $m * $other, $mf); } 115 116sub divide { 117 my ($self, $other) = @_; 118 my ($pts, $p, $pf, $m, $mf) = @$self; 119 $other = $other->valueOf if ref $other; 120 return (ref $self)->new($pts / $other, $p / $other, $pf, $m / $other, $mf); } 121 122sub divideround { 123 my ($self, $other) = @_; 124 my ($pts, $p, $pf, $m, $mf) = @$self; 125 $other = $other->valueOf if ref $other; 126 return (ref $self)->new($pts / $other, $p / $other, $pf, $m / $other, $mf); } 127 128sub stringify { 129 my ($self) = @_; 130 return "Glue[" . join(',', @$self) . "]"; } 131 132#====================================================================== 1331; 134 135__END__ 136 137=pod 138 139=head1 NAME 140 141C<LaTeXML::Common::Glue> - representation of glue, skips, stretchy dimensions; 142extends L<LaTeXML::Common::Dimension>. 143 144=head2 Exported functions 145 146=over 4 147 148=item C<< $glue = Glue($gluespec); >> 149 150=item C<< $glue = Glue($sp,$plus,$pfill,$minus,$mfill); >> 151 152Creates a Glue object. C<$gluespec> can be a string in the 153form that TeX recognizes (number units optional plus and minus parts). 154Alternatively, the dimension, plus and minus parts can be given separately: 155C<$pfill> and C<$mfill> are 0 (when the C<$plus> or C<$minus> part is in sp) 156or 1,2,3 for fil, fill or filll. 157 158=back 159 160=head1 AUTHOR 161 162Bruce Miller <bruce.miller@nist.gov> 163 164=head1 COPYRIGHT 165 166Public domain software, produced as part of work done by the 167United States Government & not subject to copyright in the US. 168 169=cut 170 171