Following this answer by @StevenB.Segletes, who's also one of the creators of the package listofitems, I'm now trying to use what that package was able to parse from a single-branch SGF string inside a macro.
This is what I would like to be able to achieve, but I think I'm having expansion problems, because I'm getting a Missing \endcsname inserted error:
\long\def\Firstof#1#2\endFirstof{#1}
\ignoreemptyitems
\newcommand{\parseSgf}[1]{
\setsepchar{;/[||]}
\readlist*\Z{#1}
% This loop basically splits on ;, which is a node/move delimiter in SGF
\foreachitem \i \in \Z[]{
\itemtomacro\Z[\icnt, 1]\stoneColor
\itemtomacro\Z[\icnt, 2]\sgfCoords
% These if's test the `key[value]` SGF format for the keys `B` and `W`, which denote Black and White moves, respecitvely
% Other keys typically refer to metadata, or other secondary info.
\if\stoneColor B
\drawStoneFromSgfCoords{black}{\sgfCoords} % if I hardcode the arguments, it works.
% \drawStoneFromSgfCoords{black}{Z[\icnt, 2]} % I've also tried stuff like this directly...
\fi
\if\stoneColor AB
\drawStoneFromSgfCoords{black}{\sgfCoords}
\fi
\if\stoneColor W
\drawStoneFromSgfCoords{white}{\sgfCoords}
\fi
\if\stoneColor AW
\drawStoneFromSgfCoords{white}{\sgfCoords}
\fi
}
}
Ideally, if anyone is able to find a solution to this, I would like it to find both Black or White moves (B and W) and edited (added) stones (AB and AW), so the if's would look like this:
\if\stoneColor { B \OR AB }
...
\if\stoneColor { W \OR AW }
But, of course, I can save this for another question, if it gets to be too much.
Here's a complete example:
\documentclass{article}
\usepackage{tikz}
% From this answer by @DavidCarlisle.
\newcommand\notwhite{black}
\newcommand\notblack{white}
% From this answer by @DavidCarlisle.
\ExplSyntaxOn
\cs_generate_variant:Nn \int_from_alph:n {e}
\NewExpandableDocumentCommand{\stringToCoordX}{ m }{
\int_from_alph:e { \use_i:nn #1 }
}
\NewExpandableDocumentCommand{\stringToCoordY}{ m }{
\int_from_alph:e { \use_ii:nn #1 }
}
\ExplSyntaxOff
\newcommand{\drawStoneFromSgfCoords}[2]{
\pgfmathsetmacro{\x}{\stringToCoordX{#2} - 1}
\pgfmathsetmacro{\y}{\stringToCoordY{#2} - 1}
\draw[draw = \UseName{not#1}, fill = #1, line width = 0.1mm]
(\x * 10cm / 18, \y * 10cm / 18)
circle [radius = 0.2575cm];
}
\usepackage{listofitems}
% From this answer by @StevenB.Segletes.
\long\def\Firstof#1#2\endFirstof{#1}
\ignoreemptyitems
\newcommand{\parseSgf}[1]{
\setsepchar{;/[||]}
\readlist*\Z{#1}
\foreachitem \i \in \Z[]{
\itemtomacro\Z[\icnt, 1]\color
\itemtomacro\Z[\icnt, 2]\sgfCoords
\expandafter\if\expandafter\Firstof\stoneColor\endFirstof B
\drawStoneFromSgfCoords{black}{ab}
\else\expandafter\if\expandafter\Firstof\stoneColor\endFirstof W
\drawStoneFromSgfCoords{white}{cd}
\fi\fi
}
}
\def\sgfA{;B[ab];W[cd]} % not truly valid SGF, just one simple example
\def\sgfB{(;GM[1]FF[4]CA[UTF-8]AP[Sabaki:0.52.2]KM[6.5]SZ[19]DT[2024-02-05];B[as];W[bs];B[cs])}
\def\sgfC{(;GM[1]FF[4]CA[UTF-8]AP[Sabaki:0.52.2]KM[6.5]SZ[19]DT[2024-02-05];B[as];W[bs];B[cs];PL[W]AB[dq]AW[eq])}
\begin{document}
\begin{tikzpicture}
\pgfmathsetmacro{\step}{10 / 18}
\draw[step=\step] (0, 0) grid (10, 10);
% \drawStoneFromSgfCoords{black}{ab}
% \drawStoneFromSgfCoords{white}{cd}
\parseSgf{\sgfA}
\end{tikzpicture}
\end{document}

\expandafter(once) to\colorwhich will not produce anything useful, and also using\ifwhich comapres character code of character tokens. What do you intent to test here? It;s hard to guess from the code shown. – David Carlisle Feb 09 '24 at 17:05\coloras a local variable will break any use of latex color commands in that scope, some but not all tikz color may work but it seems unnecessarily risky – David Carlisle Feb 09 '24 at 17:17\colorin my code, it kinda got mixed up when pasting here. Just fixed it. – psygo Feb 09 '24 at 17:18\expandafter\if\expandafter\Firstof\color\endFirstof Bto\if\color B– David Carlisle Feb 09 '24 at 17:21