Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FormattedNumber and post Latex and HTML conversion #134

Merged
merged 38 commits into from
Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
6451afd
remove unused parse_standard_exp_tr
jagerber48 Jan 21, 2024
be27537
latex output conversion
jagerber48 Jan 21, 2024
4fed95d
tests
jagerber48 Jan 21, 2024
fbe2206
ruff format
jagerber48 Jan 21, 2024
f7ad328
no \left or \right
jagerber48 Jan 22, 2024
8d4cf02
Remove old latex functionality
jagerber48 Jan 22, 2024
4c26d89
docstrings and minor reorganization
jagerber48 Jan 22, 2024
8679083
allowed-confusables
jagerber48 Jan 22, 2024
b77e140
typo
jagerber48 Jan 22, 2024
e09b366
documentation
jagerber48 Jan 22, 2024
9ca141a
docstring ruff formatting
jagerber48 Jan 23, 2024
1ed8e3f
add sciform_to_html and FormattedNumber
jagerber48 Jan 24, 2024
f60a710
surrounding $$
jagerber48 Jan 24, 2024
b5a3389
add strip_env_symbs flag
jagerber48 Jan 24, 2024
330f9fb
refactor conversion code and add ASCII conversion
jagerber48 Jan 25, 2024
046e606
ruff
jagerber48 Jan 25, 2024
bd37a8c
work on documentation
jagerber48 Jan 25, 2024
dd59969
fix unicode exp pattern regex
jagerber48 Jan 26, 2024
aa06c9b
update documentation
jagerber48 Jan 26, 2024
66298dd
_repr_html_ and _repr_latex_ to use as_html and as_latex (instead of …
jagerber48 Jan 26, 2024
a9e081c
consolidate output conversion tests
jagerber48 Jan 26, 2024
67c66c3
rename output conversion
jagerber48 Jan 26, 2024
bb8cca4
test latex/html repr
jagerber48 Jan 26, 2024
695e08b
test invalid cases
jagerber48 Jan 26, 2024
5671994
strip_math_mode rename and documentation
jagerber48 Jan 26, 2024
1e448b3
_repr_html_ and _repr_latex_ docs
jagerber48 Jan 26, 2024
770dc08
jupyter/IPython display example
jagerber48 Jan 26, 2024
b34bdbc
break out "examples" dependencies
jagerber48 Jan 26, 2024
d9b6870
sort autodoc members by source
jagerber48 Jan 26, 2024
d55674d
test left_pad_matching
jagerber48 Jan 26, 2024
18e916c
minor docs
jagerber48 Jan 26, 2024
49ed1c1
minor docs
jagerber48 Jan 26, 2024
1797a61
changelog
jagerber48 Jan 27, 2024
22f6c44
changelog
jagerber48 Jan 27, 2024
c6ca0c5
changelog
jagerber48 Jan 27, 2024
4f9747f
minor
jagerber48 Jan 27, 2024
0b9afda
minor
jagerber48 Jan 27, 2024
c155d5a
minor
jagerber48 Jan 27, 2024
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
5 changes: 5 additions & 0 deletions docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,8 @@ Global Configuration
.. autofunction:: reset_global_defaults()

.. autoclass:: GlobalDefaultsContext()

Output Conversion
=================

.. autofunction:: sciform_to_latex
54 changes: 7 additions & 47 deletions docs/source/options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@ mantissa ``m`` satisfies ``1 <= m < 10``.
>>> print(sform(123.456, 0.001))
(1.23456 ± 0.00001)e+02

Note that, for all exponent modes, the exponent integer is always
displayed with a sign symbol (+ or -) and is left padded with a zero so
that it is at least two digits wide.
There are no options to modify this behavior for standard exponent
display.
The :ref:`superscript` or :ref:`latex_format` options can be used as
alternatives.
By default the exponent is expressed using ASCII characters, e.g.
``e+02``.
The sign symbol is always included and the exponent value is left padded
so that it is at least two digits wide.
These behaviors for ASCII exponents cannot be modified.
However the :ref:`superscript` mode can be used to represent the
exponent using unicode characters.

.. _engineering:

Expand Down Expand Up @@ -567,46 +567,6 @@ superscript notation as opposed to e.g. ``e+02`` notation.
>>> print(sform(789))
7.89×10²

.. _latex_format:

Latex Format
============

The ``latex`` option can be chosen to convert strings into latex
parseable codes.

>>> sform = Formatter(
... exp_mode="scientific",
... exp_val=-1,
... upper_separator="_",
... latex=True,
... )
>>> print(sform(12345))
123\_450\times 10^{-1}
>>> sform = Formatter(
... exp_mode="percent",
... lower_separator="_",
... latex=True,
... )
>>> print(sform(0.12345678, 0.00000255))
\left(12.345\_678 \pm 0.000\_255\right)\%

The latex format makes the following changes:

* Convert standard exponent strings such as ``'e+02'`` into latex
superscript strings like ``'\times 10^{+2}``
* Replace ``'('`` and ``')'`` by latex size-aware delimiters
``'\left('`` and ``'\right)'``.
* Replace ``'±'`` by ``'\pm'``
* Replace ``'_'`` by ``'\_'``
* Replace ``'%'`` by ``'\%'``
* Exponent replacements such as ``'M'``, ``'Ki'``, or ``'ppb'`` and
non-finite numbers such as ``'nan'``, ``'NAN'``, ``'inf'``, and
``'INF'`` are wrapped in ``'\text{}'``.

Note that use of ``latex`` renders the use of the ``superscript``
option meaningless.

Include Exponent on nan and inf
===============================

Expand Down
55 changes: 53 additions & 2 deletions docs/source/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ package default settings):
'extra_parts_per_forms': {},
'capitalize': False,
'superscript': False,
'latex': False,
'nan_inf_exp': False,
'paren_uncertainty': False,
'pdg_sig_figs': False,
Expand Down Expand Up @@ -176,7 +175,6 @@ unchanged.
'extra_parts_per_forms': {},
'capitalize': False,
'superscript': False,
'latex': False,
'nan_inf_exp': False,
'paren_uncertainty': False,
'pdg_sig_figs': False,
Expand Down Expand Up @@ -218,6 +216,59 @@ If the user wishes to configure these options, but also use the
:ref:`FSML <fsml>`, then they must do so by modifying the global default
settings.

.. _latex_conversion:

Latex Conversion
================

The :func:`sciform_to_latex` function can be used to convert ``sciform``
output strings into latex commands.

>>> from sciform import sciform_to_latex
>>> sform = Formatter(
... exp_mode="scientific",
... exp_val=-1,
... upper_separator="_",
... )
>>> formatted_str = sform(12345)
>>> latex_str = sciform_to_latex(formatted_str)
>>> print(f"{formatted_str} -> {latex_str}")
123_450e-01 -> 123\_450\times10^{-1}

>>> sform = Formatter(
... exp_mode="percent",
... lower_separator="_",
... )
>>> formatted_str = sform(0.12345678, 0.00000255)
>>> latex_str= sciform_to_latex(formatted_str)
>>> print(f"{formatted_str} -> {latex_str}")
(12.345_678 ± 0.000_255)% -> (12.345\_678\:\pm\:0.000\_255)\%

>>> sform = Formatter(
... exp_mode="engineering",
... exp_format="prefix",
... ndigits=4
... )
>>> formatted_str = sform(314.159e-6, 2.71828e-6)
>>> latex_str = sciform_to_latex(formatted_str)
>>> print(f"{formatted_str} -> {latex_str}")
(314.159 ± 2.718) μ -> (314.159\:\pm\:2.718)\:\text{\textmu}

The latex format makes the following changes:

* Convert all ASCII (``"e+02"``) and superscript (``"×10²"``) exponents
into latex superscript strings like ``"\times10^{2}"``.
* Wrap all text like ``"nan"``, ``"INF"``, ``"M"``, ``"μ"``, ``"Ki"``,
or ``"ppb"`` in the latex math mode text environment ``"\text{}"``.
* Make the following symbol replacements

* ``"%"`` -> ``r"\%"``
* ``"_"`` -> ``r"\_"``
* ``" "`` -> ``r"\:"``
* ``"±"`` -> ``r"\pm"``
* ``"×"`` -> ```r"\times"``
* ``"μ"`` -> ``r"\textmu"``

.. _dec_and_float:

Note on Decimals and Floats
Expand Down
7 changes: 7 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ readme = {file = "README.rst"}

[tool.setuptools_scm]

[tool.ruff]
allowed-confusables = ["×"]

[tool.ruff.lint]
select = ['ALL']
ignore = [
Expand All @@ -57,8 +60,12 @@ ignore = [
'TD002',
'TD003',
'FIX002',
'RET504',
]

[tool.ruff.format]
docstring-code-format = true
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I just learned about this option, I love it!

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Batalex yes it's nice. I still use blackdoc to format code snippets in the .rst documentation files. Awaiting astral-sh/ruff#8237 so I can move entirely away from black and over to ruff.


[tool.ruff.per-file-ignores]
"tests/*.py" = ["D", "ANN", "PT"]
"examples/*.py" = ["D"]
Expand Down
3 changes: 3 additions & 0 deletions src/sciform/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
set_global_defaults,
)
from sciform.modes import AutoDigits, AutoExpVal
from sciform.output_conversion import sciform_to_html, sciform_to_latex
from sciform.scinum import SciNum

__all__ = [
Expand All @@ -18,5 +19,7 @@
"set_global_defaults",
"AutoDigits",
"AutoExpVal",
"sciform_to_html",
"sciform_to_latex",
"SciNum",
]
57 changes: 2 additions & 55 deletions src/sciform/format_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ def get_standard_exp_str(base: int, exp_val: int, *, capitalize: bool = False) -


def get_superscript_exp_str(base: int, exp_val: int) -> str:
"""Get superscript (e.g. '×10⁺²') exponent string.""" # noqa: RUF002
"""Get superscript (e.g. '×10⁺²') exponent string."""
sup_trans = str.maketrans("+-0123456789", "⁺⁻⁰¹²³⁴⁵⁶⁷⁸⁹")
exp_val_str = f"{exp_val}".translate(sup_trans)
return f"×{base}{exp_val_str}"
Expand Down Expand Up @@ -197,8 +197,6 @@ def get_exp_str( # noqa: PLR0913
extra_iec_prefixes: dict[int, str],
extra_parts_per_forms: dict[int, str],
capitalize: bool,
latex: bool,
latex_trim_whitespace: bool,
superscript: bool,
) -> str:
"""Get formatting exponent string."""
Expand All @@ -224,43 +222,14 @@ def get_exp_str( # noqa: PLR0913
if exp_val in text_exp_dict and text_exp_dict[exp_val] is not None:
exp_str = f" {text_exp_dict[exp_val]}"
exp_str = exp_str.rstrip(" ")
if latex:
if latex_trim_whitespace:
exp_str = exp_str.lstrip(" ")
exp_str = rf"\text{{{exp_str}}}"
return exp_str

if latex:
return rf"\times {base}^{{{exp_val:+}}}"
if superscript:
return get_superscript_exp_str(base, exp_val)

return get_standard_exp_str(base, exp_val, capitalize=capitalize)


def parse_standard_exp_str(exp_str: str) -> tuple[int, int]:
"""Extract base and exponent value from standard exponent string."""
match = re.match(
r"""
^
(?P<exp_symbol>[eEbB])
(?P<exp_val>[+-]\d+)
$
""",
exp_str,
re.VERBOSE,
)

exp_symbol = match.group("exp_symbol")
symbol_to_base_dict = {"e": 10, "b": 2}
base = symbol_to_base_dict[exp_symbol.lower()]

exp_val_str = match.group("exp_val")
exp_val = int(exp_val_str)

return base, exp_val


def get_sign_str(num: Decimal, sign_mode: SignModeEnum) -> str:
"""Get the format sign string."""
if num < 0:
Expand Down Expand Up @@ -365,24 +334,6 @@ def format_num_by_top_bottom_dig(
return f"{sign_str}{pad_str}{abs_mantissa_str}"


def latex_translate(input_str: str) -> str:
"""Translate elements of a string for Latex compatibility."""
result_str = input_str
replacements = (
("(", r"\left("),
(")", r"\right)"),
("%", r"\%"),
("_", r"\_"),
("nan", r"\text{nan}"),
("NAN", r"\text{NAN}"),
("inf", r"\text{inf}"),
("INF", r"\text{INF}"),
)
for old_chars, new_chars in replacements:
result_str = result_str.replace(old_chars, new_chars)
return result_str


def round_val_unc(
val: Decimal,
unc: Decimal,
Expand Down Expand Up @@ -487,13 +438,12 @@ def construct_val_unc_str( # noqa: PLR0913
decimal_separator: SeparatorEnum,
*,
paren_uncertainty: bool,
latex: bool,
pm_whitespace: bool,
paren_uncertainty_separators: bool,
) -> str:
"""Construct the value/uncertainty part of the formatted string."""
if not paren_uncertainty:
pm_symb = r"\pm" if latex else "±"
pm_symb = "±"
if pm_whitespace:
pm_symb = f" {pm_symb} "
val_unc_str = f"{val_mantissa_str}{pm_symb}{unc_mantissa_str}"
Expand Down Expand Up @@ -538,7 +488,6 @@ def construct_val_unc_exp_str( # noqa: PLR0913
extra_iec_prefixes: dict[int, str | None],
extra_parts_per_forms: dict[int, str | None],
capitalize: bool,
latex: bool,
superscript: bool,
paren_uncertainty: bool,
) -> str:
Expand All @@ -548,8 +497,6 @@ def construct_val_unc_exp_str( # noqa: PLR0913
exp_mode=exp_mode,
exp_format=exp_format,
capitalize=capitalize,
latex=latex,
latex_trim_whitespace=True,
superscript=superscript,
extra_si_prefixes=extra_si_prefixes,
extra_iec_prefixes=extra_iec_prefixes,
Expand Down
Loading
Loading