Skip to content

Commit edd0da7

Browse files
committed
tex, string, and separator options for units
1 parent 7445e5c commit edd0da7

2 files changed

Lines changed: 94 additions & 21 deletions

File tree

lib/Units.pm

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ our $PI = 4 * atan2(1, 1);
3838

3939
# 9.80665 m/s^2 -- standard acceleration of gravity
4040

41+
# If adding a string property to a unit below, check that the default font
42+
# in use for hardcopy has the glyphs needed for that string.
43+
4144
our %known_units = (
4245
m => {
4346
factor => 1,
@@ -61,16 +64,22 @@ our %known_units = (
6164
degC => {
6265
factor => 1,
6366
degC => 1,
67+
string => "\x{2103}",
68+
tex => "\x{2103}",
6469
aliases => [ "\x{00B0}C", "\x{2103}" ]
6570
},
6671
degF => {
6772
factor => 1,
6873
degF => 1,
74+
string => "\x{00B0}F",
75+
tex => "\x{00B0}F",
6976
aliases => [ "\x{00B0}F", "\x{2109}" ]
7077
},
7178
K => {
7279
factor => 1,
7380
K => 1,
81+
string => "\x{212A}",
82+
tex => "\x{212A}",
7483
aliases => [ "\x{212A}", 'degK', "\x{00B0}K" ] # Should the degree forms be deleted? Probably.
7584
},
7685
mol => {
@@ -92,9 +101,13 @@ our %known_units = (
92101

93102
# ANGLES: fundamental unit rad (radian)
94103
deg => { # degree
95-
factor => $PI / 180,
96-
rad => 1,
97-
aliases => [ "\x{00B0}", 'degree', 'degrees' ]
104+
factor => $PI / 180,
105+
rad => 1,
106+
string => "\x{00B0}",
107+
tex => "\x{00B0}",
108+
string_separator => '',
109+
tex_separator => '',
110+
aliases => [ "\x{00B0}", 'degree', 'degrees' ]
98111
},
99112
sr => { # steradian, a mesure of solid angle
100113
factor => 1,
@@ -109,6 +122,8 @@ our %known_units = (
109122
us => { # microsecond
110123
factor => 1E-6,
111124
s => 1,
125+
string => "\x{00B5}s",
126+
tex => "\x{00B5}s",
112127
aliases => ["\x{00B5}s"]
113128
},
114129
ns => { # nanosecond
@@ -163,22 +178,30 @@ our %known_units = (
163178
um => { # micrometer
164179
factor => 1E-6,
165180
m => 1,
166-
aliases => [ 'micron', "\x{00B5}m" ]
181+
string => "\x{00B5}m",
182+
tex => "\x{00B5}m",
183+
aliases => ["\x{00B5}m"]
184+
},
185+
micron => { # micrometer
186+
factor => 1E-6,
187+
m => 1,
167188
},
168-
nm => { # nanometer
189+
nm => { # nanometer
169190
factor => 1E-9,
170191
m => 1
171192
},
172193
angstrom => {
173194
factor => 1E-10,
174195
m => 1,
196+
string => "\x{00C5}",
197+
tex => "\x{00C5}",
175198
aliases => [ 'angstroms', 'Angstrom', 'Angstroms', "\x{00C5}" ]
176199
},
177-
pm => { # picometer
200+
pm => { # picometer
178201
factor => 1E-12,
179202
m => 1
180203
},
181-
fm => { # femtometer
204+
fm => { # femtometer
182205
factor => 1E-15,
183206
m => 1
184207
},
@@ -218,8 +241,9 @@ our %known_units = (
218241
219242
# VOLUME: fundamental unit m^3 (cubic meter)
220243
L => { # liter
221-
factor => 0.001,
222-
m => 3
244+
factor => 0.001,
245+
m => 3,
246+
aliases => [ 'litre', 'litres', 'liter', 'liters' ]
223247
},
224248
ml => { # milliliter (cubic centimeter)
225249
factor => 1E-6,
@@ -331,6 +355,8 @@ our %known_units = (
331355
m => 1,
332356
kg => 1,
333357
s => -2,
358+
string => "\x{00B5}N",
359+
tex => "\x{00B5}N",
334360
aliases => [ 'microN', "\x{00B5}N" ]
335361
},
336362
kN => { # kilonewton
@@ -561,6 +587,8 @@ our %known_units = (
561587
factor => 1e-6,
562588
amp => 1,
563589
s => 1,
590+
string => "\x{00B5}C",
591+
tex => "\x{00B5}C",
564592
aliases => ["\x{00B5}C"]
565593
},
566594
nC => { # nanocoulomb
@@ -616,6 +644,8 @@ our %known_units = (
616644
s => 4,
617645
kg => -1,
618646
m => -2,
647+
string => "\x{00B5}F",
648+
tex => "\x{00B5}F",
619649
aliases => [ "\x{00B5}F", "\x{338C}" ]
620650
},
621651
ohm => { # V/amp
@@ -624,6 +654,8 @@ our %known_units = (
624654
m => 2,
625655
amp => -2,
626656
s => -3,
657+
string => "\x{2126}",
658+
tex => "\x{2126}",
627659
aliases => ["\x{2126}"]
628660
},
629661
kohm => { # kiloohm
@@ -632,6 +664,8 @@ our %known_units = (
632664
m => 2,
633665
amp => -2,
634666
s => -3,
667+
string => "k\x{2126}",
668+
tex => "k\x{2126}",
635669
aliases => [ "k\x{2126}", "\x{33C0}" ]
636670
},
637671
Mohm => { # megaohm
@@ -640,6 +674,8 @@ our %known_units = (
640674
m => 2,
641675
amp => -2,
642676
s => -3,
677+
string => "M\x{2126}",
678+
tex => "M\x{2126}",
643679
aliases => [ "M\x{2126}", "\x{33C1}" ]
644680
},
645681
S => { # siemens (1/ohm)
@@ -735,6 +771,8 @@ our %known_units = (
735771
factor => 0.000001,
736772
m => 2,
737773
s => -2,
774+
string => "\x{00B5}Sv",
775+
tex => "\x{00B5}Sv",
738776
aliases => ["\x{00B5}Sv"]
739777
},
740778
Bq => { # becquerel, radioactivity (https://en.wikipedia.org/wiki/Becquerel)
@@ -802,6 +840,32 @@ for my $unit (keys %known_units) {
802840
}
803841
}
804842

843+
# A map from unit name to display options
844+
our %unit_display;
845+
846+
# Process display options
847+
for my $unit (keys %known_units) {
848+
# note that aliases were not deep copied, so cannot delete
849+
# these until a separate loop after all are processed
850+
for ('string', 'tex', 'string_separator', 'tex_separator') {
851+
$unit_display{$unit}{$_} = $known_units{$unit}{$_} if defined $known_units{$unit}{$_};
852+
}
853+
}
854+
855+
# If a unit has a string option set, make sure that there is a unit with that name too.
856+
for my $unit (keys %known_units) {
857+
$known_units{ $known_units{$unit}{string} } = $known_units{$unit}
858+
if $known_units{$unit}{string} && !$known_units{ $known_units{$unit}{string} };
859+
}
860+
861+
for my $unit (keys %known_units) {
862+
# note that aliases were not deep copied, so cannot delete
863+
# these until a separate loop after all are processed
864+
for ('string', 'tex', 'string_separator', 'tex_separator') {
865+
delete $known_units{$unit}{$_};
866+
}
867+
}
868+
805869
sub process_unit {
806870

807871
my $string = shift;

macros/contexts/contextUnits.pl

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -684,14 +684,10 @@ package context::Units::Context;
684684
#
685685
# The units from the original Units package
686686
#
687-
our %UNITS = (%Units::known_units);
688-
our %ALIAS = (%Units::unit_aliased_to);
689-
for ('litre', 'litres', 'liter', 'liters') {
690-
$UNITS{$_} = $UNITS{L};
691-
$ALIAS{$_} = 'L';
692-
}
687+
our %UNITS = (%Units::known_units);
688+
our %ALIAS = (%Units::unit_aliased_to);
689+
our %DISPLAY = (%Units::unit_display);
693690

694-
#
695691
# The categories of units that can be selected.
696692
#
697693
# These give the fundamental units of the unit names to be added to
@@ -780,8 +776,9 @@ sub addUnit {
780776
if ($name) {
781777
$constants->add(
782778
$name => {
783-
value => context::Units::Unit->new($name => $unit),
784-
TeX => "\\text{$name}",
779+
value => context::Units::Unit->new($name => $unit),
780+
TeX => $DISPLAY{$name}{tex} ? "\\text{$DISPLAY{$name}{tex}}" : "\\text{$name}",
781+
$DISPLAY{$name}{string} ? (string => $DISPLAY{$name}{string}) : (),
785782
isUnit => 1,
786783
isConstant => 1
787784
}
@@ -958,6 +955,8 @@ sub assignUnits {
958955
package context::Units::Unit;
959956
our @ISA = ('Value');
960957

958+
our %DISPLAY = (%context::Units::Context::DISPLAY);
959+
961960
#
962961
# Create a new Unit object, either by parsing a string version of
963962
# the units, or by giving the name of a known unit, or as name => unit_def,
@@ -1401,7 +1400,7 @@ sub pushUnitTeX {
14011400
my ($self, $units, $u, $n, $invert) = @_;
14021401
return unless $n;
14031402
my $def = $self->context->constants->get($u);
1404-
my $unit = ($def->{TeX} || "\\text{$u}");
1403+
my $unit = ($def->{TeX} || ($DISPLAY{$u}{tex} ? "\\text{$DISPLAY{$u}{tex}}" : "\\text{$u}"));
14051404
if ($self->{negativePowers}{$u} || $self->getFlag('useNegativePowers')) {
14061405
push(@$invert, $unit . "^{-$n}");
14071406
} else {
@@ -1440,6 +1439,8 @@ sub perl {
14401439
package context::Units::NumberWithUnit;
14411440
our @ISA = ('Value');
14421441

1442+
our %DISPLAY = (%context::Units::Context::DISPLAY);
1443+
14431444
#
14441445
# Create a new Number-with-Unit object, either by giving the number
14451446
# and units separately. The number can be any MathObject that is of
@@ -1504,7 +1505,11 @@ sub string {
15041505
my $unit = $self->unit;
15051506
my $u = $unit->stringFor('nunits', 'dunits', $unit->{order}, 0, 1);
15061507
my $string = $self->number->string;
1507-
$string .= substr($u, 0, 1) eq '/' ? $u : " $u";
1508+
my $separator =
1509+
(%{ $unit->{nunits} } > 0 && defined $DISPLAY{ $unit->{order}[0] }{string_separator})
1510+
? $DISPLAY{ $unit->{order}[0] }{string_separator}
1511+
: ' ';
1512+
$string .= substr($u, 0, 1) eq '/' ? $u : "$separator$u";
15081513
$string = '(' . $string . ')' if defined($precedence) && $precedence > 1;
15091514
return $string;
15101515
}
@@ -1520,7 +1525,11 @@ sub TeX {
15201525
if (substr($u, 0, 1) eq '/') {
15211526
$tex = "\\frac{$tex}{" . $unit->raiseUnit(-1, 1)->with(negativePowers => {})->TeX . '}';
15221527
} else {
1523-
$tex .= '\\,' . $unit->TeX;
1528+
$tex .=
1529+
((%{ $unit->{dunits} } == 0 && defined $DISPLAY{ $unit->{order}[0] }{tex_separator})
1530+
? $DISPLAY{ $unit->{order}[0] }{tex_separator}
1531+
: '\\,')
1532+
. $unit->TeX;
15241533
}
15251534
$tex = '(' . $tex . ')' if defined($precedence) && $precedence > 1;
15261535
return $tex;

0 commit comments

Comments
 (0)