.png)
Я рисую камни на доске для игры в Го.СГФкоординаты (что мне удалось сделать только благодаря помощи, которую мне дали люди наэтот вопрос) так \drawStoneFromSgfCoords{ab}
.
Однако на одной диаграмме может быть много камней, поэтому было бы практично иметь еще один макрос, например такой: \drawStonesFromSgfCoords{{black, ab}, {white, cd}}
(цвета обычно чередуются, но иногда практичнее иметь список черных координат, а затем белых).
Вот что я сейчас пробую, хотя это не работает (я имею в виду, это работает, просто не с новым макросом):
\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}
\newcommand\stringToCoordX[1]{
\int_from_alph:e{\use_i:nn#1}
}
\newcommand\stringToCoordY[1]{
~\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];
node[color = white] {1};
}
% Example usage: `drawStonesFromSgfCoords{{black, ab}, {white, cd}}`
\newcommand{\drawStonesFromSgfCoords}[1]{
\foreach \coords in {#1}{
\drawStoneFromSgfCoords{{\coords}[0]}{{\coords}[1]}
}
}
\begin{document}
\begin{tikzpicture}
\pgfmathsetmacro{\step}{10 / 18}
\draw[step=\step] (0, 0) grid (10, 10);
\drawStoneFromSgfCoords{black}{ab}
\drawStoneFromSgfCoords{white}{cd}
% \drawStonesFromSgfCoords{{black, ab}, {white, cd}}
\end{tikzpicture}
\end{document}
Каков правильный способ доступа к массивам или их передачи (внутри цикла)?
(Я использую PGF, \foreach
потому что я это знаю.)
решение1
Я думаю, что было бы лучше обрабатывать вложенный clist
список (разделенный запятыми) с помощью инструментов expl, поскольку там уже существуют инструменты для обработки таких списков:
\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];
}
\ExplSyntaxOn
% Example usage: `drawStonesFromSgfCoords{{black, ab}, {white, cd}}`
\NewExpandableDocumentCommand{\drawStonesFromSgfCoords}{ m }{
\clist_set:Nn \l_tmpa_clist { #1 }
\clist_map_inline:Nn \l_tmpa_clist {
\clist_set:Nn \l_tmpb_clist { ##1 }
\clist_pop:NN \l_tmpb_clist \l_tmpa_tl
\clist_pop:NN \l_tmpb_clist \l_tmpb_tl
\exp_args:Noo \drawStoneFromSgfCoords { \l_tmpa_tl } { \l_tmpb_tl }
}
}
\ExplSyntaxOff
\begin{document}
\begin{tikzpicture}
\pgfmathsetmacro{\step}{10 / 18}
\draw[step=\step] (0, 0) grid (10, 10);
%\drawStoneFromSgfCoords{black}{ab}
%\drawStoneFromSgfCoords{white}{cd}
\drawStonesFromSgfCoords{{black, ab}, {white, cd}}
\end{tikzpicture}
\end{document}
Некоторые заметки об используемых командах (хороший обзор и исчерпывающую документацию можно найти вИнтерфейсы L3 PDF):
\clist_set:Nn \l_tmpa_clist { #1 }
сохраняетclist
(список, разделенный запятыми) в переменной токена, чтобы сделать его доступным. В примере{{black, ab}, {white, cd}}
хранится какclist
в переменной токена\l_tmpa_clist
.\clist_map_inline:Nn \l_tmpa_clist { ... }
цикл по каждому элементу вclist
(хранится в переменной token) и выполняет код между фигурными скобками. Текущий элемент доступен через#1
(##1
в примере кода, потому что он вложен на один уровень глубже).\clist_pop:NN \l_tmpb_clist \l_tmpa_tl
берет первый элемент изclist
и сохраняет его в переменной токена (l_tmpa_tl
). Затем он удаляет этот элемент изclist
.\exp_args:Noo \drawStoneFromSgfCoords { \l_tmpa_tl } { \l_tmpb_tl }
сначала расширяет две переменные токена и вставляет результат в качестве аргументов в\drawStoneFromSgfCoords
.
Итак, давайте посмотрим, что произойдет шаг за шагом, если мы скажем \drawStonesFromSgfCoords{{black, ab}, {white, cd}}
:
\NewExpandableDocumentCommand{\drawStonesFromSgfCoords}{ m }{
% store {{black, ab}, {white, cd}} in \l_tmpa_clist
\clist_set:Nn \l_tmpa_clist { #1 }
% loop over items in \l_tmpa_clist
\clist_map_inline:Nn \l_tmpa_clist {
% store {black, ab} in \l_tmpb_clist
\clist_set:Nn \l_tmpb_clist { ##1 }
% store black in \l_tmpa_tl and remove item from clist
\clist_pop:NN \l_tmpb_clist \l_tmpa_tl
% store ab in \l_tmpb_tl and remove item from clist
\clist_pop:NN \l_tmpb_clist \l_tmpb_tl
% expand \l_tmpa_tl and \l_tmpb_tl so that we get
% \drawStoneFromSgfCoords{black}{ab}
\exp_args:Noo \drawStoneFromSgfCoords { \l_tmpa_tl } { \l_tmpb_tl }
% repeat this loop for the next item in the clist in \l_tmpa_clist
}
}