
수행원@StevenB.Segletes의 답변입니다., 패키지 작성자 중 한 명이기도 합니다.listofitems
, 이제 해당 패키지가 단일 분기에서 구문 분석할 수 있었던 것을 사용하려고 합니다.SGF매크로 내부의 문자열.
이것이 제가 달성하고 싶은 것이지만 오류가 발생하여 확장 문제가 있는 것 같습니다 Missing \endcsname inserted
.
\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
}
}
B
이상적으로는 누구든지 이에 대한 해결책을 찾을 수 있다면 흑백 동작( 및 W
)과 편집된(추가된) 돌( AB
및 ) 을 모두 찾고 싶습니다. AW
따라서 if는 다음과 같습니다.
\if\stoneColor { B \OR AB }
...
\if\stoneColor { W \OR AW }
하지만 물론 너무 많아지면 다른 질문으로 남겨두겠습니다.
완전한 예는 다음과 같습니다.
\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}
답변1
몇 가지 문제:
을 사용하지 마십시오
\color
. 기존 매크로를 덮어쓰므로... 로 변경했습니다\Color
.의 값은 실제 색상이 아닌 또는
\Color
입니다 . 그래서 실제 색상으로 변환하여 소개 합니다 .B
W
\newcommand\thecolorofB{black}
\newcommand\thecolorofW{white}
\Color
SGF 정의의 괄호도 문제를 일으키고 있습니다. 구문 분석되지 않고 대신 SGF 명령으로 해석되었습니다(그러나 관련
[]
데이터가 누락됨). 따라서 나는 그것들을 소화하기 위해 구문 분석을 직접 연결했습니다. 이 접근 방식은 즉각적인 문제를 해결하지만 나중에 이 문제를 해결하려는 위치에 따라 적합하지 않을 수 있습니다.매크로에 공급하기 전에
\Color
및 의 값을 확장해야 합니다 . 나는 그것들을 확장한 다음 매크로 호출로 확장함으로써 이를 달성했습니다.\sgfCoords
\drawStoneFromSgfCoords
\tmp
\tmp
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}