Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Better error message for unescaped underscores#18357

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
timhoffm wants to merge1 commit intomatplotlib:mainfromtimhoffm:tex-underscore

Conversation

timhoffm
Copy link
Member

PR Summary

Closes#17774.

The solution requires user action#17774 (comment). Therefore, raising with appropriate information is the best way out. We could instead just document that somewhere, but it would be hard to find (even more so if the plot is generated via pandas as in the original example in#17774).

@timhoffmtimhoffm marked this pull request as draftAugust 26, 2020 06:43
@anntzer
Copy link
Contributor

I would suggest either making the underscore package a documented dependency and always\usepackage it, or even just vendor it ourselves and include its source in our preamble, if we're genuinely worried about the dependency, or at least include it automatically if it is present (https://tex.stackexchange.com/a/98205).

jklymak reacted with thumbs up emoji

@timhoffm
Copy link
MemberAuthor

Just checked, that underscore is not installed by default in my MikTeX on win. Therefore, adding that as a hard dependency would potentially annoy users.

I'm fine to either vendoring (does somebody know how to set this up, so that LaTeX will find it?) or automatically including if available. In case of the latter a slight variation of the error message proposed here would still be helpful.

@anntzer
Copy link
Contributor

I think (untested...) you just need to copy underscore.sty to the same (temporary) directory as the one where compilation occurs.

@timhoffm
Copy link
MemberAuthor

Anyone, feel free to implement the vendoring of underscore.sty. That would make this PR obsolete.

Until then, I'll leave this PR open as a draft.

@anntzer
Copy link
Contributor

I think the patch below works; I'll leave it to others to add a test, possibly add a license file (and check that the license file allows such vendoring), and turn this into a PR.

diff --git c/lib/matplotlib/mpl-data/latex/underscore.sty i/lib/matplotlib/mpl-data/latex/underscore.stynew file mode 100644index 000000000..f0cfb895d--- /dev/null+++ i/lib/matplotlib/mpl-data/latex/underscore.sty@@ -0,0 +1,248 @@+% underscore.sty     21-Sep-2005   Donald Arseneau   asnd@triumf.ca+% Make the "_" character print as "\textunderscore" in text.+% Copyright 1998,2001,2005,2006 Donald Arseneau;+% License: LPPL version 1.2 or later.+% Instructions follow after the definitions.++\ProvidesPackage{underscore}[2006/09/13]++\begingroup+ \catcode`\_=\active+ \gdef _{% \relax % No relax gives a small vulnerability in alignments+   \ifx\if@safe@actives\iftrue % must be outermost test!+      \string_%+   \else+      \ifx\protect\@typeset@protect+         \ifmmode \sb \else \BreakableUnderscore \fi+      \else+         \ifx\protect\@unexpandable@protect \noexpand_%+         \else \protect_%+      \fi\fi+    \fi}+  \global\let\ActiveUnderscore=_+  \gdef\normalUnderscoreDef{\let_\ActiveUnderscore}+\endgroup++% At begin: set catcode; fix \long \ttdefault so I can use it in comparisons;+% reapply definition of active _ in output routine (\@firstofone to strip+% away braces, so avoiding deeper nesting).+\AtBeginDocument{%+  {\immediate\write\@auxout{\catcode\number\string`\_ \string\active}}%+  \catcode\string`\_\string=\active+  \edef\ttdefault{\ttdefault}%+  \output=\expandafter\expandafter\expandafter+     {\expandafter\expandafter\expandafter\normalUnderscoreDef+      \expandafter\@firstofone\the\output}%+}++\newcommand{\BreakableUnderscore}{\leavevmode\nobreak\hskip\z@skip+ \ifx\f@family\ttdefault \string_\else \textunderscore\fi+ \usc@dischyph\nobreak\hskip\z@skip}++\DeclareRobustCommand{\_}{%+  \ifmmode \nfss@text{\textunderscore}\else \BreakableUnderscore \fi}+++\let\usc@dischyph\@dischyph+\DeclareOption{nohyphen}{\def\usc@dischyph{\discretionary{}{}{}}}+\DeclareOption{strings}{\catcode`\_=\active}++\ProcessOptions+\ifnum\catcode`\_=\active\else \endinput \fi++%%%%%%%%   Redefine commands that use character strings   %%%%%%%%++\@ifundefined{UnderscoreCommands}{\let\UnderscoreCommands\@empty}{}+\expandafter\def\expandafter\UnderscoreCommands\expandafter{%+  \UnderscoreCommands+  \do\include \do\includeonly+  \do\@input \do\@iinput \do\InputIfFileExists+  \do\ref \do\pageref \do\newlabel+  \do\bibitem \do\@bibitem \do\cite \do\nocite \do\bibcite+  \do\Ginclude@graphics \do\@setckpt+}++% Macro to redefine a macro to pre-process its string argument+% with \protect -> \string.+\def\do#1{% Avoid double processing if user includes command twice!+ \@ifundefined{US\string_\expandafter\@gobble\string#1}{%+   \edef\@tempb{\meaning#1}% Check if macro is just a protection shell...+   \def\@tempc{\protect}%+   \edef\@tempc{\meaning\@tempc\string#1\space\space}%+   \ifx\@tempb\@tempc % just a shell: hook into the protected inner command+     \expandafter\do+       \csname \expandafter\@gobble\string#1 \expandafter\endcsname+   \else % Check if macro takes an optional argument+     \def\@tempc{\@ifnextchar[}%+     \edef\@tempa{\def\noexpand\@tempa####1\meaning\@tempc}%+     \@tempa##2##3\@tempa{##2\relax}%+     \edef\@tempb{\meaning#1\meaning\@tempc}%+     \edef\@tempc{\noexpand\@tempd \csname+        US\string_\expandafter\@gobble\string#1\endcsname}%+     \if \expandafter\@tempa\@tempb \relax 12\@tempa % then no optional arg+       \@tempc #1\US@prot+     \else  % There is optional arg+       \@tempc #1\US@protopt+     \fi+   \fi+ }{}}++\def\@tempd#1#2#3{\let#1#2\def#2{#3#1}}++\def\US@prot#1#2{\let\@@protect\protect \let\protect\string+  \edef\US@temp##1{##1{#2}}\restore@protect\US@temp#1}+\def\US@protopt#1{\@ifnextchar[{\US@protarg#1}{\US@prot#1}}+\def\US@protarg #1[#2]{\US@prot{{#1[#2]}}}++\UnderscoreCommands+\let\do\relax \let\@tempd\relax  % un-do++%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%++\endinput++underscore.sty    13-Sep-2006  Donald Arseneau++Features:+~~~~~~~~~+The "\_" command (which normally prints an underscore character or+facsimile) is altered so that the hyphenation of constituent words+is not affected, and hyphenation is permitted after the underscore.+For example, "compound\_fracture" hyphenates as com- pound\_- frac- ture.+If you prefer the underscore to break without a hyphen (but still with+the same rules for explicit hyphen-breaks) then use the [nohyphen]+package option.++A simple "_" acts just like "\_" in text mode, but makes a subscript+in math mode: activation_energy $E_a$++Both forms use an underscore character if the font encoding contains+one (e.g., "\usepackage[T1]{fontenc}" or typewriter fonts in any encoding),+but they use a rule if there is no proper character.++Deficiencies:+~~~~~~~~~~~~~+The skips and penalties ruin any kerning with the underscore character+(when a character is used).  However, there doesn't seem to be much, if+any, such kerning in the ec fonts, and there is never any kerning with+a rule.++You must avoid "_" in file names and in cite or ref tags, or you must use+the babel package, with its active-character controls, or you must give+the [strings] option, which attempts to redefine several commands (and+may not work perfectly).  Even without the [strings] option or babel, you+can use occasional underscores like: "\include{file\string_name}".++Option: [strings]+~~~~~~~~~~~~~~~~~+The default operation is quite simple and needs no customization; but+you must avoid using "_" in any place where LaTeX uses an argument as+a string of characters for some control function or as a name.  These+include the tags for "\cite" and "\ref", file names for "\input",+"\include", and "\includegraphics", environment names, counter names,+and placement parameters (like "[t]").  The problem with these contexts+is that they are `moving arguments' but LaTeX does not `switch on' the+"\protect" mechanism for them.++If you need to use the underscore character in these places, the package+option [strings] is provided to redefine commands that take such a string+argument so that protection is applied (with "\protect" being "\string").+The list of commands is given in "\UnderscoreCommands", with "\do" before+each; plus several others covering "\input", "\includegraphics, "\cite",+"\ref", and their variants.  Not included are many commands regarding font+names, everything with counter names, environment names, page styles, and+versions of "\ref" and "\cite" defined by external packages (e.g., "\vref"+and "\citeyear").++You can add to the list of supported commands by defining "\UnderscoreCommands"+before loading this package; e.g.++   \usepackage{chicago}+   \newcommand{\UnderscoreCommands}{%   (\cite already done)+     \do\citeNP \do\citeA \do\citeANP \do\citeN \do\shortcite+     \do\shortciteNP \do\shortciteA \do\shortciteANP \do\shortciteN+     \do\citeyear \do\citeyearNP+   }+   \usepackage[strings]{underscore}++Not all commands can be supported this way!  Only commands that take a+string argument *first* can be protected.  One optional argument before+the string argument is also permitted, as exemplified by "\cite": both+"\cite{tags}" and "\cite[text]{tags}" are allowed.  A command like+"\@addtoreset" which takes two counter names as arguments could not+be protected by listing it in "\UnderscoreCommands".++*When you use the [strings] option, you must load this package+last* (or nearly last).++There are two reasons: 1) The redefinitions done for protection must come+after other packages define their customized versions of those commands.+2) The [strings] option requires the "_" character to be activated immediately+in order for the cite and ref tags to be read properly from the .aux file+as plain strings, and this catcode setting might disrupt other packages.++The babel package implements a protection mechanism for many commands,+and will be a complete fix for most documents without the [strings] option.+Many add-on packages are compatible with babel, so they will get the+strings protection also.  However, there are several commands that are+not covered by babel, but can easily be supported by the [strings] and+"\UnderscoreCommands" mechanism.  Beware that using both [strings] and+babel might lead to conflicts, but none are seen yet (load babel last).++Implementation Notes:+~~~~~~~~~~~~~~~~~~~~~+The first setting of "_" to be an active character is performed in a local+group so as to not interfere with other packages.  The catcode setting+is repeated with "\AtBeginDocument" so the definition is in effect for the+text.  However, the catcode setting is repeated immediately when the+[strings] option is detected.++The definition of the active "_" is essentially:++       \ifmmode \sb \else \BreakableUnderscore \fi++where "\sb" retains the normal subscript meaning of "_" and where+"\BreakableUnderscore" is essentially "\_".  The rest of the definition+handles the "\protect"ion without causing "\relax" to be inserted before+the character.++"\BreakableUnderscore" uses "\nobreak\hskip\z@skip" to separate the+underscore from surrounding words, thus allowing TeX to hyphenate them,+but preventing free breaks around the underscore. Next, it checks the+current font family, and uses the underscore character from tt fonts or+otherwise "\textunderscore" (which is a character or rule depending on+the font encoding).  After the underscore, it inserts a discretionary+hyphenation point as "\usc@dischyph", which is usually just "\-"+except that it still works in the tabbing environment, although it+will give "\discretionary{}{}{}" under the [nohyphen] option.  After+that, another piece of non-breaking interword glue is inserted.+Ordinarily, the comparison "\ifx\f@family\ttdefault" will always fail+because "\ttdefault" is `long' whereas "\f@family" is not (boooo hisss),+but "\ttdefault" is redefined to be non-long by "\AtBeginDocument".++The "\_" command is then defined to use "\BreakableUnderscore".++If the [strings] option is not given, then that is all!++Under the [strings] option, the list of special commands is processed to:++ - retain the original command as "\US_"*command* (e.g., "\US_ref")+ - redefine the command as "\US@prot\US_command" for ordinary commands+   ("\US@prot\US_ref") or as "\US@protopt\US_command" when an optional+   argument is possible (e.g., "\US@protopt\US_bibitem").+ - self-protecting commands ("\cite") retain their self-protection.++Diagnosing the state of the pre-existing command is done by painful+contortions involving "\meaning".++"\US@prot" and "\US@protopt" read the argument, process it with+"\protect" enabled, then invoke the saved "\US_command".++Modifications:+~~~~~~~~~~~~~~+13-Sep-2006  Reassert my definition in the output routine (listings).+21-Sep-2005  \includegraphics safe.+12-Oct-2001  Babel (safe@actives) compatibility and [nohyphen] option.++Test file integrity:  ASCII 32-57, 58-126:  !"#$%&'()*+,-./0123456789+:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~diff --git c/lib/matplotlib/texmanager.py i/lib/matplotlib/texmanager.pyindex 254a36fb8..04ef1869a 100644--- c/lib/matplotlib/texmanager.py+++ i/lib/matplotlib/texmanager.py@@ -34,6 +34,7 @@ import logging import os from pathlib import Path import re+import shutil import subprocess from tempfile import TemporaryDirectory@@ -191,6 +192,7 @@ class TexManager:             # geometry is loaded before the custom preamble as convert_psfrags             # relies on a custom preamble to change the geometry.             r"\usepackage[papersize=72in, margin=1in]{geometry}",+            r"\usepackage{underscore}",             self.get_custom_preamble(),             # textcomp is loaded last (if not already loaded by the custom             # preamble) in order not to clash with custom packages (e.g.@@ -312,6 +314,8 @@ class TexManager:             # final output dir ensures that they are on the same filesystem,             # and thus replace() works atomically.             with TemporaryDirectory(dir=Path(dvifile).parent) as tmpdir:+                shutil.copy(+                    cbook._get_data_path("latex/underscore.sty"), tmpdir)                 self._run_checked_subprocess(                     ["latex", "-interaction=nonstopmode", "--halt-on-error",                      texfile], tex, cwd=tmpdir)@@ -334,6 +338,8 @@ class TexManager:          if not os.path.exists(dvifile) or not os.path.exists(baselinefile):             texfile = self.make_tex_preview(tex, fontsize)+            shutil.copy(cbook._get_data_path("latex/underscore.sty"),+                        Path(texfile).parent)             report = self._run_checked_subprocess(                 ["latex", "-interaction=nonstopmode", "--halt-on-error",                  texfile], tex)

@anntzer
Copy link
Contributor

Superseded by#20706.

@timhoffmtimhoffm deleted the tex-underscore branchFebruary 11, 2022 08:21
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers
No reviews
Assignees
No one assigned
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

Cannot make Latex plots when Pandas dataframe has underscore in variable name
2 participants
@timhoffm@anntzer

[8]ページ先頭

©2009-2025 Movatter.jp