.png)
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}
sgfA
não é um SGF adequado, apenas um exemplo simples. Eu gostaria que imprimisse uma lista não ordenada como esta:
- Cor:
B
e Coordenadas:ab
- Cor:
W
e Coordenadas:cd
Mas não consegui descobrir como usar \setsepchar
e \defpair
separar 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 B
or 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 x
e y
sã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}
Responder2
Aqui está uma listofitems
abordagem. 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}