@@ -70,6 +70,8 @@ def _get_preamble():
7070 path = pathlib .Path (fm .findfont (family ))
7171 preamble .append (r"\%s{%s}[Path=\detokenize{%s/}]" % (
7272 command , path .name , path .parent .as_posix ()))
73+ preamble .append (mpl .texmanager ._usepackage_if_not_loaded (
74+ "underscore" , option = "strings" )) # Documented as "must come last".
7375 return "\n " .join (preamble )
7476
7577
@@ -84,9 +86,8 @@ def _get_preamble():
8486_NO_ESCAPE = r"(?<!\\)(?:\\\\)*"
8587_split_math = re .compile (_NO_ESCAPE + r"\$" ).split
8688_replace_escapetext = functools .partial (
87- # When the next character is _, ^, $, or % (not preceded by an escape),
88- # insert a backslash.
89- re .compile (_NO_ESCAPE + "(?=[_^$%])" ).sub , "\\ \\ " )
89+ # When the next character is an unescaped % or ^, insert a backslash.
90+ re .compile (_NO_ESCAPE + "(?=[%^])" ).sub , "\\ \\ " )
9091_replace_mathdefault = functools .partial (
9192 # Replace \mathdefault (when not preceded by an escape) by empty string.
9293 re .compile (_NO_ESCAPE + r"(\\mathdefault)" ).sub , "" )
@@ -106,7 +107,7 @@ def _tex_escape(text):
106107 ``$`` with ``\(\displaystyle %s\)``. Escaped math separators (``\$``)
107108 are ignored.
108109
109- The following characters are escaped in text segments: ``_^$ %``
110+ The following characters are escaped in text segments: ``^ %``
110111 """
111112 # Sometimes, matplotlib adds the unknown command \mathdefault.
112113 # Not using \mathnormal instead since this looks odd for the latex cm font.
@@ -309,8 +310,10 @@ def __init__(self):
309310 test_input = self .latex_header + latex_end
310311 stdout , stderr = latex .communicate (test_input )
311312 if latex .returncode != 0 :
312- raise LatexError ("LaTeX returned an error, probably missing font "
313- "or error in preamble." , stdout )
313+ raise LatexError (
314+ f"LaTeX errored (probably missing font or error in preamble) "
315+ f"while processing the following input:\n { test_input } " ,
316+ stdout )
314317
315318 self .latex = None # Will be set up on first use.
316319 # Per-instance cache.
@@ -358,14 +361,16 @@ def _get_box_metrics(self, tex):
358361 try :
359362 answer = self ._expect_prompt ()
360363 except LatexError as err :
361- raise ValueError ("Error measuring {!r}\n LaTeX Output:\n {}"
364+ # Here and below, use '{}' instead of {!r} to avoid doubling all
365+ # backslashes.
366+ raise ValueError ("Error measuring {}\n LaTeX Output:\n {}"
362367 .format (tex , err .latex_output )) from err
363368 try :
364369 # Parse metrics from the answer string. Last line is prompt, and
365370 # next-to-last-line is blank line from \typeout.
366371 width , height , offset = answer .splitlines ()[- 3 ].split ("," )
367372 except Exception as err :
368- raise ValueError ("Error measuring {!r }\n LaTeX Output:\n {}"
373+ raise ValueError ("Error measuring {}\n LaTeX Output:\n {}"
369374 .format (tex , answer )) from err
370375 w , h , o = float (width [:- 2 ]), float (height [:- 2 ]), float (offset [:- 2 ])
371376 # The height returned from LaTeX goes from base to top;
@@ -864,8 +869,8 @@ def print_pdf(self, fname_or_fh, *, metadata=None, **kwargs):
864869 r"\documentclass[12pt]{minimal}" ,
865870 r"\usepackage[papersize={%fin,%fin}, margin=0in]{geometry}"
866871 % (w , h ),
867- _get_preamble (),
868872 r"\usepackage{pgf}" ,
873+ _get_preamble (),
869874 r"\begin{document}" ,
870875 r"\centering" ,
871876 r"\input{figure.pgf}" ,
@@ -975,8 +980,8 @@ def _write_header(self, width_inches, height_inches):
975980 r"\documentclass[12pt]{minimal}" ,
976981 r"\usepackage[papersize={%fin,%fin}, margin=0in]{geometry}"
977982 % (width_inches , height_inches ),
978- _get_preamble (),
979983 r"\usepackage{pgf}" ,
984+ _get_preamble (),
980985 r"\setlength{\parindent}{0pt}" ,
981986 r"\begin{document}%" ,
982987 ])
0 commit comments