可以自由定义格式的数据库具有以下属性的实体:
ID、十六进制数字、LATEXFORMULA、文字。
该 ID 是唯一的,可以包含数字、点和虚线。示例:
MystructOne.val16_A
HEXNUMBER 始终是类似的地址
0xD0007246
。LATEXFORMULA 看起来将会像这样:
$p = \frac{57426}{10^8} \mathrm{[V]} \cdot i$
LITERAL 将包含类型信息:
UINT(t16)
我可以随意保存数据,但内容是固定的。我该如何保存它们,以便可以在 LaTeX 中使用以下内容访问它们:
\custom{MystructOne.val16_A}{ID}
\custom{MystructOne.val16_A}{HEXNUMBER}
\custom{MystructOne.val16_A}{LATEXFORMULA}
\custom{MystructOne.val16_A}{LITERAL}
有一次我想使用以下命令生成一个表:
foreach key in keysource
{
\custom{key}{ID}
\custom{key}{HEXNUMBER}
\custom{key}{LATEXFORMULA}
\custom{key}{LITERAL}
}
我在 LaTeX 中可以做什么来访问这样的数据?
编辑 #2(替换了之前的编辑)
这是我目前取得的进展:
\documentclass{article}
\usepackage{hyperref}
\newcounter{keylabel}
\newcommand*{\keylabel}[2]{%
\leavevmode%
\raisebox{2ex}[0pt][0pt]{%
\renewcommand*{\thekeylabel}{#1}%
\refstepcounter{keylabel}%
\label{#2}%
}%
#1%
}
\usepackage[T1]{fontenc}
\usepackage{csvtools}
\setcsvseparator{;}
\def\verbID{\texttt{\edef\tmp{\insertID}\expandafter\detokenize\expandafter{\tmp}}}
\newcommand{\DATARow}[4]{\keylabel{#1}{#1} & #2 & #3 & #4\\[.5ex]}
%The keylabel throws a lot of errors here
\begin{document}
%%% - Creating the Table
\CSVtotabular{stackoverflow.csv}%
{|c|c|c|c|}%
{\DATARow{ID}{REGISTER}{TYPE}{FORMULA}}%
{\DATARow{\verbID}{\insertREGISTER}{\insertTYPE}{\insertFORMULA}}%
{\DATARow{\verbID}{\insertREGISTER}{\insertTYPE}{\insertFORMULA}}
\newpage
%%% - Referencing something in the Table:
\noindent
%\ref{A_B_C_D}\\ - Does not work at all
%\ref{ONE}\\ - Does not work at all
%\ref{TWO.FOUR}\\ - Does not work at all
%\ref{Thirty[2]}\\ - Does not work at all
%\ref{TreeHouse}\\ - Does not work at all
\end{document}
最后一步是设置 Keylable 并引用它们。我希望引用像这个答案中那样工作这里。
但我收到了错误和警告。
- 我无法设置按键,有些环境碰撞我不明白。
- 我无法测试这一点,但我想我需要一个 \verbRef。
- 我需要抑制 texlipse 中出现的警告,因为只能在编译时设置键。我不知道该怎么做。
在我可以合理地说我正在查找我需要的值之前,需要清除这些最后的项目。
以下是可用于解决此问题的演示 csv 文件:
ID;REGISTER;TYPE;FORMULA
A_B_C_D;0xD000720C;UINT(16);$Y = \frac{57426}{10^8} \cdot X$
ONE;0xD020720C;UINT(8);$Y = 109 \cdot X$
TWO.FOUR;0xD080720C;INT(16);$Y = \frac{57426}{X}$
Thirty[2];0xD009720C;INT(8);$Y = X$
TreeHouse;0xD200720C;UINT(32);$Y = \frac{X}{10^8} \cdot X$
答案1
不要使用csvtools
它,它已经过时了。以下是使用替换包的答案datatool
:
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{datatool}
\usepackage{hyperref}
\begin{filecontents}{test.csv}
ID;REGISTER;TYPE;FORMULA
A_B_C_D;0xD000720C;UINT(16);$Y = \frac{57426}{10^8} \cdot X$
ONE;0xD020720C;UINT(8);$Y = 109 \cdot X$
TWO.FOUR;0xD080720C;INT(16);$Y = \frac{57426}{X}$
Thirty[2];0xD009720C;INT(8);$Y = X$
TreeHouse;0xD200720C;UINT(32);$Y = \frac{X}{10^8} \cdot X$
\end{filecontents}
\DTLsetseparator{;}
\DTLloaddb{data}{test.csv}
% syntax: \useentry{ID value}{field}
\newcommand{\useentry}[2]{%
% fetch row for given ID field:
\dtlgetrowforvalue{data}{\dtlcolumnindex{data}{ID}}{#1}%
% access required field from current row:
\dtlgetentryfromcurrentrow{\thisval}{\dtlcolumnindex{data}{#2}}%
\thisval
}
\newcounter{keylabel}
\newcommand*{\keylabel}[2]{%
\leavevmode%
\raisebox{2ex}[0pt][0pt]{%
\renewcommand*{\thekeylabel}{#1}%
\refstepcounter{keylabel}%
\label{#2}%
}%
#1%
}
\makeatletter
\DeclareRobustCommand*{\dispID}[1]{%
\def\thisID{#1}%
\@onelevel@sanitize\thisID
\texttt{\thisID}%
}
\makeatother
\newcommand{\DATARow}[4]{%
\keylabel{\dispID{#1}}{#1} & #2 & #3 & #4\\[.5ex]%
}
\begin{document}
Reference entries in the database:
\useentry{A_B_C_D}{FORMULA}
\useentry{Thirty[2]}{REGISTER}
Display all entries in a table:
\begin{tabular}{llll}
ID & Register & Type & Formula\\
\DTLforeach*{data}{\ID=ID,\Register=REGISTER,\Type=TYPE,\Formula=FORMULA}%
{%
\expandafter\DATARow\expandafter{\ID}{\Register}{\Type}{\Formula}%
}
\end{tabular}
Reference something in the table:
\ref{A_B_C_D}
\ref{ONE}
\ref{TWO.FOUR}
\ref{Thirty[2]}
\end{document}
得出的结果为:
答案2
这似乎可以实现你想要的效果,至少我能理解。
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{csvtools}
\setcsvseparator{;}
\def\IDs{}
\let\IDdo\relax
\applyCSVfile{johancsv.csv}
{%
\expandafter\xdef\csname joh@\insertID@@@ID\endcsname{\detokenize\expandafter{\insertID}}%
\expandafter\gdef\csname joh@\insertID@@@REGISTER\expandafter\endcsname\expandafter{\insertREGISTER}%
\expandafter\gdef\csname joh@\insertID@@@TYPE\expandafter\endcsname\expandafter{\insertTYPE}%
\expandafter\gdef\csname joh@\insertID@@@FORMULA\expandafter\endcsname\expandafter{\insertFORMULA}%
\xdef\IDs{\IDs\IDdo{\insertID}}
}
\newcommand{\use}[2]{\csname joh@#1@@@#2\endcsname}
\newcommand{\eachID}[1]{\def\IDdo##1{#1}\IDs}
\begin{document}
\use{A_B_C_D}{FORMULA}
\bigskip
\use{TreeHouse}{TYPE}
\bigskip
\newcounter{formulas}
\eachID{%
\stepcounter{formulas}\noindent
\theformulas\quad\texttt{\use{#1}{ID}}
\use{#1}{FORMULA}\par\medskip
}
\end{document}
对于 CSV 文件的每一行,我们将每个 ID 关联到一些宏,这些宏稍后可以使用
\use{<ID>}{<FIELD>}
你甚至可以说
\use{A_B_C_D}{ID}
用于打印 ID 而不必担心下划线(前提是选择了 T1 编码);最后有一个示例\eachID
。
该宏\eachID
循环遍历 ID 列表并执行参数中指定的操作,其中#1
代表当前 ID。
答案3
我会在 LuaTex 中执行此操作,因为 Lua 可以比 Tex 更简单地执行这种自定义记录提取。
下面的 Lua 代码非常简单(如果您提供示例数据集,我会对其进行测试):
t={} -- The table we store the result in
for line in io.lines "filename" do
id, hex, lstr, lit = line:match "^([^,]+),%s*(0x%x+),%s*(.*),%s*[^,]+$"
t[1+#t] = {id=id, hex=hex, lstr=lst, lit=lit}
end
并使用输入文件中四个逗号分隔字段的命名字段填充表格t
;代码检查十六进制字段是否确实采用十六进制数字的形式。除 Latex 代码字段外,禁止在任何字段中使用逗号。
\directlua
可以使用其中一个 Lua 包装器将上述 Lua 嵌入到 Lua Latex 文档中,并且\custom
还可以定义宏来使用 访问表记录\directlua
。