diff --git a/quantiphy/quantiphy.py b/quantiphy/quantiphy.py index 5066bf3..2339a50 100644 --- a/quantiphy/quantiphy.py +++ b/quantiphy/quantiphy.py @@ -418,18 +418,26 @@ def add_constant(value, alias=None, unit_systems=None): # These mappings are only used when writing numbers BIG_SCALE_FACTORS = 'kMGTPEZYRQ' # These must be given in order, one for every three decades. - # Use k rather than K, because K looks like a temperature when used alone. + # Use k rather than K because K looks like a temperature when used alone. SMALL_SCALE_FACTORS = 'munpfazyrq' # These must be given in order, one for every three decades. -# Supported currency symbols (these go on left side of number) +# Supported currency symbols (these precede the number) CURRENCY_SYMBOLS = '$€¥£₩₺₽₹Ƀ₿Ξ' +# Units that abut the number. +# % is controversial, NIST and ISO say that a space should be used to separate +# the percent sign from a number, but the Chicago Manual of Style says the +# opposite. +TIGHT_UNITS = '''°'"′″''' + # The code is written assuming that TIGHT_UNITS includes only single + # character symbols, though the user can add multi-character tight units. + # Unit symbols that are not simple letters. # Do not include % as it will be picked up when converting text to numbers, # which is generally not desired (you would end up converting 0.001% to 1m%). -UNIT_SYMBOLS = '°ÅΩƱΩ℧¢$€¥£₩₺₽₹Ƀ₿șΞΔ' +UNIT_SYMBOLS = """ÅΩƱΩ℧Δ¢ș""" + CURRENCY_SYMBOLS + TIGHT_UNITS # Regular expression for recognizing and decomposing string .format method codes FORMAT_SPEC = re.compile(r'''\A @@ -494,7 +502,7 @@ def add_constant(value, alias=None, unit_systems=None): spacer = ' ', strip_radix = True, strip_zeros = True, - tight_units = ''' % ° ' " ′ ″ '''.split(), + tight_units = list(TIGHT_UNITS), unity_sf = '', ) @@ -977,9 +985,9 @@ def set_prefs(cls, **kwargs): to be '' or ' '; use the latter if you prefer a space between the number and the units. Generally using ' ' makes numbers easier to read, particularly with complex units, and using '' is easier to - parse. You could also use a Unicode non-breaking space ' '. For - your convenience, you can access a non-breaking space using - :attr:`Quantity.non_breaking_space`, + parse. Use of a non-breaking space is preferred when embedding + numbers in prose. For your convenience, you can access a + non-breaking spaces using :attr:`Quantity.non_breaking_space`, :attr:`Quantity.narrow_non_breaking_space`, or :attr:`Quantity.thin_space`. diff --git a/tests/test_misc.py b/tests/test_misc.py index 829cfa6..32d28c4 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -179,6 +179,12 @@ def test_misc(): q = Quantity('90°') assert q.render() == '90°' + q = Quantity("36 ′") + assert q.render() == "36′" + + q = Quantity('18 ″') + assert q.render() == '18″' + q = Quantity('80°F') assert q.render() == '80 °F' @@ -304,7 +310,7 @@ class Foo(Quantity): q4 = Quantity('10%', name='bar', desc='buzz') assert '{:G}'.format(q3) == 'foo = 0.1' assert '{:G}'.format(q4) == 'bar = 10 # buzz' - assert '{:S}'.format(q4) == 'bar = 10% # buzz' + assert '{:S}'.format(q4) == 'bar = 10 % # buzz' class Derived(Quantity): pass @@ -464,6 +470,8 @@ class Foo(Quantity): assert Quantity('10cm').render() == '100mm' Quantity.set_prefs(unity_sf='', spacer=' ') + assert Quantity('10%').render() == '10 %' + Quantity.set_prefs(tight_units='%') assert Quantity('10%').render() == '10%' Quantity.set_prefs(input_sf='%') assert Quantity('10%').render() == '100m' @@ -1085,9 +1093,14 @@ def test_percent(): # by default QuantiPhy treats % as a tight unit assert '%' not in Quantity.get_pref('input_sf') - assert Quantity('10%').render() == '10%' + assert Quantity('10%').render() == '10 %' assert Quantity('10%Δ').render() == '10 %Δ' + # adding % to tight_units + with Quantity.prefs(tight_units = Quantity.get_pref('tight_units') + ['%']): + assert Quantity('10%').render() == '10%' + assert Quantity('10%Δ').render() == '10 %Δ' + # but by adding it to input_sf it is treated as a scale factor with Quantity.prefs(input_sf = Quantity.get_pref('input_sf') + '%'): assert '%' in Quantity.get_pref('input_sf')