使用文本中的引用自动从数​​据工具创建表格

使用文本中的引用自动从数​​据工具创建表格

这个问题基于 Peter Grill 的回答“包括主表的行的表”。

该函数\PrintDTLTable将可选的 rowID 列表(数据文件的第一行)作为其第一个参数,并创建一个仅包含这些行的表。rowID 也可用作标签。

BibTeX 通常用于仅列出参考书目中引用的论文。我不知道这种机制是如何工作的,但我想知道是否可以适应这种情况。即,如果我在文本中按标签引用某些行,那么是否有某种方法可以自动生成一个仅包含与文本中出现的标签相对应的行的表格?

\documentclass{article}
\usepackage{array}
\usepackage{multirow}
\usepackage{datatool}
\usepackage{longtable}
\usepackage{etoolbox}
\usepackage{filecontents}
\newcommand{\colhead}[1]{\multicolumn{1}{>{\bfseries}l}{#1}}
\newcounter{tabenum}\setcounter{tabenum}{0}
\newcommand{\nextnuml}[1]{\refstepcounter{tabenum}\thetabenum.\label{#1}}

\begin{filecontents*}{foo.dat}
  Hammer001,   Hammer,    1 ,  0 , 1 , 10 , 1 , \multirow{2}{2in}{light (add some words here to wrap around)}\\
  Hammer002,   Hammer,    2 ,  0 , 1 , 10 , 1 , heavy
  Hammer003,   Hammer,    3 ,  0 , 1 , 10 , 1 , really heavy
  Longsword001,Longsword, 1 , -1 , 2 , 75 , 2 , one-handed
  Longsword002,Longsword, 2 , -1 , 2 , 75 , 2 , two-handed
  Longsword003,Longsword, 3 , -1 , 2 , 75 , 2 , three-handed
\end{filecontents*}

\newcommand{\PrintDTLTable}[2][]{%
 % #1 = list of rowIDs
 % #2 = database to search
  \begin{longtable}{l l l l l l l l}
    % & \colhead{Date} & \colhead{From} & \colhead{To} & \colhead{Email} & \colhead{Subject}\\\hlin
    & \colhead{Label} & \colhead{Cost} & \colhead{Weight} & \colhead{PropA} & \colhead{PropB} & \colhead{PropC} & \colhead{Description}\\\hline
    \DTLforeach
    [\ifblank{#1}{\boolean{true}}{\DTLisSubString{#1}{\RowID}}]
    {#2}{%
      \RowID=RowID,%
      \Label=Label,%
      \Cost=Cost,%
      \Weight=Weight,%
      \PropA=PropA,%
      \PropB=PropB,%
      \PropC=PropC,%
      \Description=Description%
     }{%
       \nextnuml{\RowID} & \Label &\Cost & \Weight & \PropA & \PropB & \PropC & \Description \\
    }%
    \end{longtable}
}%

\begin{document}
% \DTLsetseparator{&}% Define separator of the data
\DTLloaddb[noheader,keys={RowID,Label,Cost,Weight,PropA,PropB,PropC,Description}]{myDB}{foo.dat}

% \DTLdisplaydb{myDB}% Useful for debugging.

\PrintDTLTable[Hammer001,Hammer003,Longsword003]{myDB}
\PrintDTLTable{myDB}

This is a reference to ~\ref{Hammer003}.

\end{document}

代码生成的表格如下:在

\PrintDTLTable[Hammer001,Hammer003,Longsword003]{myDB}

默认情况下,表格由三行组成

Hammer001,Hammer003,Longsword003

由于唯一的引用是Hammer003,因此生成的表应该只包含Hammer003行。

类似地,在 的情况下\PrintDTLTable{myDB},表格默认包含所有 6 行。同样,由于唯一引用的是Hammer003,因此生成的表格应该只包含Hammer003行。

答案1

也许这就是你想要的:

\begin{filecontents*}{\jobname.dat}
  Hammer001,   Hammer,    1 ,  0 , 1 , 10 , 1 , light (add some words here to wrap around)
  Hammer002,   Hammer,    2 ,  0 , 1 , 10 , 1 , heavy
  Hammer003,   Hammer,    3 ,  0 , 1 , 10 , 1 , really heavy
  Longsword001,Longsword, 1 , -1 , 2 , 75 , 2 , one-handed
  Longsword002,Longsword, 2 , -1 , 2 , 75 , 2 , two-handed
  Longsword003,Longsword, 3 , -1 , 2 , 75 , 2 , three-handed
\end{filecontents*}

\documentclass{article}
\usepackage{array}
\usepackage{datatool}
\usepackage{longtable}
\usepackage{etoolbox}

\newcommand{\colhead}[1]{\multicolumn{1}{>{\bfseries}l}{#1}}
\newcounter{tabenum}\setcounter{tabenum}{0}
\newcommand{\nextnuml}[1]{%
  \refstepcounter{tabenum}\thetabenum.\label{#1}%
}

\newcommand{\PrintDTLTable}[2][]{%
 % #1 = list of rowIDs
 % #2 = database to search
  \begin{longtable}{l l l l l l l m{2in}}
  & \colhead{Label} & \colhead{Cost} & \colhead{Weight} &
    \colhead{PropA} & \colhead{PropB} & \colhead{PropC} & \colhead{Description}\\
  \hline
  \DTLforeach
    [%
     \(\equal{#1}{}\AND\DTLisSubString{\ReferencedIDs}{\RowID}\)
     \OR
     \(\DTLisSubString{#1}{\RowID}\AND\DTLisSubString{\ReferencedIDs}{\RowID}\)%
    ]
    {#2}{%
      \RowID=RowID,%
      \Label=Label,%
      \Cost=Cost,%
      \Weight=Weight,%
      \PropA=PropA,%
      \PropB=PropB,%
      \PropC=PropC,%
      \Description=Description%
     }{%
       \nextnuml{\RowID} & \Label &\Cost & \Weight & \PropA & \PropB & \PropC & \Description \\
    }%
    \end{longtable}
}

\makeatletter
\let\oldref\ref
\def\ref#1{%
  \immediate\write\@auxout{%
    \string\gappto\string\ReferencedIDs{#1,}%
  }%
  \oldref{#1}%
}
\def\ReferencedIDs{}
\makeatother


\begin{document}

% \DTLsetseparator{&}% Define separator of the data
\DTLloaddb[noheader,keys={RowID,Label,Cost,Weight,PropA,PropB,PropC,Description}]{myDB}{\jobname.dat}

% \DTLdisplaydb{myDB}% Useful for debugging.

\PrintDTLTable[Hammer001,Hammer003,Longsword003]{myDB}

\PrintDTLTable[Hammer002,Longsword002]{myDB}

This is a reference to ~\ref{Hammer003}.

This is a reference to ~\ref{Longsword002}.

\end{document}

在此处输入图片描述

\ref重新定义宏以写入.aux文件中

\gappto\ReferencedIDs{Hammer003,}
\gappto\ReferencedIDs{Longsword002,}

假设\ref{Hammer003}\ref{Longsword002}出现在文本中。

\ReferencedIDs在作业开始时,宏被初始化为空。在下一次运行时,当 LaTeX 读取.aux文件时,它将看到这些指令,因此在 begin document 处,的值\ReferencedIDs相当于说

\def\ReferencedIDs{Hammer003,Longsword002,}

因为它是如何\gappto工作的。

\DTLforeach调用时,我们会检查可选参数。如果它为空,则当前 ID 仅与匹配\ReferencedIDs。否则,当前 ID 将与可选参数和匹配\ReferencedIDs;如果当前 ID 存在于两个列表中,则打印该行,否则将其省略。

答案2

在此处输入图片描述

\documentclass{article}
\usepackage{array}
\usepackage{longtable}
\makeatletter
\let\oldref\ref
\def\ref#1{\immediate\write\@auxout{\string\expandafter\gdef\noexpand\csname REF:#1\string\endcsname{}}%
\oldref{#1}}


\def\zz#1#2{\noalign{%
\expandafter\ifx\csname REF:#1\endcsname\@empty
\def\@currentlabel{#2}\label{#1}%
\else
\aftergroup\zzapline
\fi}#2}

\long\def\zzapline#1\\{}
\makeatother

\begin{document}

  \begin{longtable}{l l l l l l p{2in}}
  \zz{Hammer001}{Hammer}&    1 &  0 & 1 & 10 & 1 & light (add some words here to wrap around)\\
   \zz{Hammer002}{Hammer}&    2 &  0 & 1 & 10 & 1 & heavy\\
  \zz{Hammer003}{Hammer}&    3 &  0 & 1 & 10 & 1 & really heavy\\
  \zz{Longsword001}{Longsword}& 1 & -1 & 2 & 75 & 2 & one-handed\\
  \zz{Longsword002}{Longsword}& 2 & -1 & 2 & 75 & 2 & two-handed\\
  \zz{Longsword003}{Longsword}& 3 & -1 & 2 & 75 & 2 & three-handed\\% don't miss this out
\end{longtable}


This is a reference to ~\ref{Hammer003} or  ~\ref{Longsword002}.

\end{document}

相关内容