我有以下 MWE
\documentclass{standalone}
\RequirePackage{luatex85}
\usepackage{fontspec}
\usepackage{siunitx}
\usepackage{datatool}
\usepackage{filecontents}
\begin{filecontents*}{myfile.csv}
filename,date,pressure
blabla,2018-03-12,66
\end{filecontents*}
\newcommand{\getfirstrowfromcol}[2]{%
\DTLsetseparator{,}%
\DTLifdbexists{mydb}{\DTLdeletedb{mydb}}{}%
\DTLloadrawdb{mydb}{#1}%
\DTLgetvalue{\myname}{mydb}{1}{\dtlcolumnindex{mydb}{#2}}%
\myname%
}
\begin{document}
\SI{\getfirstrowfromcol{myfile.csv}{pressure}}{\bar}
\end{document}
当我用 lualatex 编译它时,我总是收到错误
! Undefined control sequence.
\GenericError ...
#4 \errhelp \@err@ ...
l.18 \DeclareSIUnit
\A { \ampere }
我的新命令有什么问题?
答案1
您的\getfirstrowfromcol
命令不可扩展。我建议用其他方法执行。
\begin{filecontents*}{myfile.csv}
filename,date,pressure
blabla,2018-03-12,66
\end{filecontents*}
\documentclass{article}
\usepackage{fontspec}
\usepackage{siunitx}
\usepackage{datatool}
\newcommand{\SIfromDB}[4][]{%
\begingroup
\DTLsetseparator{,}%
\DTLifdbexists{mydb}{\DTLdeletedb{mydb}}{}%
\DTLloadrawdb{mydb}{#2}%
\DTLgetvalue{\myname}{mydb}{1}{\dtlcolumnindex{mydb}{#3}}%
\SI[#1]{\myname}{#4}%
\endgroup
}
\begin{document}
\SIfromDB{myfile.csv}{pressure}{\bar}
\end{document}
您还可以致电
\SIfromDB[<options>]{myfile.csv}{pressure}{\bar}
以防您需要传递一些\SI
选项。仅举个例子,如果您将压力条目更改为111.111
,则调用
\SIfromDB[output-decimal-marker={,}]{myfile.csv}{pressure}{\bar}
将打印
答案2
您的宏\getfirstrowfromcol
(重新)定义并传递了宏令牌\myname
。
如何在定义中提供一个可选参数\getfirstrowfromcol
来提供一个宏令牌,其第一个非可选参数将是令牌\myname
?
\documentclass{standalone}
\RequirePackage{luatex85}
\usepackage{fontspec}
\usepackage{siunitx}
\usepackage{datatool}
\usepackage{filecontents}
\begin{filecontents*}{myfile.csv}
filename,date,pressure
blabla,2018-03-12,66
\end{filecontents*}
\makeatletter
\newcommand{\getfirstrowfromcol}[3][\@firstofone]{%
\DTLsetseparator{,}%
\DTLifdbexists{mydb}{\DTLdeletedb{mydb}}{}%
\DTLloadrawdb{mydb}{#2}%
\DTLgetvalue{\myname}{mydb}{1}{\dtlcolumnindex{mydb}{#3}}%
#1{\myname}%
}
\makeatother
\begin{document}
\getfirstrowfromcol{myfile.csv}{pressure} /
\getfirstrowfromcol[\texttt]{myfile.csv}{pressure} /
\getfirstrowfromcol[\SI]{myfile.csv}{pressure}{\bar}
\end{document}
(如果不是\myname
可选参数中提供的宏标记的第一个参数,而是第 n 个参数,则还在可选参数中提供前面的(n-1)个参数。
请注意,在可选参数中嵌套可选参数时,需要将整个可选参数嵌套在花括号中。粗略地说:这些花括号可帮助外部可选参数不会错误地将内部可选参数的右方括号作为其自己的右方括号。处理可选参数的机制将删除这些花括号。
IE,
\macroA[{%<-curly braces surround macroA's optional argument.
\macroB[macroB's optional argument]{macroB's mandatory argument}%
}]{macroA's mandatory argument}
)
答案3
您可以使用以下方法解决问题parse-numbers=false
\documentclass{article}
\usepackage{siunitx}
\usepackage{datatool}
\usepackage{filecontents}
\begin{filecontents*}{myfile.csv}
filename,date,pressure
blabla,2018-03-12,66
\end{filecontents*}
\newcommand{\getfirstrowfromcol}[2]{%
\DTLsetseparator{,}%
\DTLifdbexists{mydb}{\DTLdeletedb{mydb}}{}%
\DTLloadrawdb{mydb}{#1}%
\DTLgetvalue{\myname}{mydb}{1}{\dtlcolumnindex{mydb}{#2}}%
\myname%
}
\begin{document}
\SI[parse-numbers=false]{\getfirstrowfromcol{myfile.csv}{pressure}}{\bar}
\getfirstrowfromcol{myfile.csv}{pressure}
\end{document}
答案4
通过使用 lualatex,可以实现可扩展的宏:
\documentclass{standalone}
\usepackage{fontspec}
\usepackage{siunitx}
\usepackage{datatool}
\usepackage{filecontents}
\begin{filecontents*}{myfile.csv}
filename,date,pressure
blabla,2018-03-12,66
\end{filecontents*}
\newcommand{\getfirstrowfromcol}[2]{%
\directlua{
require("lualibs.lua")
local splitter = utilities.parsers.csvsplitter()
f = io.open("#1", 'r')
s = f:read('*a')
f.close()
local list = splitter(s)
local header = list[1]
local body = list[2]
for colidx, colname in pairs(header) do
if colname == "#2" then
tex.print(body[colidx])
break
end
end
}
}
\begin{document}
\getfirstrowfromcol{myfile.csv}{pressure} /
\texttt{\getfirstrowfromcol{myfile.csv}{pressure}} /
\SI{\getfirstrowfromcol{myfile.csv}{pressure}}{\bar}
\end{document}