문자열 배열을 통한 루프(실제로는 문자열 배열의 배열, 예: `{{black, ab}, {white, cd}}`)

문자열 배열을 통한 루프(실제로는 문자열 배열의 배열, 예: `{{black, ab}, {white, cd}}`)

바둑판에 돌을 그리고 있어요SGF좌표(사람들이 나에게 준 도움으로만 할 수 있었습니다)이 질문) 이와 같이 \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}

루프 내에서 배열에 액세스하거나 전달하는 올바른 방법은 무엇입니까?

\foreach(나는 그것이 내가 아는 것이기 때문에 PGF를 사용하고 있습니다 .)

답변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토큰 변수에 a(쉼표로 구분된 목록)를 저장하여 액세스할 수 있도록 합니다. 예제의 경우 토큰 변수에 {{black, ab}, {white, cd}}가 저장됩니다 .clist\l_tmpa_clist
  • \clist_map_inline:Nn \l_tmpa_clist { ... }(토큰 변수에 저장된) 의 모든 항목을 반복 clist하고 중괄호 사이의 코드를 실행합니다. 현재 항목은 #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

    }
}

관련 정보