Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 73 additions & 9 deletions lib/Units.pm
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ our $PI = 4 * atan2(1, 1);

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

# If adding a string property to a unit below, check that the default font
# in use for hardcopy has the glyphs needed for that string.

our %known_units = (
m => {
factor => 1,
Expand All @@ -61,16 +64,22 @@ our %known_units = (
degC => {
factor => 1,
degC => 1,
string => "\x{2103}",
tex => "\x{2103}",
aliases => [ "\x{00B0}C", "\x{2103}" ]
},
degF => {
factor => 1,
degF => 1,
string => "\x{00B0}F",
tex => "\x{00B0}F",
aliases => [ "\x{00B0}F", "\x{2109}" ]
},
K => {
factor => 1,
K => 1,
string => "\x{212A}",
tex => "\x{212A}",
aliases => [ "\x{212A}", 'degK', "\x{00B0}K" ] # Should the degree forms be deleted? Probably.
},
mol => {
Expand All @@ -92,9 +101,13 @@ our %known_units = (

# ANGLES: fundamental unit rad (radian)
deg => { # degree
factor => $PI / 180,
rad => 1,
aliases => [ "\x{00B0}", 'degree', 'degrees' ]
factor => $PI / 180,
rad => 1,
string => "\x{00B0}",
tex => "\x{00B0}",
string_separator => '',
tex_separator => '',
aliases => [ "\x{00B0}", 'degree', 'degrees' ]
},
sr => { # steradian, a mesure of solid angle
factor => 1,
Expand All @@ -109,6 +122,8 @@ our %known_units = (
us => { # microsecond
factor => 1E-6,
s => 1,
string => "\x{00B5}s",
tex => "\x{00B5}s",
aliases => ["\x{00B5}s"]
},
ns => { # nanosecond
Expand Down Expand Up @@ -163,22 +178,30 @@ our %known_units = (
um => { # micrometer
factor => 1E-6,
m => 1,
aliases => [ 'micron', "\x{00B5}m" ]
string => "\x{00B5}m",
tex => "\x{00B5}m",
aliases => ["\x{00B5}m"]
},
micron => { # micrometer
factor => 1E-6,
m => 1,
},
nm => { # nanometer
nm => { # nanometer
factor => 1E-9,
m => 1
},
angstrom => {
factor => 1E-10,
m => 1,
string => "\x{00C5}",
tex => "\x{00C5}",
aliases => [ 'angstroms', 'Angstrom', 'Angstroms', "\x{00C5}" ]
},
pm => { # picometer
pm => { # picometer
factor => 1E-12,
m => 1
},
fm => { # femtometer
fm => { # femtometer
factor => 1E-15,
m => 1
},
Expand Down Expand Up @@ -218,8 +241,9 @@ our %known_units = (

# VOLUME: fundamental unit m^3 (cubic meter)
L => { # liter
factor => 0.001,
m => 3
factor => 0.001,
m => 3,
aliases => [ 'litre', 'litres', 'liter', 'liters' ]
},
ml => { # milliliter (cubic centimeter)
factor => 1E-6,
Expand Down Expand Up @@ -331,6 +355,8 @@ our %known_units = (
m => 1,
kg => 1,
s => -2,
string => "\x{00B5}N",
tex => "\x{00B5}N",
aliases => [ 'microN', "\x{00B5}N" ]
},
kN => { # kilonewton
Expand Down Expand Up @@ -561,6 +587,8 @@ our %known_units = (
factor => 1e-6,
amp => 1,
s => 1,
string => "\x{00B5}C",
tex => "\x{00B5}C",
aliases => ["\x{00B5}C"]
},
nC => { # nanocoulomb
Expand Down Expand Up @@ -616,6 +644,8 @@ our %known_units = (
s => 4,
kg => -1,
m => -2,
string => "\x{00B5}F",
tex => "\x{00B5}F",
aliases => [ "\x{00B5}F", "\x{338C}" ]
},
ohm => { # V/amp
Expand All @@ -624,6 +654,8 @@ our %known_units = (
m => 2,
amp => -2,
s => -3,
string => "\x{2126}",
tex => "\x{2126}",
aliases => ["\x{2126}"]
},
kohm => { # kiloohm
Expand All @@ -632,6 +664,8 @@ our %known_units = (
m => 2,
amp => -2,
s => -3,
string => "k\x{2126}",
tex => "k\x{2126}",
aliases => [ "k\x{2126}", "\x{33C0}" ]
},
Mohm => { # megaohm
Expand All @@ -640,6 +674,8 @@ our %known_units = (
m => 2,
amp => -2,
s => -3,
string => "M\x{2126}",
tex => "M\x{2126}",
aliases => [ "M\x{2126}", "\x{33C1}" ]
},
S => { # siemens (1/ohm)
Expand Down Expand Up @@ -735,6 +771,8 @@ our %known_units = (
factor => 0.000001,
m => 2,
s => -2,
string => "\x{00B5}Sv",
tex => "\x{00B5}Sv",
aliases => ["\x{00B5}Sv"]
},
Bq => { # becquerel, radioactivity (https://en.wikipedia.org/wiki/Becquerel)
Expand Down Expand Up @@ -802,6 +840,32 @@ for my $unit (keys %known_units) {
}
}

# A map from unit name to display options
our %unit_display;

# Process display options
for my $unit (keys %known_units) {
# note that aliases were not deep copied, so cannot delete
# these until a separate loop after all are processed
for ('string', 'tex', 'string_separator', 'tex_separator') {
$unit_display{$unit}{$_} = $known_units{$unit}{$_} if defined $known_units{$unit}{$_};
}
}

# If a unit has a string option set, make sure that there is a unit with that name too.
for my $unit (keys %known_units) {
$known_units{ $known_units{$unit}{string} } = $known_units{$unit}
if $known_units{$unit}{string} && !$known_units{ $known_units{$unit}{string} };
}

for my $unit (keys %known_units) {
# note that aliases were not deep copied, so cannot delete
# these until a separate loop after all are processed
for ('string', 'tex', 'string_separator', 'tex_separator') {
delete $known_units{$unit}{$_};
}
}

sub process_unit {

my $string = shift;
Expand Down
34 changes: 22 additions & 12 deletions macros/contexts/contextUnits.pl
Original file line number Diff line number Diff line change
Expand Up @@ -684,14 +684,10 @@ package context::Units::Context;
#
# The units from the original Units package
#
our %UNITS = (%Units::known_units);
our %ALIAS = (%Units::unit_aliased_to);
for ('litre', 'litres', 'liter', 'liters') {
$UNITS{$_} = $UNITS{L};
$ALIAS{$_} = 'L';
}
our %UNITS = (%Units::known_units);
our %ALIAS = (%Units::unit_aliased_to);
our %DISPLAY = (%Units::unit_display);

#
# The categories of units that can be selected.
#
# These give the fundamental units of the unit names to be added to
Expand Down Expand Up @@ -780,8 +776,9 @@ sub addUnit {
if ($name) {
$constants->add(
$name => {
value => context::Units::Unit->new($name => $unit),
TeX => "\\text{$name}",
value => context::Units::Unit->new($name => $unit),
TeX => $DISPLAY{$name}{tex} ? "\\text{$DISPLAY{$name}{tex}}" : "\\text{$name}",
$DISPLAY{$name}{string} ? (string => $DISPLAY{$name}{string}) : (),
isUnit => 1,
isConstant => 1
}
Expand Down Expand Up @@ -958,6 +955,8 @@ sub assignUnits {
package context::Units::Unit;
our @ISA = ('Value');

our %DISPLAY = (%context::Units::Context::DISPLAY);

#
# Create a new Unit object, either by parsing a string version of
# the units, or by giving the name of a known unit, or as name => unit_def,
Expand Down Expand Up @@ -1401,7 +1400,7 @@ sub pushUnitTeX {
my ($self, $units, $u, $n, $invert) = @_;
return unless $n;
my $def = $self->context->constants->get($u);
my $unit = ($def->{TeX} || "\\text{$u}");
my $unit = ($def->{TeX} || ($DISPLAY{$u}{tex} ? "\\text{$DISPLAY{$u}{tex}}" : "\\text{$u}"));
if ($self->{negativePowers}{$u} || $self->getFlag('useNegativePowers')) {
push(@$invert, $unit . "^{-$n}");
} else {
Expand Down Expand Up @@ -1440,6 +1439,8 @@ sub perl {
package context::Units::NumberWithUnit;
our @ISA = ('Value');

our %DISPLAY = (%context::Units::Context::DISPLAY);

#
# Create a new Number-with-Unit object, either by giving the number
# and units separately. The number can be any MathObject that is of
Expand Down Expand Up @@ -1504,7 +1505,12 @@ sub string {
my $unit = $self->unit;
my $u = $unit->stringFor('nunits', 'dunits', $unit->{order}, 0, 1);
my $string = $self->number->string;
$string .= substr($u, 0, 1) eq '/' ? $u : " $u";
my $separator =
((%{ $unit->{dunits} } > 0 && %{ $unit->{nunits} } == 1 || %{ $unit->{dunits} } == 0)
&& defined $DISPLAY{ $unit->{order}[0] }{string_separator})
? $DISPLAY{ $unit->{order}[0] }{string_separator}
: ' ';
$string .= substr($u, 0, 1) eq '/' ? $u : "$separator$u";
$string = '(' . $string . ')' if defined($precedence) && $precedence > 1;
return $string;
}
Expand All @@ -1520,7 +1526,11 @@ sub TeX {
if (substr($u, 0, 1) eq '/') {
$tex = "\\frac{$tex}{" . $unit->raiseUnit(-1, 1)->with(negativePowers => {})->TeX . '}';
} else {
$tex .= '\\,' . $unit->TeX;
$tex .=
((%{ $unit->{dunits} } == 0 && defined $DISPLAY{ $unit->{order}[0] }{tex_separator})
? $DISPLAY{ $unit->{order}[0] }{tex_separator}
: '\\,')
. $unit->TeX;
}
$tex = '(' . $tex . ')' if defined($precedence) && $precedence > 1;
return $tex;
Expand Down