Genealogytree:如何从 csv 文件填充节点字段?

Genealogytree:如何从 csv 文件填充节点字段?

我想使用(主要/通常)相同的节点来生成不同的(子、父、沙钟)图表,因此我想分离节点内容及其结构。

问题:是否有可能使用 csv(或类似文件)填充节点?例如通过查找 id 来获取姓名、出生日期等?如果可以,怎么做?

演示 csvfile 内容:

id,forename,surname,birthdate,location,comment,sex,filname.jpg

演示节点来自https://tex.stackexchange.com/a/389534/112503

\documentclass[landscape,paper=a5]{scrartcl}
\usepackage[all]{genealogytree}
\begin{filecontents*}{file.csv}
id,forename,surname,birthdate,location,comment,sex,filname.jpg
\end{filecontents*}
\usepackage{mwe}

\begin{document}
    \newcommand{\treetitle}{Mr. X}
    
    \begin{tcolorbox}[enhanced,sharp corners,boxrule=0.6pt,left=0pt,right=0pt,
        colback=blue!50!black,interior style image=goldshade.png,
        halign=center,center title,fonttitle=\bfseries,
        title={\treetitle},
        ]
        
        \begin{genealogypicture}[
            processing=database,
            database format=full marriage below,
            node size=2.4cm,
            level size=3.5cm,
            level distance=6mm,
            list separators hang,
            name font=\bfseries,
            surn code={\textcolor{red!50!black}{#1}},
            place text={\newline}{},
            date format=d.mon.yyyy,
            tcbset={
                male/.style={colframe=blue,colback=blue!5},
                female/.style={colframe=red,colback=red!5}
            },
            box={fit basedim=7pt,boxsep=2pt,
                halign=flush left,before upper=\parskip1pt,segmentation style=solid,
                \gtrDBsex
                ,drop fuzzy shadow,
                if image defined={add to width=25mm,right=25mm,segmentation style={solid,shorten >=24mm},
                    underlay={\begin{tcbclipinterior}\path[fill overzoom image=
                            \gtrDBimage
                            ]
                            ([xshift=-24mm]interior.south east) rectangle (interior.north east);
                    \end{tcbclipinterior}},
                }{},
            },
            edges=rounded,
            symbols record reset,
            ]
            sandclock{
                child{
                    g[id=SurnameForename1990]{
                        sex-from-csv,
                        name={forename-from-csv \surn{surename-from-csv}},
                        birth={birthdate-from-csv}{location-from-csv},
                        comment={comment-from-csv},
                        image=example-image-a, %<--filename-from-csv
                    }
                }
            }
        \end{genealogypicture}
    \end{tcolorbox}
    
\end{document}

答案1

persdata-raw.txt您有一个这样的原始数据文件

id, forename, surname, sex, birthdate, birthplace, comment, filname.jpg
father, John, Surname, male, 01-02-1777, Somewhere,    , 
mother, Marta,    , female, 01-02-1800, Paris,    , 
.....

persdate-help.tex所以你需要一个这样的帮助文件

\gtrset{database/.cd,
persdata/father/.style={name=John Surname,birth={01-02-1777}{Somewhere},comment={},},
persdata/mother/.style={name=Marta ,birth={01-02-1800}{Paris},comment={},},
.....
.....
}

使用新密钥persdata看这里),这意味着

\gtrset{
  database/.cd,
  persdata/.is choice,
% with that:
  persdata/JaneID/.style={name=Jane, birth={1-1-1777}{somewhere}}
% ...
% ...
}

有了它我就可以使用语法p[]{persdata=JaneID}

因此我使用newwritepgfplotstable来创建persdata-help.tex

随着安排

  \genealogytree[
    template=signpost, 
    processing=database,
  ]{
    parent{
      g{persdata=c1}
      c{persdata=c2}
      c{persdata=c3}
      p[]{persdata=father}
      p[box={width=33mm}]{persdata=mother}
    }
  }

我得到:

在此处输入图片描述

\def\PersDataRawFilename{persdata-raw.txt}
\begin{filecontents*}[overwrite]{\PersDataRawFilename}
id, forename, surname, sex, birthdate, birthplace, comment, filname.jpg
father, John, Surname, male, 01-02-1777, Somewhere,    , 
mother, Marta,    , female, 01-02-1800, Paris,    , 
c1, Moe,    , male, 01-02-1810,    ,    , 
c2, Boe,    , female, 01-02-1811,    ,    , 
c3, Doe,    , male, 01-02-1812, Unknown, {A comment}, 
\end{filecontents*}



\documentclass[landscape]{article}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.17}

\usepackage{newverbs}
\Verbdef\leftbrace|{|
\Verbdef\rightbrace|}|
\Verbdef\bslash|\|
\Verbdef\aspace| |

\usepackage[all]{genealogytree}
\gtrset{
  database/.cd,
  persdata/.is choice,
%  persdata/JaneID/.style={name=Jane, birth={1-1-1777}{somewhere},},
%  persdata/JohnID/.style={name=John, birth={1-1-1777}{somewhere},},
}

% ==========================================
% Create Helpfile ================================
\pgfplotstableread[col sep=comma, header=true]{persdata-raw.txt}\PersData
\pgfplotstablegetrowsof{\PersData}
\pgfmathtruncatemacro\RowNo{\pgfplotsretval-1}

\def\PersDataHelpFilename{persdata-help.tex}
\newwrite\PersDataHelpFile
\immediate\openout\PersDataHelpFile=\PersDataHelpFilename%
% Write Head:
\immediate\write\PersDataHelpFile{%
   \bslash gtrset\leftbrace database/.cd,}
% Write Entries:
\foreach \n in {0,...,\RowNo}{% ==================
% Read in from raw data:
\pgfplotstablegetelem{\n}{id}\of{\PersData}
\xdef\ID{\pgfplotsretval}
\pgfplotstablegetelem{\n}{forename}\of{\PersData}
\xdef\Forename{\pgfplotsretval}
\pgfplotstablegetelem{\n}{surname}\of{\PersData}
\xdef\Surname{\pgfplotsretval}
\pgfplotstablegetelem{\n}{birthdate}\of{\PersData}
\xdef\Birthdate{\pgfplotsretval}
\pgfplotstablegetelem{\n}{birthplace}\of{\PersData}
\xdef\Birthplace{\pgfplotsretval}
\pgfplotstablegetelem{\n}{comment}\of{\PersData}
\xdef\Comment{\pgfplotsretval}
% Write out:
\immediate\write\PersDataHelpFile{%%
  persdata/\ID/.style=\leftbrace %
      name=\Forename\aspace\Surname,%
      birth=\leftbrace\Birthdate\rightbrace\leftbrace\Birthplace\rightbrace,%
      comment=\leftbrace\Comment\rightbrace,%
      \rightbrace,%
}%%
}% ==================
% Write closing Brace:
\immediate\write\PersDataHelpFile{\rightbrace}% 
\immediate\closeout\PersDataHelpFile
% ==========================================
% ==========================================
% Read in Helpfile in document: 
\input{\PersDataHelpFilename}


%\usepackage{mwe}
\begin{document}
% Test: \RowNo
\pgfplotstabletypeset[string type, 
assign column name/.style={/pgfplots/table/column name={\textbf{#1}}},
]{\PersData}

\bigskip
\begin{tikzpicture}[]
  \genealogytree[
    template=signpost, 
    processing=database,
  ]{
    parent{
      g{persdata=c1}
      c{persdata=c2}
      c{persdata=c3}
      p[]{persdata=father}
      p[box={width=33mm}]{persdata=mother}
    }
  }
\end{tikzpicture}
\end{document}


persdate-help.tex如果仅当原始数据文件发生更改时才写入帮助文件,则可以使用persdata-raw.txt查询(IfFileHasChangedTF看这里):

在此处输入图片描述

% https://tex.stackexchange.com/questions/557511/how-to-query-if-a-file-has-changed-a-iffilehaschanged-conditional?
\begin{filecontents*}{IfFileHasChanged.tex}
\RequirePackage{expl3}
\ExplSyntaxOn
\file_if_exist:nTF { myfile.txt }
  {
    \ior_open:Nn \g_tmpa_ior { myfile.txt }
    \ior_str_get:NN \g_tmpa_ior \l_tmpa_tl
    \ior_close:N \g_tmpa_ior
    \tl_put_right:Nn \l_tmpa_tl { ~change. }
  }
  { \tl_set:Nn \l_tmpa_tl { This~is~my~file. } }
\iow_open:Nn \g_tmpa_iow { myfile.txt }
\iow_now:Nx \g_tmpa_iow { \l_tmpa_tl }
\iow_close:N \g_tmpa_iow
\ExplSyntaxOff

\usepackage{xparse}
\pagestyle{empty}
\ExplSyntaxOn
\prop_new:N \g__cis_file_mdfive_prop
\tl_new:N \l__cis_tmpa_tl
\tl_new:N \l__cis_tmpb_tl
\NewDocumentCommand \IfFileChangedTF { m +m +m }
  { \cis_file_if_changed:nTF {#1} {#2} {#3} }
\prg_new_protected_conditional:Npnn \cis_file_if_changed:n #1 { T, F, TF }
  {
    \file_if_exist:nTF {#1}
      {
        \file_get_mdfive_hash:nN {#1} \l__cis_tmpb_tl
        \prop_get:NnNTF \g__cis_file_mdfive_prop {#1} \l__cis_tmpa_tl
          {
            \str_if_eq:NNTF \l__cis_tmpa_tl \l__cis_tmpb_tl
              { \prg_return_false: }
              {
                \__cis_mdfive_update:nN {#1} \l__cis_tmpb_tl
                \prg_return_true:
              }
          }
          {
            \__cis_mdfive_update:nN {#1} \l__cis_tmpb_tl
            \prg_return_true:
          }
      }
      { \msg_error:nnn { cis } { file-not-found } {#1} }
  }
\makeatletter
\cs_new_protected:Npn \cis@mdfive@update #1 #2
  { \prop_gput:Nnx \g__cis_file_mdfive_prop {#1} {#2} }
\cs_new_protected:Npn \cis@mdfive@save #1 #2
  { \iow_now:Nx \@auxout { \exp_not:N \cis@mdfive@update {#1} {#2} } }
\cs_new_protected:Npn \__cis_mdfive_update:nN #1 #2
  { \cis@mdfive@update {#1} {#2} }
\AtEndDocument
  {
    \prop_map_inline:Nn \g__cis_file_mdfive_prop
      { \cis@mdfive@save {#1} {#2} }
  }
\makeatother
\msg_new:nnn { cis } { file-not-found }
  { File~'#1'~not~found. }
\ExplSyntaxOff
\end{filecontents*}


\def\PersDataRawFilename{persdata-raw.txt}
\begin{filecontents*}[overwrite]{\PersDataRawFilename}
id, forename, surname, sex, birthdate, birthplace, comment, filname.jpg
father, John, Surname, male, 01-02-1777, Somewhere,    , 
mother, Marta,    , female, 01-02-1800, Paris,    , 
c1, Moe,    , male, 01-02-1810,    ,    , 
c2, Boe,    , female, 01-02-1811,    ,    , 
c3, Doe,    , male, 01-02-1812, Unknown, {A comment}, 
\end{filecontents*}



\documentclass[landscape]{article}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.17}

\usepackage{newverbs}
\Verbdef\leftbrace|{|
\Verbdef\rightbrace|}|
\Verbdef\bslash|\|
\Verbdef\aspace| |

\usepackage[all]{genealogytree}
\gtrset{
  database/.cd,
  persdata/.is choice,
%  persdata/JaneID/.style={name=Jane, birth={1-1-1777}{somewhere},},
%  persdata/JohnID/.style={name=John, birth={1-1-1777}{somewhere},},
}

% ==========================================
% Create Helpfile ================================
\def\PersDataHelpFilename{persdata-help.tex}

\pgfplotstableread[col sep=comma, header=true]{\PersDataRawFilename}\PersData
\pgfplotstablegetrowsof{\PersData}
\pgfmathtruncatemacro\RowNo{\pgfplotsretval-1}

\newcommand\MakePersDataHelpfile{%===== command  start ===
\newwrite\PersDataHelpFile
\immediate\openout\PersDataHelpFile=\PersDataHelpFilename%
% Write Head:
\immediate\write\PersDataHelpFile{%
   \bslash gtrset\leftbrace database/.cd,}
% Write Entries:
\foreach \n in {0,...,\RowNo}{% ==================
% Read in from raw data:
\pgfplotstablegetelem{\n}{id}\of{\PersData}
\xdef\ID{\pgfplotsretval}
\pgfplotstablegetelem{\n}{forename}\of{\PersData}
\xdef\Forename{\pgfplotsretval}
\pgfplotstablegetelem{\n}{surname}\of{\PersData}
\xdef\Surname{\pgfplotsretval}
\pgfplotstablegetelem{\n}{birthdate}\of{\PersData}
\xdef\Birthdate{\pgfplotsretval}
\pgfplotstablegetelem{\n}{birthplace}\of{\PersData}
\xdef\Birthplace{\pgfplotsretval}
\pgfplotstablegetelem{\n}{comment}\of{\PersData}
\xdef\Comment{\pgfplotsretval}
% Write out:
\immediate\write\PersDataHelpFile{%%
  persdata/\ID/.style=\leftbrace %
      name=\Forename\aspace\Surname,%
      birth=\leftbrace\Birthdate\rightbrace\leftbrace\Birthplace\rightbrace,%
      comment=\leftbrace\Comment\rightbrace,%
      \rightbrace,%
}%%
}% ==================
% Write closing Brace:
\immediate\write\PersDataHelpFile{\rightbrace}% 
\immediate\closeout\PersDataHelpFile
}% ============ command end   ================
% ==========================================
%\MakePersDataHelpfile %    run command

% Check if Raw Data has changed 1/2
\input{IfFileHasChanged.tex}

%\usepackage{mwe}
\begin{document}
% \texttt{\PersDataRawFilename} has \RowNo rows. 
%
% Check if Raw Data has changed 2/2
\IfFileChangedTF{\PersDataRawFilename}  
  {\MakePersDataHelpfile \def\yesno{yes}}   
       {   \IfFileExists{\PersDataHelpFilename}{}{\MakePersDataHelpfile} 
          \def\yesno{no}    }
% Read in Helpfile in document: 
\input{\PersDataHelpFilename}
% Check if Raw Data has changed - Info
\texttt{\PersDataRawFilename} has changed? \yesno
% \IfFileChangedTF{\PersDataRawFilename}  {yes}   {no} % not 2 times!

\bigskip
\pgfplotstabletypeset[string type, 
assign column name/.style={/pgfplots/table/column name={\textbf{#1}}},
]{\PersData}

\bigskip
\begin{tikzpicture}[]
  \genealogytree[
    template=signpost, 
    processing=database,
  ]{
    parent{
      g{persdata=c1}
      c{persdata=c2}
      c{persdata=c3}
      p[]{persdata=father}
      p[box={width=33mm}]{persdata=mother}
    }
  }
\end{tikzpicture}
\end{document}

相关内容