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

\pgfimage should support \graphicspath #1314

Open
JasonGross opened this issue Apr 2, 2024 · 9 comments
Open

\pgfimage should support \graphicspath #1314

JasonGross opened this issue Apr 2, 2024 · 9 comments

Comments

@JasonGross
Copy link

JasonGross commented Apr 2, 2024

Brief outline of the bug

Using includegraphics cmd=\pgfimage breaks use of \graphicspath

Minimal working example (MWE)

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{pgfplots}
\DeclareUnicodeCharacter{2212}{−}
\usepgfplotslibrary{groupplots,dateplot}
\usetikzlibrary{patterns,shapes.arrows}
\pgfplotsset{compat=newest}
\usepackage{graphicx}
\usepackage{amssymb}
\begin{document}

\begin{figure}
\centering
\graphicspath{{images/}}
\begin{tikzpicture}
\begin{axis}[
    title=Example Plot,
    xlabel=$x$,
    ylabel={$f(x)$},
]
% Attempting to use \addplot graphics without specifying the full path
\addplot graphics [includegraphics cmd=\pgfimage,xmin=0,xmax=1,ymin=0,ymax=1] {some-image.png};
\end{axis}
\end{tikzpicture}
\caption{Plot with an external image}
\end{figure}

\end{document}
@davidcarlisle
Copy link
Member

I assume you meant an example other than example-image as example-image.pdf is in the default input path and your example as posted works without error with or without the \graphicspath (which isn't used)

@JasonGross
Copy link
Author

Yes, if you put, e.g., example-image.png in images/, then it does not work

@davidcarlisle
Copy link
Member

sure but you need to rename it as otherwise it'll always pick up the standard one anyway the example as posted gives no error whether or not \graphicspath is used and whether or not there is an images subdirectory. it's not my code I'm just an interested observer but is there an advantage here to using \pgfimage rather than using \includegraphics?

@JasonGross
Copy link
Author

Ah, okay, I guess I didn't quite test thoroughly enough, thanks. I've renamed it.

I'm not sure if there's any advantage, but includegraphics cmd=\pgfimage is automatically generated by tikzplotlib.

@muzimuzhi
Copy link
Member

muzimuzhi commented Apr 3, 2024

Duplicate of #565 and #1259.

You can try what I posted in this TeX-SX answer,

\makeatletter
\let\pgfutil@InputIfFileExists=\InputIfFileExists
\let\pgfutil@IfFileExists=\IfFileExists
\makeatother

@JasonGross
Copy link
Author

Is there a way to make this work with \tikzexternalize?

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{pgfplots}
\usepackage{import}
\DeclareUnicodeCharacter{2212}{−}
\usepgfplotslibrary{groupplots,dateplot}
\usetikzlibrary{patterns,shapes.arrows}
\pgfplotsset{compat=newest}
\usepackage{graphicx}
\usepackage{amssymb}
\makeatletter
\let\pgfutil@InputIfFileExists=\InputIfFileExists
\let\pgfutil@IfFileExists=\IfFileExists
\makeatother
\usetikzlibrary{external}
\tikzexternalize
\begin{document}
\immediate\write18{mkdir -p images}
\begin{filecontents}{images/some-image.tex}
\documentclass{article}
\begin{document}
.
\end{document}
\end{filecontents}
\immediate\write18{pdflatex -output-directory=images images/some-image.tex}
\begin{filecontents}{images/foo.tex}
\begin{tikzpicture}
\begin{axis}[
    title=Example Plot,
    xlabel=$x$,
    ylabel={$f(x)$},
]
% Attempting to use \addplot graphics without specifying the full path
\addplot graphics [includegraphics cmd=\pgfimage,xmin=0,xmax=1,ymin=0,ymax=1] {some-image.pdf};
\end{axis}
\end{tikzpicture}
\end{filecontents}
\begin{figure}
\centering
\import{images/}{foo.tex}
\caption{Plot with an external image}
\end{figure}
\end{document}

@muzimuzhi
Copy link
Member

I was wrong in #1314 (comment) in part. This issue is not a direct duplicate of #1259 since apart from \pgfutil@InputIfFileExists and \pgfutil@IfFileExists, to make \pgfimage aware \graphicspath one need to patch \pgf@findfile too.

Example 1 redefines all these three commands and now \pgfimage supports \graphicspath, just like \includegraphics.

\documentclass{article}
\usepackage{tikz}

\makeatletter
\let\pgfutil@InputIfFileExists=\InputIfFileExists
\let\pgfutil@IfFileExists=\IfFileExists

\ifdefined\ExplLoaderFileDate
  \ExplSyntaxOn
  \def\pgfutil@getfullnameTF{\file_get_full_name:nNTF}
  \def\pgfutil@ifemptyTF{\tl_if_empty:nTF}
  \ExplSyntaxOff

  \def\pgf@findfile#1:#2+#3{%
    \begingroup
    % similar to how \Ginput@path is used in \Ginclude@graphics, graphics.sty
    \let\input@path=\Ginput@path
    \pgf@findfile@i#1:#2+{#3}%
    \endgroup
  }
  \def\pgf@findfile@i#1:#2+#3{%
    \pgfutil@getfullnameTF{#3#1}\pgf@filefound
      {\global\let\pgf@filename=\pgf@filefound}%
      {\pgfutil@ifemptyTF{#2}{}{\pgf@findfile@i#2+{#3}}}%
  }
\fi
\makeatother

\graphicspath{{./tikz-gh1314}}

% create sub-dir "./tikz-gh1314" and image "./tikz-gh1314/some-image-2.pdf"
\immediate\write18{mkdir -p tikz-gh1314}
\begin{filecontents}[force]{tikz-gh1314/some-image-2.tex}
\documentclass{standalone}
\begin{document}
\fbox{some-image-2.tex}
\end{document}
\end{filecontents}
\immediate\write18{pdflatex -output-directory=tikz-gh1314 tikz-gh1314/some-image-2.tex}

\begin{document}
\includegraphics{some-image-2}

\pgfimage{some-image-2}
\end{document}

image

Adding the same redefinitions to example in #1314 (comment), it errors in first run, but then works in all following runs. Content of some-image.tex is modified to get some content in a proper-sized image.

! Extra }, or forgotten \endgroup.
\@endfloatbox ...pagefalse \outer@nobreak \egroup 
                                                  \color@endbox 
l.74 \end{figure}

image

Example 2, \tikzexternalize example + patch

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{pgfplots}
\usepackage{import}
\DeclareUnicodeCharacter{2212}{−}
\usepgfplotslibrary{groupplots,dateplot}
\usetikzlibrary{patterns,shapes.arrows}
\pgfplotsset{compat=newest}
\usepackage{graphicx}
\usepackage{amssymb}

\usetikzlibrary{external}
\tikzexternalize

\makeatletter
\let\pgfutil@InputIfFileExists=\InputIfFileExists
\let\pgfutil@IfFileExists=\IfFileExists

\ifdefined\ExplLoaderFileDate
  \ExplSyntaxOn
  \def\pgfutil@getfullnameTF{\file_get_full_name:nNTF}
  \def\pgfutil@ifemptyTF{\tl_if_empty:nTF}
  \ExplSyntaxOff

  \def\pgf@findfile#1:#2+#3{%
    \begingroup
    % similar to how \Ginput@path is used in \Ginclude@graphics, graphics.sty
    \let\input@path=\Ginput@path
    \pgf@findfile@i#1:#2+{#3}%
    \endgroup
  }
  \def\pgf@findfile@i#1:#2+#3{%
    \pgfutil@getfullnameTF{#3#1}\pgf@filefound
      {\global\let\pgf@filename=\pgf@filefound}%
      {\pgfutil@ifemptyTF{#2}{}{\pgf@findfile@i#2+{#3}}}%
  }
\fi
\makeatother

\graphicspath{{tikz-gh1314/}}

% create sub-dir "./tikz-gh1314" and image "./tikz-gh1314/some-image-2.pdf"
\immediate\write18{mkdir -p tikz-gh1314}
\begin{filecontents}[force]{tikz-gh1314/some-image.tex}
\documentclass{standalone}
\begin{document}
\fbox{some-image.tex}
\end{document}
\end{filecontents}
\immediate\write18{pdflatex -output-directory=tikz-gh1314 tikz-gh1314/some-image.tex}

% create file "./tikz-gh1314/foo.tex"
\begin{filecontents}[force]{tikz-gh1314/foo.tex}
\begin{tikzpicture}
  \begin{axis}[
      title=Example Plot,
      xlabel=$x$,
      ylabel={$f(x)$},
  ]
    % Attempting to use \addplot graphics without specifying the full path
    \addplot graphics
      [includegraphics cmd=\pgfimage,xmin=0,xmax=1,ymin=0,ymax=1]
      {some-image.pdf};
  \end{axis}
\end{tikzpicture}
\end{filecontents}

\begin{document}
\begin{figure}
  \centering
  \import{tikz-gh1314/}{foo.tex}
  \caption{Plot with an external image}
\end{figure}
\end{document}

@JasonGross
Copy link
Author

Thank you!

it errors in first run, but then works in all following runs.

What's the cause of the error?

@muzimuzhi
Copy link
Member

I don't know why.

Either removing force or adding noheader option to the filecontents environment for foo.tex fixes the error.

With force option, the same file is written twice, one by main tex file and one by the externalization system call. As the current \jobname is written to header comments unless noheader is specified, I'm guessing the culprit is the change of content of generated file.

Example header

%% LaTeX2e file `bar.tex'
%% generated by the `filecontents' environment
%% from source `tikz-gh1314-external-figure0' on 2024/04/05.
%%

Example 3: A simplified version raising error ! Too many }'s.

If \input bar.tex is used in an environment, then the same error ! Extra }, or forgotten \endgroup. is raised.

\documentclass{article}
\usepackage{tikz}

\usetikzlibrary{external}
\tikzexternalize

\begin{filecontents}[force]{bar.tex}
\begin{tikzpicture}
  \draw (0,0) rectangle (1,1);
\end{tikzpicture}
\end{filecontents}

\begin{document}
\input bar.tex
\end{document}
  • expected image
  • actual/first run image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants