-
Notifications
You must be signed in to change notification settings - Fork 113
Description
Brief outline of the bug
Without comma at the end of \pgfkeys, the MWE produces:
! Extra }, or forgotten \endgroup.
(probably due to \unskip being redefined to become closing-brace). Checked with tl2022 (in unknown state) and tl2023 (in pristine state).
Background: I have a large (a few K-LoC) system of macros based on PGF/TiKZ in use for about a decade, and a few aspects of its operation are quite flaky. (In total, it is probably several man-days lost on trying to debug this.)
This bug seems to be the root cause of ALL the flakiness I observe.
Example of a similar trace
In this shortened form, the traces of the runs with/without the comma are very different. However, in the process of isolation there was one version where the diffs contained a small standalone fragment (paraphrased below by removing irrelevant part). Essentially, at end of the argument-to-\pgfkeys, \unskip is redefined to become close-brace:
@@ -500161,753 +500240,55 @@ edef \pgfkeyscurrentkey {\pgfkeyscurrent
mpty \else \pgfkeys@add@path@as@needed \pgfkeys@spdef \pgfkeyscurrentvalue {#2}
\ifx \pgfkeyscurrentvalue \pgfkeysnovalue@text \pgfkeysifdefined {\pgfkeyscurre
ntkey /.@def}{\pgfkeysgetvalue {\pgfkeyscurrentkey /.@def}{\pgfkeyscurrentvalue
}} {}\fi \ifx \pgfkeyscurrentvalue \pgfkeysvaluerequired \def \pgf@marshal {\p
gfkeysvalueof {/errors/value required/.@cmd}}\expandafter \pgf@marshal \expanda
fter {\pgfkeyscurrentkey }{}\pgfeov \else \pgfkeys@case@one \fi \fi
#1<-every scope/.try
#2<-\pgfkeysnovalue
#3<-
\pgfkeys@spdef #1#2->\futurelet \pgfkeys@possiblespace \pgfkeys@sp@a #2\pgfkeys
@stop \pgfkeys@stop \pgfkeys@stop \relax #1
#1<-\pgfkeyscurrentkey
#2<-every scope/.try
{\futurelet}
-{changing \unskip=\unskip}
-{into \unskip=end-group character }}
-{\hfil}
-{end-group character }}
-! Extra }, or forgotten \endgroup.
-<recently read> }
-
-<template> \unskip \hfil }
- \hskip \tabcolsep \endtemplate
-\pgfkeys@spdef ...uturelet \pgfkeys@possiblespace
- \pgfkeys@sp@a #2\pgfkeys@s...
-
-\pgfkeys@unpack ...s@spdef \pgfkeyscurrentkey {#1}
- \edef \pgfkeyscurrentkey {...
-
-\pgfkeys@@normal ...pgfkeysnovalue =\pgfkeys@stop
- \pgfkeys@parse
-\pgfkeys@@qset ...aultpath {#2/}\pgfkeys@parse #3,
- \pgfkeys@mainstop \def \pg...
-
-\scope ...y@groupfalse \tikzset {every scope/.try}
- \tikz@collect@scope@anims ...
-
-\tikz@picture ...{.5}\tikz@installcommands \scope
- [every picture,#1]\iftikz@...
-
-\tikz@opt [#1]->\tikzpicture [#1]
- \pgfutil@ifnextchar \bgroup {\tikz@ }{\tikz...
-
-\\Tcircled ...vevmode \tikz [baseline=(char.base)]
- {\node [circle,#1,inner se...
-
-\NUMcc ... #1>0 \circledAsDivisor {\NUMc {#2}{#3}}
- \else \NUMc {#2}{#3}\fi
-\joinedRowsInTable ...}\NUMcc 00{14}&\NUMcc 11{13}
- &\NUMcc 00{12}&\NUMcc 01{1...
-l.145 \joinedRowsInTable
-
-? s
+{changing \pgfkeys@possiblespace=undefined}
+{into \pgfkeys@possiblespace=the letter e}
\pgfkeys@sp@a ->\ifx \pgfkeys@possiblespace \pgfkeys@sptoken \expandafter \pgfk
eys@sp@b \else \expandafter \pgfkeys@sp@b \expandafter \fi
{\ifx: (level 2) entered on line 145}
{false}
{\else: \ifx (level 2) entered on line 145}
{\expandafter}
{\expandafter}
{\fi: \ifx (level 2) entered on line 145}
\pgfkeys@sp@b #1 \pgfkeys@stop ->\pgfkeys@sp@c #1
#1<-every scope/.try\pgfkeys@stop \pgfkeys@stop
\pgfkeys@sp@c #1\pgfkeys@stop #2\relax #3->\pgfkeys@temptoks {#1}\edef #3{\the
\pgfkeys@temptoks }
Minimal working example (MWE)
\documentclass{article}
\usepackage{tikz}
\begin{document}
{% \tracingall \tracingstacklevels=0
\pgfkeys{/joinerDefault/.initial=&}% With comma at end, works. Otherwise \unskip is redefined to close-brace, breaking:
\begin{tabular}{c}
\leavevmode\tikz \node {12};
\end{tabular}
}
\end{document}