Analysieren eines flachen SGF-Strings (mit dem Paket „listofitems“)

Analysieren eines flachen SGF-Strings (mit dem Paket „listofitems“)

Ich versuche, eineSGFZeichenfolge mit dem Paketlistofitems. SGFs sind Bäume in Textform, aber im Moment arbeite ich der Einfachheit halber nur an einfach verzweigten SGFs.

Hier ist ein Beispiel dessen, was ich versuche:

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

sgfAist kein richtiges SGF, nur ein einfaches Beispiel. Ich möchte, dass es eine ungeordnete Liste wie diese ausgibt:

  • Farbe: Bund Koordinaten:ab
  • Farbe: Wund Koordinaten:cd

Ich habe jedoch nicht herausfinden können, wie ich die Dinge richtig verwende \setsepcharund \defpairtrenne oder wie ich sie in einem verwende \foreach.

sgfBist eine richtige SGF-Zeichenfolge. Und es gibt das zusätzliche Problem, dass Schlüssel ignoriert werden, die nicht Boder sind W. Wenn jemand weiß, wie man das mit macht listofitems, wäre das ein Plus.

Antwort1

Ich verstehe, dass Sie in erster Linie an den Teilen der Zeichenfolge interessiert sind, die die Syntax „ B[xy]oder“ haben W[xy](wobei x„und“ yeinzelne Buchstaben sind). Der folgende Code ignoriert daher alles andere.

Dies sollte wahrscheinlich nicht als die endgültige Version betrachtet werden, aber vielleicht kann so etwas funktionieren. Ich habe in diesem Fall expl-Sequenzen verwendet, da die meisten Dinge mit dem Aufteilen von Zeichenfolgen zu tun haben (beachten Sie, dass möglicherweise ein „fehlendes Element“-Fehler auftritt, wenn die Zeichenfolge keine geeignete Syntax enthält):

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

Bildbeschreibung hier eingeben

Antwort2

Hier ist ein listofitemsAnsatz. Allerdings wird nicht auf falsche Syntax in der SGF-Zeichenfolge geprüft, wie z. B. ;B[ab[;W]cd], das auf die gleiche Weise reagiert wie der Testfall \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}

Bildbeschreibung hier eingeben

verwandte Informationen