Analisando uma string SGF plana (com os itens da lista do pacote)

Analisando uma string SGF plana (com os itens da lista do pacote)

Estou tentando analisar umSGFstring com o pacotelistofitems. SGFs são árvores em formato de texto, mas no momento estou trabalhando apenas em SGFs de ramificação única, para simplificar.

Aqui está um exemplo do que estou tentando fazer:

\documentclass{article}

\usepackage{listofitems}
\usepackage{tikz}

\newcommand{\parseSgf}[1]{
  % From [this answer by @StevenB.Segletes](https://tex.stackexchange.com/a/429895/64441).
  \setsepchar{;}
  \defpair{[]}
  
  \readlist\Z{#1}

  \begin{itemize}
    \foreach \i in {\Z}{
      % TODO: if key is either `B` or `W`:
      \item Color: {\i}[0] and Coords: {\i}[1]
    }
  \end{itemize}
}

\begin{document}
  \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])}

  \parseSgf{\sgfA}
  \parseSgf{\sgfB}
\end{document}

sgfAnão é um SGF adequado, apenas um exemplo simples. Eu gostaria que imprimisse uma lista não ordenada como esta:

  • Cor: Be Coordenadas:ab
  • Cor: We Coordenadas:cd

Mas não consegui descobrir como usar \setsepchare \defpairseparar as coisas corretamente, ou como usá-las em um arquivo \foreach.

sgfBé uma string SGF adequada. E há o problema adicional de ignorar chaves que não são Bor W. Se alguém souber como fazer isso listofitems, seria uma vantagem.

Responder1

Entendo que você está interessado principalmente nas partes da string que possuem a sintaxe B[xy]ou W[xy](onde xe ysão algumas letras únicas). O código abaixo, portanto, ignora todo o resto.

Esta provavelmente não deve ser considerada a versão final, mas talvez algo assim possa servir. Usei sequências expl neste caso, pois a maioria das coisas está relacionada à divisão de strings (observe que um erro de "item ausente" pode aparecer, se a string não contiver nenhuma sintaxe adequada):

\documentclass{article}

\ExplSyntaxOn
\cs_generate_variant:Nn \tl_set:Nn { Ne } % You might need to add this if the version of your TeX installation is not the most recent one 
\cs_generate_variant:Nn \seq_set_split:Nnn { Nne }
\NewDocumentCommand{\parseSgf}{ m }{
  \tl_set:Ne \l_tmpa_tl { #1 }
  % remove ( and ) from string
  \tl_remove_all:Nn \l_tmpa_tl { ( }
  \tl_remove_all:Nn \l_tmpa_tl { ) }
  % store the contents of #1 in a sequence with ; as delimiter
  \seq_set_split:Nne \l_tmpa_seq { ; } { \l_tmpa_tl }
  \begin{itemize}
    % loop over all items in sequence
    \seq_map_inline:Nn \l_tmpa_seq {
      % split string at [ and store result in another sequence
      \seq_set_split:Nne \l_tmpb_seq { [ } { ##1 }
      \bool_if:nT { 
        % test if first part of sequence is B or W
        \str_if_eq_p:ee { \seq_item:Nn \l_tmpb_seq { 1 } } { B } ||
        \str_if_eq_p:ee { \seq_item:Nn \l_tmpb_seq { 1 } } { W } 
      } {
        \tl_set:Ne \l_tmpa_tl { \seq_item:Nn \l_tmpb_seq { 1 } }
        \tl_set:Ne \l_tmpb_tl { \seq_item:Nn \l_tmpb_seq { 2 } }
        % remove ] from string
        \tl_remove_all:Nn \l_tmpb_tl { ] }
        \item Color: ~ \l_tmpa_tl {} ~ and ~ Coords: ~ \l_tmpb_tl
      } 
   }
  \end{itemize}
}
\ExplSyntaxOff

\begin{document}

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

  \parseSgf{\sgfA}
  \parseSgf{\sgfB}
  
\end{document}

insira a descrição da imagem aqui

Responder2

Aqui está uma listofitemsabordagem. No entanto, ele não testará a sintaxe inadequada na string SGF, como ;B[ab[;W]cd], que responderá da mesma forma que o caso de teste \sgfA.

\documentclass{article}
\usepackage{listofitems,tikz}
\long\def\Firstof#1#2\endFirstof{#1}
\ignoreemptyitems
\newcommand{\parseSgf}[1]{%
  \setsepchar{;/[||]}%
  \readlist*\Z{#1}%
  \begin{itemize}
    \foreachitem \i \in \Z[]{%
      \itemtomacro\Z[\icnt,1]\tmp
      % TODO: if key is either `B` or `W`:
      \expandafter\if\expandafter\Firstof\tmp\endFirstof B
        \item Color: \tmp and Coords: \Z[\icnt,2]
      \else\expandafter\if\expandafter\Firstof\tmp\endFirstof W
        \item Color: \tmp and Coords: \Z[\icnt,2]
      \fi\fi
    }%
  \end{itemize}
}
\begin{document}
  \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])}
  \parseSgf{\sgfA}\bigskip
  \parseSgf{\sgfB}
\end{document}

insira a descrição da imagem aqui

informação relacionada