1

Following this answer by @JasperHabicht, in my code, I would like to add an option to that macro so, depending on a flag I can execute either \drawMoveFromSgfCoords or \drawStoneFromSgfCoords. I still don't know much about expl3, so this is kinda my pseudocode:

% Parameters
%
% 1: array of {<black | white>, <coordinates}
%
% Example usage: `drawStonesOrMovesFromSgfCoords{{black, ab}, {white, cd}}{true}`
\ExplSyntaxOn
  \NewExpandableDocumentCommand{\drawStonesOrMovesFromSgfCoords}{ m }{ 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 
      % I'm trying to fix what's in-between parentheses below:
      \exp_args:Noo (\bool_if:NN ##2 \drawStoneFromSgfCoords \drawMoveFromSgfCoords) { \l_tmpa_tl } { \l_tmpb_tl }
    }
  }
\ExplSyntaxOff

Here's a more or less complete example (if you know the syntax, this is probably gonna be unnecessary):

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

\newcounter{moveCounter} \setcounter{moveCounter}{1} \newcommand{\drawMoveFromSgfCoords}[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 = \UseName{not#1}] {\themoveCounter};

\stepcounter{moveCounter} }

\ExplSyntaxOn % Example usage: drawMovesOrStonesFromSgfCoords{{black, ab}, {white, cd}} \NewExpandableDocumentCommand{\drawMovesOrStonesFromSgfCoords}{ 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}
\drawMovesOrStonesFromSgfCoords{{black, ab}, {white, cd}}

\end{tikzpicture} \end{document}

psygo
  • 438
  • Your question is far from clear: what are you actually trying to do? I suspect that the command you want is: \str_case:nn. – 314159265358979323 Feb 08 '24 at 14:30
  • I've added a comment to the first code block. I'm trying to basically do a ternary on those 2 macros. – psygo Feb 08 '24 at 14:33
  • 1
    you shouldn't normally need exp_args:... explicitly, and \exp_args:Noo is a bit odd as o just expand one step whereas normally ou want full expansion e if you want it at all but \exp_args:Noo (\bool_if:NN ## applies N to (, o to \bool_if:NN and # which probably wan't the intention? – David Carlisle Feb 08 '24 at 14:56
  • Also, \NewExpandableDocumentCommand{\drawStonesOrMovesFromSgfCoords}{ m }{ m }{ ...} won't work. You need to pass the specification of all the arguments (m etc.) as a single argument. So you'd need \NewExpandableDocumentCommand{\drawStonesOrMovesFromSgfCoords}{ m m }{ ...}. Your code never actually uses the second argument. Probably you wanted #2 rather than ##2? – cfr Feb 08 '24 at 17:40

2 Answers2

2

I wouldn't do it this way myself, but the following code works with relatively conservative changes to your original.

\documentclass{standalone}
\usepackage{tikz}

% From this answer by @DavidCarlisle. \newcommand\notwhite{black} \newcommand\notblack{white}

% From this answer by @DavidCarlisle. \ExplSyntaxOn

\NewExpandableDocumentCommand{\stringToCoordX}{ mm }{ \int_from_alph:n { #1 } } \NewExpandableDocumentCommand{\stringToCoordY}{ mm }{ \int_from_alph:n { #2 } } \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 * 1.8cm},{\y * 1.8cm}) circle [radius = 0.2575cm]; }

\newcounter{moveCounter} \setcounter{moveCounter}{1} \newcommand{\drawMoveFromSgfCoords}[2]{ \pgfmathsetmacro{\x}{\stringToCoordX#2 - 1} \pgfmathsetmacro{\y}{\stringToCoordY#2 - 1} \draw[draw = \UseName{not#1}, fill = #1, line width = 0.1mm] ({\x * 1.8cm},{\y * 1.8cm}) circle [radius = 0.2575cm] node[color = \UseName{not#1}] {\themoveCounter}; \stepcounter{moveCounter} }

\ExplSyntaxOn % Example usage: drawMovesOrStonesFromSgfCoords{{black, ab}, {white, cd}} \NewExpandableDocumentCommand{\drawMovesOrStonesFromSgfCoords}{ sm }{ \clist_set:Nn \l_tmpa_clist { #2 } \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 \IfBooleanTF { #1 } { \ExpandArgs { VV } \drawStoneFromSgfCoords \l_tmpa_tl \l_tmpb_tl }{ \ExpandArgs { VV } \drawMoveFromSgfCoords \l_tmpa_tl \l_tmpb_tl
}
} } \ExplSyntaxOff

\begin{document} \begin{tikzpicture} \pgfmathsetmacro{\step}{10 / 18}

\draw[step=\step] (0, 0) grid (10, 10);

\drawMovesOrStonesFromSgfCoords{{black,ab}, {white, cd}} \end{tikzpicture} \begin{tikzpicture} \pgfmathsetmacro{\step}{10 / 18}

\draw[step=\step] (0, 0) grid (10, 10);

\drawMovesOrStonesFromSgfCoords*{{black, ab}, {white, cd}} \end{tikzpicture} \end{document}

two boards with stones

cfr
  • 198,882
1

You can do:

\ExplSyntaxOn
  % There is no point in doing \NewExpandableDocument as \clist_set:Nn and
  % \clist_pop:NN and \clist_map_inline:Nn are not fully expandable.
  \NewDocumentCommand{\drawMovesOrStonesFromSgfCoords}{ s m }{
    % The s argument, denoted by #1, is "true" in case a star was provided.
    % The s argument, denoted by #1, is "false" in case no star was provided.
    \clist_set:Nn \l_tmpa_clist { #2 }
    \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 
      \IfBooleanTF {#1} { \exp_args:NVV \drawStoneFromSgfCoords } 
                        { \exp_args:NVV \drawMoveFromSgfCoords } 
      \l_tmpa_tl  \l_tmpb_tl
    }
  }
\ExplSyntaxOff

Or:

\ExplSyntaxOn
  % There is no point in doing \NewExpandableDocument as \clist_set:Nn and
  % \clist_pop:NN and \clist_map_inline:Nn are not fully expandable.
  \NewDocumentCommand{\drawMovesOrStonesFromSgfCoords}{ s m }{
    % The s argument, denoted by #1, is "true" in case a star was provided.
    % The s argument, denoted by #1, is "false" in case no star was provided.
    \clist_set:Nn \l_tmpa_clist { #2 }
    \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:Nc
      \exp_args:NVV
      {draw\IfBooleanTF {#1}{Stone}{Move}FromSgfCoords}
      \l_tmpa_tl  \l_tmpb_tl
    }
  }
\ExplSyntaxOff

If you like it complicated, you can nest \exp_args:NnV \use:n {...} \Variable within the n-argument of \exp_args:NnV:

\ExplSyntaxOn
  % There is no point in doing \NewExpandableDocument as \clist_set:Nn and
  % \clist_pop:NN and \clist_map_inline:Nn are not fully expandable.
  \NewDocumentCommand{\drawMovesOrStonesFromSgfCoords}{ s m }{
    % The s argument, denoted by #1, is "true" in case a star was provided.
    % The s argument, denoted by #1, is "false" in case no star was provided.
    \clist_set:Nn \l_tmpa_clist { #2 }
    \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:NnV 
         \use:n 
         {
           \exp_args:NnV 
              \use:n 
              { \IfBooleanTF {#1} {\drawStoneFromSgfCoords} {\drawMoveFromSgfCoords} } 
              \l_tmpa_tl
         } 
         \l_tmpb_tl
    }
  }
\ExplSyntaxOff

Here is 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]; }

\newcounter{moveCounter} \setcounter{moveCounter}{1} \newcommand{\drawMoveFromSgfCoords}[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 = \UseName{not#1}] {\themoveCounter};

\stepcounter{moveCounter} }

\ExplSyntaxOn % There is no point in doing \NewExpandableDocument as \clist_set:Nn and % \clist_pop:NN and \clist_map_inline:Nn are not fully expandable. \NewDocumentCommand{\drawMovesOrStonesFromSgfCoords}{ s m }{ % The s argument, denoted by #1, is "true" in case a star was provided. % The s argument, denoted by #1, is "false" in case no star was provided. \clist_set:Nn \l_tmpa_clist { #2 } \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 \IfBooleanTF {#1} { \exp_args:NVV \drawStoneFromSgfCoords } { \exp_args:NVV \drawMoveFromSgfCoords } \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}
% The unstarred variant does \drawMoveFromSgfCoords:
\drawMovesOrStonesFromSgfCoords{{black, ab}, {white, cd}}

\end{tikzpicture}

\begin{tikzpicture} \pgfmathsetmacro{\step}{10 / 18}

\draw[step=\step] (0, 0) grid (10, 10);

%\drawStoneFromSgfCoords{black}{ab}
%\drawStoneFromSgfCoords{white}{cd}
% The starred variant does \drawStoneFromSgfCoords:
\drawMovesOrStonesFromSgfCoords*{{black, ab}, {white, cd}}

\end{tikzpicture}

\end{document}

Ulrich Diez
  • 28,770