@@ -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'$\g amma x+y + \m athcal{Z}$ and \t extbf{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 \m athcal{}, \m athbb{} 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
226273Some 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