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

pgfkeys doesn't play well with edef keys #305

Closed
pgf-tikz-bot opened this issue Apr 6, 2014 · 12 comments
Closed

pgfkeys doesn't play well with edef keys #305

pgf-tikz-bot opened this issue Apr 6, 2014 · 12 comments

Comments

@pgf-tikz-bot
Copy link

pgf-tikz-bot commented Apr 6, 2014

Migrated from SourceForge
Author: mirandole
Timestamp: 2014-04-06 10:24:37.816000

Example :

\documentclass {minimal}
\usepackage [utf8]{inputenc}
\usepackage {etex}
\usepackage {pgfkeys}

\loggingall

\pgfkeysedef {/cle}{\noexpand \macro }
\pgfkeys {/cle/.append code=\MACRO }

\expandafter \show \csname pgfk@/cle/.@cmd\endcsname

% \pgfk@/cle/.@cmd  is  "\noexpand \macro \MACRO "

confer pgfkeys.code.tex line 608 :

\long\def\pgfkeysedef#1#2{%
  \long\edef\pgfkeys@temp##1\pgfeov{#2}%
  \pgfkeyslet{#1/.@cmd}{\pgfkeys@temp}%
  \pgfkeyssetvalue{#1/.@body}{#2}%
} 

/.@body is NOT expanded in the definition !!

@pgf-tikz-bot
Copy link
Author

Migrated from SourceForge
Author: gaborit
Timestamp: 2017-01-05 14:18:40.931000

https://sourceforge.net/p/pgf/bugs/_discuss/thread/3fba4423/f5f2/attachment/patch.txt
Here is my proposed patch on pgfkeys.code.tex (from v3.0.1a).

I add the \pgfkeyssetevalue macro and modify the \pgfkeysedef and \pgfkeysedefargs macros to use it.

PS: you may thank wipet on stackexchange that finds the way to define \pgfkeyssetevalue (http://tex.stackexchange.com/q/346779/14500).

@pgf-tikz-bot
Copy link
Author

Migrated from SourceForge
Author: gaborit
Timestamp: 2017-01-08 00:38:18.074000

https://sourceforge.net/p/pgf/bugs/_discuss/thread/3fba4423/b608/attachment/pgfkeys-tests.tex
https://sourceforge.net/p/pgf/bugs/_discuss/thread/3fba4423/b608/attachment/pgfkeys.code.tex.patch
Here is a better patch.

PS: with a test document.

@pgf-tikz-bot
Copy link
Author

Migrated from SourceForge
Author: gaborit
Timestamp: 2017-01-09 15:48:05.858000

https://sourceforge.net/p/pgf/bugs/_discuss/thread/3fba4423/a81a/attachment/pgfkeys.code.tex
Here is my last proposition for pgfkeys.code.tex. I provide the entire file.

@pgf-tikz-bot
Copy link
Author

Migrated from SourceForge
Author: mo-gul
Timestamp: 2018-12-24 11:42:05.018000

  • status: open --> closed-fixed

@pgf-tikz-bot
Copy link
Author

Migrated from SourceForge
Author: mo-gul
Timestamp: 2018-12-24 11:45:06.019000

Thank you for reporting and providing the patch. It is included now.

@polgab
Copy link

polgab commented Dec 16, 2019

Here my new test file (with #669 example) with .txt extension as github don't support .tex attached file!
pgfkeys-tests.txt

Can you reopen this issue?

Thanks.

@hmenke hmenke changed the title Big bug with \pgfkeysedef (expanded definition) pgfkeys doesn't play well with edef keys Dec 16, 2019
@hmenke hmenke reopened this Dec 16, 2019
@hmenke
Copy link
Member

hmenke commented Dec 16, 2019

Do you also have actual use-cases? Most of the stuff that you sent looks very contrived.

@hmenke hmenke added this to the 3.1.6 milestone Dec 17, 2019
@polgab
Copy link

polgab commented Dec 17, 2019

You are right!
This particular issue seems fixed so you can close it.
I'm sure there are still bugs or limits that need to be fixed or, at a minimum, documented. I will look for good use-cases and then I will submit a new issue.

@hmenke
Copy link
Member

hmenke commented Dec 17, 2019

Open issues don't look nice on the bug tracker but they don't hurt. I'll leave this open so we don't forget about it.

@muzimuzhi
Copy link
Member

muzimuzhi commented May 25, 2020

(Not sure if I should open a new issue, but since this one is open ...)

In \pgfkeyssetevalue, we actually want to define \pgfk@#1/.@body to be the expanded result of #2, with doubling of hashes unchanged.

  • The current implementation (v3.1.5b) eliminates the doubled hashes, hence \pgfkeys{/ekey/.ecode={\def\noexpand\test##1{<##1>}}} defines \pgfk@/ekey/.@body to be \def\test#1{#1}, which should be \def\test##1{##1}.
  • \expanded meets our requirement, but it is not fully supported by various engines until texlive 2019.
    % c.f. https://tex.stackexchange.com/a/509706
    \long\def\pgfkeyssetevalue#1#2{%
      \expandafter\edef\csname pgfk@#1\endcsname
      {\unexpanded\expandafter{\expanded{#2}}}%
    }
  • Luckily, \expanded can be emulated. Both the LaTeX3 team (see texdoc source3, sec. 6.6) and Ulrich Diez on TeX-SX (see this answer) have provided such emulation.
  • The new implementation of \pgfkeyssetevalue using \expanded passes the pgfkeys-tests.txt in pgfkeys doesn't play well with edef keys #305 (comment). I have not read and tested the emulated \expanded yet (I will, in the next couple of days).

A full example demonstrating the problem in current implementation and the effect of \expanded:

Example
\documentclass{article}
\usepackage{geometry}
\usepackage{xcolor}
\usepackage{pgfkeys}

% helper macros
% execute \pgfkeys{#1}, then inspect #2/.@cmd and #2/.@body
\def\showKey#1#2{
  \pgfkeys{#1}
  \begingroup
  \large\bfseries After \textcolor{key}{\detokenize{#1}}
  \endgroup
  \par
  \smallskip
  \showcs{pgfk@#2/.@cmd}
  \showcs{pgfk@#2/.@body}
  \medskip
}

\def\showcs#1{
  \makebox[100pt][l]{\expandafter\string\csname #1\endcsname} =
  \expandafter\meaning\csname #1\endcsname\par
}

\begin{document}
\parindent=0pt
\ttfamily

\section{Handler \texttt{.code}}
\colorlet{key}{orange!90!black}

\showKey{/key/.code={\def\test##1{<##1>}}}{/key}
\showKey{/key/.add code={}{\test{#1}}}{/key}

\section{Handler \texttt{.ecode}, current implementation}
\colorlet{key}{magenta!90!black}

\showKey{/ekey/.ecode={\def\noexpand\test##1{<##1>}}}{/ekey}
\showKey{/ekey/.add code={}{\test{#1}}}{/ekey}

% c.f. https://tex.stackexchange.com/a/509706
\long\def\pgfkeyssetevalue#1#2{%
  \expandafter\edef\csname pgfk@#1\endcsname
  {\unexpanded\expandafter{\expanded{#2}}}%
}

\section{Handler \texttt{.ecode}, new implementation using \texttt{\string\expanded}}
\colorlet{key}{cyan!90!black}

\showKey{/ekey/.ecode={\def\noexpand\test##1{<##1>}}}{/ekey}
\showKey{/ekey/.add code={}{\test{#1}}}{/ekey}

\end{document}

image

@hmenke
Copy link
Member

hmenke commented May 26, 2020

Yes, this issue has been a source of a lot of headache. I have thought about using \expanded here previously, which is the only proper solution, but have so far held off on it for the compatibility reasons you mentioned. Maybe I'll ship that for TeX Live 2021.

@muzimuzhi
Copy link
Member

Perhaps the compatibility reason is weaker than you thought, because it only happens when a user uses

  • an engine other than luatex (this is common), and
  • an engine prior to texlive 2019 (this is not rare), and
  • an updated pgf (this is rare).

To sum up, I think most users who upgrade pgf, will also have latest tex engines installed. And users who have old engines installed, will most likely not solely upgrade package(s).

@hmenke hmenke modified the milestones: 3.1.6, 3.1.7 Sep 3, 2020
muzimuzhi added a commit to muzimuzhi/pgf that referenced this issue Mar 24, 2021
This requires \expanded, which wasn't supported by pdftex and xetex
until texlive 2019.
hmenke added a commit that referenced this issue Mar 25, 2021
@hmenke hmenke closed this as completed Mar 31, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

4 participants