Probleme beim Erweitern einer Variable innerhalb eines `\foreachitem` mithilfe des Pakets `listofitems` und eines Makros

Probleme beim Erweitern einer Variable innerhalb eines `\foreachitem` mithilfe des Pakets `listofitems` und eines Makros

Gefolgtdiese Antwort von @StevenB.Segletes, der auch einer der Schöpfer des Pakets istlistofitems, ich versuche jetzt zu verwenden, was dieses Paket aus einem Single-Branch analysieren konnteSGFZeichenfolge innerhalb eines Makros.

Dies ist, was ich gerne erreichen würde, aber ich glaube, ich habe Erweiterungsprobleme, weil ich eine Missing \endcsname insertedFehlermeldung erhalte:

\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
  }
}

Falls irgendjemand eine Lösung hierfür finden kann, würde ich mir im Idealfall wünschen, dass sowohl die Züge von Schwarz oder Weiß ( Bund W) als auch bearbeitete (hinzugefügte) Steine ​​( ABund AW) gefunden werden, sodass die Wenns folgendermaßen aussehen würden:

\if\stoneColor { B \OR AB }
...
\if\stoneColor { W \OR AW }

Aber falls es zu viel wird, kann ich das natürlich für eine andere Frage aufheben.


Hier ist ein vollständiges Beispiel:

\documentclass{article}

\usepackage{tikz}

% From [this answer by @DavidCarlisle](https://tex.stackexchange.com/a/708876/64441).
\newcommand\notwhite{black}
\newcommand\notblack{white}

% From [this answer by @DavidCarlisle](https://tex.stackexchange.com/a/708893/64441).
\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](https://tex.stackexchange.com/a/709014/64441).
\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}

Antwort1

Mehrere Probleme:

  1. Verwenden Sie nicht \color, da es ein vorhandenes Makro überschreibt. Ich habe es in geändert \Color.

  2. Der Wert von \Colorist Boder W, was keine tatsächliche Farbe ist. Daher führe ich \newcommand\thecolorofB{black}und ein, \newcommand\thecolorofW{white}um in eine tatsächliche Farbe umzuwandeln \Color.

  3. Auch die Klammern in den SGF-Definitionen verursachen ein Problem. Sie wurden nicht analysiert, sondern als SGF-Befehle interpretiert (allerdings fehlten die zugehörigen []Daten). Daher habe ich die Analyse so programmiert, dass sie ausgeblendet wird. Dieser Ansatz löst das unmittelbare Problem, ist aber möglicherweise nicht geeignet, je nachdem, wie Sie dieses Problem in Zukunft angehen möchten.

  4. Die Werte von \Colorund \sgfCoordsmüssen erweitert werden, bevor sie Ihrem Makro zugeführt werden \drawStoneFromSgfCoords. Dies habe ich erreicht, indem ich sie in \tmpund dann \tmpin den Makroaufruf erweitert habe.

Das MWE:

\documentclass{article}

\usepackage{tikz}

% From [this answer by @DavidCarlisle](https://tex.stackexchange.com/a/708876/64441).
\newcommand\notwhite{black}
\newcommand\notblack{white}

% From [this answer by @DavidCarlisle](https://tex.stackexchange.com/a/708893/64441).
\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](https://tex.stackexchange.com/a/709014/64441).
\long\def\Firstof#1#2\endFirstof{#1}
\newcommand\thecolorofB{black}
\newcommand\thecolorofW{white}
\ignoreemptyitems
\newcommand{\parseSgf}[1]{%
  \setsepchar{;||(||)/[||]}%
  \readlist*\Z{#1}%
%
  \foreachitem \i \in \Z[]{%
    \itemtomacro\Z[\icnt, 1]\Color
    \itemtomacro\Z[\icnt, 2]\sgfCoords
    \edef\tmp{{\csname thecolorof\Color\endcsname}{\sgfCoords}}%
%
    \expandafter\if\expandafter\Firstof\Color\endFirstof B
      \expandafter\drawStoneFromSgfCoords\tmp
    \else\expandafter\if\expandafter\Firstof\Color\endFirstof W
      \expandafter\drawStoneFromSgfCoords\tmp
    \fi\fi
  }%
}

\def\sgfA{;B[ab];W[cd]}
\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);
    \parseSgf{\sgfC}
  \end{tikzpicture}
\end{document}

Bildbeschreibung hier eingeben

verwandte Informationen