解析扁平 SGF 字串(帶有包列表項)

解析扁平 SGF 字串(帶有包列表項)

我正在嘗試解析肝細胞生長因子與包一起的字串listofitems。 SGF 是文字形式的樹,但為了簡單起見,現在我只研究單一分支的 SGF。

這是我正在嘗試做的事情的一個例子:

\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不是正確的 SGF,只是一個簡單的例子。我希望它列印一個像這樣的無序列表:

  • 顏色:B和座標:ab
  • 顏色:W和座標:cd

但我一直無法弄清楚如何正確使用\setsepchar\defpair分離事物,或者如何在\foreach.

sgfB是一個合適的 SGF 字串。還有一個額外的問題是忽略不是B或 的鍵W。如果有人知道如何做到這一點listofitems,那將是一個優勢。

答案1

我知道您主要對字串中具有語法B[xy]或的部分感興趣W[xy](其中xy是一些單個字母)。因此,下面的程式碼忽略其他所有內容。

這可能不應該被視為最終版本,但也許類似的東西可以做到。在這種情況下,我使用了 expl 序列,因為大多數事情都與分割字串有關(請注意,如果字串不包含任何合適的語法,可能會彈出「缺少項目」錯誤):

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

在此輸入影像描述

答案2

這是一種listofitems方法。但是,它不會測試 SGF 字串中不正確的語法,例如;B[ab[;W]cd],它將以與測試案例相同的方式進行回應\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}

在此輸入影像描述

相關內容