Skip to content

Commit 8760cca

Browse files
committed
fix design error in math font/engine options
1 parent 390b653 commit 8760cca

8 files changed

Lines changed: 333 additions & 189 deletions

File tree

‎doc/index.rst‎

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,8 @@ Quick example::
2626

2727
where 𝑖 is the imaginary unit.
2828

29-
The letters are written with the unicode mathematical alphanumeric characters,
30-
which is how ``\textbf{}``, ``\emph{}`` and the variables of a formula are told
31-
apart in plain text. Those characters live in a high unicode plane that some
32-
fonts do not cover, and some uses (indexing, feeding another program) want plain
33-
ASCII anyway; ``LatexNodes2Text(text_fontstyle=False, math_fontstyle=False)``
34-
keeps everything else and only leaves the letters alone, and
35-
``LatexNodes2Text(math_mode='text')`` gives the plainer rendering that
36-
`pylatexenc 2` produced.
29+
(With pylatexenc v3, latex-to-text now has support for unicode font styles and
30+
improved rendering! — see :doc:`new-in-pylatexenc-3`.)
3731

3832
And the other way around::
3933

‎doc/new-in-pylatexenc-3.rst‎

Lines changed: 87 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@ architecture with extended and more flexible functionality:
3535
parsers live in `pylatexenc.latexnodes.parsers`; you can write your own by
3636
deriving from `LatexParserBase`.
3737

38+
- We've introduced a new entry point interface for parsing:
39+
:py:meth:`LatexWalker.parse_content()
40+
<pylatexenc.latexwalker.LatexWalker.parse_content>`, with a suitable parser
41+
object from :py:mod:`pylatexenc.latexnodes.parsers` (such as
42+
:py:class:`~pylatexenc.latexnodes.parsers.LatexGeneralNodesParser`).
43+
The earlier interface exposed by `pylatexenc 2`, using
44+
:py:class:`~pylatexenc.latexwalker.LatexWalker` — `get_latex_nodes()`,
45+
`get_token()`, `get_latex_expression()`, `get_latex_braced_group()`,
46+
`get_latex_environment()`, and `get_latex_maybe_optional_arg()` keeps working
47+
as it did.
48+
3849
- Lists of latex node objects
3950
(:py:class:`~pylatexenc.latexnodes.nodes.LatexNode`) are now wrapped in a
4051
special object for node lists →
@@ -111,12 +122,12 @@ The `latex2text` module was improved:
111122

112123
- Support for unicode alphabets for bold and italic text.
113124

114-
- There is a new renderer for math content, ``math_mode='fancy'``. It is now
115-
the default. It tries to make the plain text look like the
116-
formula LaTeX would typeset, so that ``$4 \pi c\sin(x+y)$`` gives
117-
``4π𝑐 sin(𝑥 + 𝑦)`` using unicode alphabets. (Use ``math_mode='text'`` to
118-
restore pylatexenc-v2's behavior.) Relevant options: ``math_mode=``,
119-
``math_fontstyle=``, ``math_expression_in=`` (see
125+
- A new default renderer for math content, ``math_mode='fancy'``, now formats
126+
math content in a way that is much more visually appealing, so that ``$\frac{4
127+
\pi c}{2}\sin(x+y)$`` gives ``(4π𝑐)/2 sin(𝑥 + 𝑦)`` instead of ``4 π
128+
c/2sin(x+y)``. We also support unicode fonts for text and math. (Use
129+
``math_mode='text', math_fontstyle=None, text_fontstyle=False`` to restore
130+
pylatexenc v2's behavior; see
120131
:py:class:`~pylatexenc.latex2text.LatexNodes2Text`).
121132

122133
- Subscripts and superscripts are now rendered with unicode characters whenever
@@ -137,17 +148,42 @@ A couple things to look out for
137148
-------------------------------
138149

139150
- :py:class:`~pylatexenc.latex2text.LatexNodes2Text` renders formulas with the
140-
new ``math_mode='fancy'`` engine by default, so its output now contains the
141-
unicode mathematical alphanumeric characters where `pylatexenc 2` produced
142-
plain ASCII letters: ``$x+y$`` gives ``𝑥 + 𝑦``, and ``\textbf{bold}`` gives
143-
``𝐛𝐨𝐥𝐝``. Those characters are outside the Basic Multilingual Plane, and a
144-
font that does not cover them shows a placeholder box. If you are indexing
145-
the output, comparing it against stored strings, or feeding it to a program
146-
that expects ASCII, pass ``math_mode='text'`` to get the `pylatexenc 2`
147-
rendering back, or keep the new rendering and only drop the unicode
148-
alphabets with ``text_fontstyle=False, math_fontstyle=False``. The
149-
command-line tool takes ``--math-mode=text``, or ``--text-fontstyle=off
150-
--math-fontstyle=off``, for the same purposes.
151+
new ``math_mode='fancy'`` engine by default, which improves math content
152+
spacing and uses cleverer unicode constructs such as for sub/superscripts and
153+
fractions. The renderer now also uses unicode mathematical font characters
154+
where `pylatexenc 2` produced plain ASCII letters. That is, ``$x+y$`` gives
155+
``𝑥 + 𝑦``, and ``\textbf{bold}`` gives ``𝐛𝐨𝐥𝐝``. If you are indexing the
156+
output, comparing it against stored strings, or feeding it to a program that
157+
expects ASCII, switch the unicode alphabets off with ``math_fontstyle=False,
158+
text_fontstyle=False``.
159+
160+
To restore `pylatexenc 2`'s behavior, set ``math_fontstyle=None,
161+
text_mathmode=False, math_mode='text'``. For example::
162+
163+
from pylatexenc.latex2text import LatexNodes2Text
164+
165+
latex = r'$\gamma x+y + \mathcal{Z}$ and \textbf{bold}'
166+
167+
# pylatexenc 3 default
168+
LatexNodes2Text().latex_to_text(latex)
169+
# -> 'γ𝑥 + 𝑦 + 𝒵 and 𝐛𝐨𝐥𝐝'
170+
171+
# the new math renderer, with all unicode alphabets dropped:
172+
LatexNodes2Text(math_fontstyle=False,
173+
text_fontstyle=False).latex_to_text(latex)
174+
# -> 'γx + y + Z and bold'
175+
176+
# Restore pylatexenc 2 behavior: legacy rendering engine; upright
177+
# default math font, but \mathcal{}, \mathbb{} still produce
178+
# the relevant unicode fonts
179+
LatexNodes2Text(math_mode='text',
180+
math_fontstyle=None,
181+
text_fontstyle=False).latex_to_text(latex)
182+
# -> 'γ x+y + 𝒵 and bold'
183+
184+
The command-line tool takes
185+
``--text-fontstyle=off --math-fontstyle=none --math-mode=text`` for the same
186+
purposes.
151187

152188
- Paragraph breaks (``\n\n``) as well as ``^`` and ``_`` are now reported as
153189
their own *specials* nodes. This means that text which used to come back as
@@ -163,13 +199,37 @@ A couple things to look out for
163199
or simply concatenating the ``chars`` of every chars node in a list, you'll
164200
need to handle those specials nodes as well.
165201

166-
- The default macro and environment database learned a few new definitions,
167-
including ``\href`` (which takes two arguments), ``\part``, ``\paragraph``
168-
(which was misspelled in the `pylatexenc 2` database, and hence unknown), and
169-
the ``{lstlisting}`` environment. When a macro becomes known, the ``{...}``
170-
groups that follow it are parsed as its *arguments* instead of remaining
171-
sibling group nodes, so the shape of the node tree changes for documents that
172-
use them.
202+
To restore pylatexenc v2's behavior (`\n\n` kept as chars, `_`/`^` not
203+
specials), exclude the corresponding categories from the default latex context
204+
DB::
205+
206+
from pylatexenc import latexwalker, latex2text
207+
208+
# restore pylatexenc v2 behavior: \n\n, _, ^ as chars and not specials
209+
latex_context = latexwalker.get_default_latex_context_db().filtered_context(
210+
exclude_categories=["latex-paragraph", "latex-base-subsuperscripts"]
211+
)
212+
213+
# Use in latex2text directly -- kwargs of latex_to_text are directly
214+
# handed over as LatexWalker constructor arguments
215+
text = latex2text.LatexNodes2Text().latex_to_text(
216+
…,
217+
latex_context=latex_context
218+
)
219+
220+
# Alternatively, if you want to create a walker object yourself:
221+
walker = latexwalker.LatexWalker(…, latex_context=latex_context)
222+
nodelist, _ = walker.parse_content() # returns (nodes, parsing_state_delta)
223+
text = latex2text.LatexNodes2Text().nodelist_to_text( nodelist )
224+
225+
226+
The :py:mod:`~pylatexenc.latex2text` module keeps a database of its own, in
227+
which the text replacements for ``^`` and ``_`` sit in a category of the same
228+
name. One could disable those definitions there as well with a corresponding
229+
``latex2text.get_default_latex_context_db().filtered_context(…)`` call;
230+
however, it is not necessary to do so because a walker that no longer reports
231+
``^`` and ``_`` as specials hands them to `latex2text` inside ordinary chars
232+
nodes, so their text replacements are never looked up.
173233

174234
- If you created a :py:class:`~pylatexenc.macrospec.LatexContextDb` database
175235
from scratch, you might suddenly get errors about unknown macros. The default
@@ -205,19 +265,6 @@ A couple things to look out for
205265
that ``isinstance(node.nodeargd, ParsedVerbatimArgs)`` is no longer true for
206266
``\verb``; the `verbatim_text` attribute still works as before.
207267

208-
- We've introduced a new entry point interface for parsing:
209-
:py:meth:`LatexWalker.parse_content()
210-
<pylatexenc.latexwalker.LatexWalker.parse_content>`, with a suitable parser
211-
object from :py:mod:`pylatexenc.latexnodes.parsers` (such as
212-
:py:class:`~pylatexenc.latexnodes.parsers.LatexGeneralNodesParser`). The new
213-
interface returns ``(nodes, parsing_state_delta)`` — the node list along with
214-
any information about state changes that occurred during the parsing.
215-
The earlier interface exposed by `pylatexenc 2`, using
216-
:py:class:`~pylatexenc.latexwalker.LatexWalker` — `get_latex_nodes()`,
217-
`get_token()`, `get_latex_expression()`, `get_latex_braced_group()`,
218-
`get_latex_environment()` and `get_latex_maybe_optional_arg()` keeps working
219-
as it did.
220-
221268
- Building macro specifications with the `pylatexenc 2` `args_parser=` argument
222269
still works, but it is deprecated and now warns.
223270

@@ -226,22 +273,17 @@ A couple things to look out for
226273
Some bug fixes in behavior
227274
--------------------------
228275

229-
- The :py:mod:`~pylatexenc.latex2text` 's ``\paragraph{...}`` output
230-
was fixed to produce simply ``"Paragraph Title\nBody"``. (Pylatexenc 2
231-
didn't get the newlines quite right.)
232-
233276
- The ``verbatim`` and ``lstlisting`` environments no longer report the newline
234277
that immediately follows ``\begin{...}`` as part of their contents, mirroring
235278
what LaTeX itself does.
236279

237280
- An unterminated ``lstlisting`` environment no longer loses its parsed
238281
arguments in tolerant parsing mode; ``nodeargd`` used to be `None` there.
239282

240-
- Fixes for latex2text: ``\href{...}{...}`` and ``\url{...}``; ``{verbatim}``
241-
and ``{lstlisting}``.
283+
- Fixes in `latex2text`, including ``\href{...}{...}``, ``\url{...}``,
284+
``\paragraph{...}``, ``{verbatim}`` and ``{lstlisting}``.
242285

243-
- ``{enumerate}`` items are numbered, and ``\frac{a}`` (with a missing second
244-
argument) no longer emits the literal replacement string ``'%s/%s'``.
286+
- Numbered and hierarchical ``{enumerate}`` items are numbered.
245287

246288
- More extensive support for math operators and symbols in latex2text.
247289

0 commit comments

Comments
 (0)