line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Number::WithError::LaTeX; |
2
|
|
|
|
|
|
|
|
3
|
6
|
|
|
6
|
|
104007
|
use 5.008; |
|
6
|
|
|
|
|
19
|
|
|
6
|
|
|
|
|
221
|
|
4
|
6
|
|
|
6
|
|
31
|
use strict; |
|
6
|
|
|
|
|
11
|
|
|
6
|
|
|
|
|
201
|
|
5
|
6
|
|
|
6
|
|
30
|
use warnings; |
|
6
|
|
|
|
|
7
|
|
|
6
|
|
|
|
|
303
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $VERSION = '0.06'; |
8
|
|
|
|
|
|
|
|
9
|
6
|
|
|
6
|
|
27
|
use base 'Number::WithError'; |
|
6
|
|
|
|
|
8
|
|
|
6
|
|
|
|
|
6205
|
|
10
|
|
|
|
|
|
|
|
11
|
6
|
|
|
6
|
|
92061
|
use base 'Exporter'; |
|
6
|
|
|
|
|
15
|
|
|
6
|
|
|
|
|
366
|
|
12
|
|
|
|
|
|
|
our %EXPORT_TAGS = %Number::WithError::EXPORT_TAGS; |
13
|
|
|
|
|
|
|
our @EXPORT_OK = @Number::WithError::EXPORT_OK; |
14
|
|
|
|
|
|
|
|
15
|
6
|
|
|
6
|
|
9359
|
use TeX::Encode; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
use Encode (); |
17
|
|
|
|
|
|
|
use Carp qw/croak/; |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
sub witherror { Number::WithError::LaTeX->new(@_) } |
20
|
|
|
|
|
|
|
sub witherror_big { Number::WithError::LaTeX->new_big(@_) } |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
use Params::Util qw/_ARRAY0/; |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
=head1 NAME |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
Number::WithError::LaTeX - LaTeX output for Number::WithError |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
=head1 SYNOPSIS |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
use Number::WithError::LaTeX; |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
my $num = Number::WithError::LaTeX->new(5.647, 0.31); |
34
|
|
|
|
|
|
|
print $num . "\n"; |
35
|
|
|
|
|
|
|
# prints '5.65e+00 +/- 3.1e-01' |
36
|
|
|
|
|
|
|
# (I.e. it automatically does scientific rounding) |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
print $num->latex() . "\n"; |
39
|
|
|
|
|
|
|
# prints '5.65 \cdot 10^{0} \pm 3.1 \cdot 10^{-1}' |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
print $num->latex(radix => ',', enclose => '$') . "\n"; |
42
|
|
|
|
|
|
|
# prints '$5,\!65 \cdot 10^{0} \pm 3,\!1 \cdot 10^{-1}$' |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
print $num->encode("This will encode an e-acute (".chr(0xe9).") as \\'e") . "\n"; |
45
|
|
|
|
|
|
|
# Delegated to TeX::Encode::encode(). |
46
|
|
|
|
|
|
|
# prints 'This is a German umlaut: \"a' |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
=head1 DESCRIPTION |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
This class is a subclass of L. It provides the same |
51
|
|
|
|
|
|
|
interface and the same exports. |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
It adds several methods to every object. The main functionality is provided by |
54
|
|
|
|
|
|
|
C, which dumps the object |
55
|
|
|
|
|
|
|
as valid LaTeX code. Also, C is a convenient way to encode |
56
|
|
|
|
|
|
|
any UTF-8 string into TeX. It is just a convenience thing since it is delegated |
57
|
|
|
|
|
|
|
to L. |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
Unlike C, this module requires perl version 5.8 or later. |
60
|
|
|
|
|
|
|
(That is the rationale for creating a separate distribution, too.) |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
=head1 EXPORT |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
This module exports the following subroutines on demand. It supports |
65
|
|
|
|
|
|
|
the C<:all> Exporter tag to export all of them. The subroutines are |
66
|
|
|
|
|
|
|
documented in L. |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
=head2 witherror |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
=head2 witherror_big |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
=cut |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
=head1 METHODS |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
This is a list of public methods. |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
=head2 latex |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
This method stringifies the object as valid LaTeX code. The returned |
81
|
|
|
|
|
|
|
string is valid in a LaTeX math mode. That means, you will have to |
82
|
|
|
|
|
|
|
enclose it in dollars or in an C environment by default. |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
The method takes named parameters. All parameters are optional. |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
The C parameter can set a string to enclose the produced |
87
|
|
|
|
|
|
|
latex code in. This can be either a simple string like C<$> or an |
88
|
|
|
|
|
|
|
array reference containing two strings. Those two strings will be |
89
|
|
|
|
|
|
|
used for the start and end respectively. (For environments.) |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
Example: (let C<$obj> be '5.6e-01 +/- 2.3e-02') |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
$obj->latex(enclose => '$'); |
94
|
|
|
|
|
|
|
# returns '$5.6 \cdot 10^{-1} \pm 2.3 \cdot 10^{-2}$' |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
The asymmetric environment-like C can be used as follows: |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
$obj->latex(enclose => ['\begin{equation}', '\end{equation}']); |
99
|
|
|
|
|
|
|
# returns'\begin{equation}5.6 \cdot 10^{-1} \pm 2.3 \cdot 10^{-2}\end{equation}' |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
There are two convenience methods C and C which do |
102
|
|
|
|
|
|
|
exactly what the above examples demonstrated. |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
The C parameter can set the radix (I) used. The default is |
105
|
|
|
|
|
|
|
a dot (C<.>). If you use a comma, LaTeX will generally typeset it in a way that |
106
|
|
|
|
|
|
|
results in a space after the comma. Since that is not desireable, using a C<,> |
107
|
|
|
|
|
|
|
as the radix results in the radix being set as C<,\!>. An example can be found |
108
|
|
|
|
|
|
|
in the synopsis. |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
=cut |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
our $CFloatCapture = qr/([+-]?)(?=\d|\.\d)(\d*(?:\.\d*)?)((?:[Ee][+-]?\d+)?)/; |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
sub latex { |
115
|
|
|
|
|
|
|
my $self = shift; |
116
|
|
|
|
|
|
|
croak("Uneven number of arguments to ".__PACKAGE__."->latex().") if @_ % 2; |
117
|
|
|
|
|
|
|
my %opt = @_; |
118
|
|
|
|
|
|
|
my $radix = $opt{radix}; |
119
|
|
|
|
|
|
|
if (not defined $radix) { |
120
|
|
|
|
|
|
|
$radix = '.'; |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
elsif ($radix eq '.') { |
123
|
|
|
|
|
|
|
#fine |
124
|
|
|
|
|
|
|
} |
125
|
|
|
|
|
|
|
else { |
126
|
|
|
|
|
|
|
$radix .= '\!'; |
127
|
|
|
|
|
|
|
} |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
my $enclose = $opt{enclose}; |
130
|
|
|
|
|
|
|
$enclose = '' if not defined $enclose; |
131
|
|
|
|
|
|
|
$enclose = '' if _ARRAY0($enclose) and @$enclose != 2; |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
my $str = "".$self->round(); |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
my $result; |
136
|
|
|
|
|
|
|
pos($str) = 0; |
137
|
|
|
|
|
|
|
my $p = -1; |
138
|
|
|
|
|
|
|
my $number = 1; |
139
|
|
|
|
|
|
|
while (defined pos($str) and pos($str) < length($str)) { |
140
|
|
|
|
|
|
|
die "Failed to advance string parser at position $p in '$str'." if pos($str) == $p; |
141
|
|
|
|
|
|
|
$p = pos($str); |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
# number |
144
|
|
|
|
|
|
|
if ($number) { |
145
|
|
|
|
|
|
|
$str =~ /\G\s*$CFloatCapture\s*/cgo or die "Expected number starting at position $p in '$str'."; |
146
|
|
|
|
|
|
|
my $sgn = $1; |
147
|
|
|
|
|
|
|
my $num = $2; |
148
|
|
|
|
|
|
|
my $exp = $3; |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
unless ($exp =~ s/^[eE]([+-]?)(\d+)$/" \\cdot 10^{".($1eq'-'?'-':'').(0+$2)."}"/e) { |
151
|
|
|
|
|
|
|
$exp = ' \cdot 10^{0}'; |
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
$num =~ s/\./$radix/; |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
$result .= "$sgn$num$exp"; |
157
|
|
|
|
|
|
|
$number = 0; |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
# +/-, +, - |
160
|
|
|
|
|
|
|
else { |
161
|
|
|
|
|
|
|
$str =~ /\G\s*(\+\/\-|\+|\-)\s*/cgo or die "Expected operator (+/-, +, -) starting at position $p in '$str'."; |
162
|
|
|
|
|
|
|
my $op = $1; |
163
|
|
|
|
|
|
|
if ($op eq '+/-') { |
164
|
|
|
|
|
|
|
$op = '\pm'; |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
$result .= " $op "; |
168
|
|
|
|
|
|
|
$number = 1; |
169
|
|
|
|
|
|
|
} |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
if (_ARRAY0($enclose)) { |
174
|
|
|
|
|
|
|
return $enclose->[0].$result.$enclose->[1]; |
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
else { |
177
|
|
|
|
|
|
|
return $enclose.$result.$enclose; |
178
|
|
|
|
|
|
|
} |
179
|
|
|
|
|
|
|
} |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
=head2 latex_math |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
Works exactly like C except that the C string defaults to C<$>. |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
=cut |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
sub latex_math { |
188
|
|
|
|
|
|
|
shift()->latex(enclose => '$', @_) |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
=head2 latex_equation |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
Works exactly like C except that the C string defaults to the |
194
|
|
|
|
|
|
|
environment C<\begin{equation}\n> and C<\n\end{equation}>. |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
=cut |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
sub latex_equation { |
199
|
|
|
|
|
|
|
shift()->latex(enclose => ["\\begin{equation}\n", "\n\\end{equation}"], @_) |
200
|
|
|
|
|
|
|
} |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
=head2 encode |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
This method encodes an arbitrary UTF-8 string as TeX. Syntax: |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
my $encoded = $obj->encode($string); |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
For detailed documentation, please refer to L. |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
=cut |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
sub encode { |
213
|
|
|
|
|
|
|
my $self = shift; |
214
|
|
|
|
|
|
|
return Encode::encode('latex', shift); |
215
|
|
|
|
|
|
|
} |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
1; |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
__END__ |