我编写了一个 Lua 函数来定位我用 TikZ 绘制的时间轴中的日期。
该函数似乎有效,但是当我在循环中使用它时\foreach
出现以下错误:
! LuaTeX error ./stardate.lua:52: attempt to compare number with nil
stack traceback:
./stardate.lua:52: in function 'StarDate'
[string "\directlua "]:1: in main chunk.
\StarDate ...directlua {tex.write(StarDate("#1"))}
如果在循环外使用,它就可以起作用。
这是我的 MWE(我使用 LuaLaTeX 编译我的源文件):
\documentclass[a4paper]{article}
\usepackage{tikz}
\directlua{require("stardate.lua")}
\newcommand*{\StarDate}[1]{%
% * <- the argument is a number and should not contain paragraphs
\directlua{tex.write(StarDate("#1"))}%
}
\begin{document}
\def\StartingDate{\StarDate{16-11-1965}}
\begin{tikzpicture}% [scale=.9]
\draw [->] (-.5,0) -- ++(\linewidth,0);
\draw (0,0) node [below] {\StartingDate} -- ++(0,1ex) node [above] {Venera 3};% works
% \foreach [evaluate={\Distance=(\StarDate{\LaunchDate}-\StartingDate);}] \Name/\LaunchDate in % code NOT working
% {%
% Galileo/18-10-1989,
% }{%
% % \pgfmathsetmacro{\Distance}{\StarDate{LaunchDate}-\StartingDate}
% \draw (\Distance ex,0) node [below] {\LaunchDate} -- ++(1ex,0) node [above,align=center] {\Name};%
% }
\end{tikzpicture}
\end{document}
和 Lua 函数(stardate.lua):
-- Converts date given in format DD-MM-YYYY to format YYYY.xxxx
-- ==============================================================
-- Determines if a year is a leap year or not.
-- Leap years are those divisible by 4, but not also divisible
-- by 100 if not divisible by 400.
local function FebDays(Year)
if Year % 4 ~= 0 then
return 28
else
if Year % 100 ~= 0 then
return 29
else
if Year % 400 ~= 0 then
return 28
else
return 29
end
end
end
end
--
-- Returns the number of days for the given Year taking into
-- account if it is a leap year or not.
local function YearDays(Year)
if FebDays(Year) == 28 then
return
365
else
return
366
end
end
--
-- Prints the number of the days of a Month for a certain Year.
local function NumberOfDays(Month, Year)
local DaysMonth = {31, FebDays(Year), 31, 30, 31, 30,
31, 31, 30, 31, 30, 31,}
return
DaysMonth[Month]
end
--
function StarDate(DateStr)
-- Accepts other separators.
local NormalizedDateStr = string.gsub(DateStr, "[ /,.%-]", "-")
local Day, Month, Year = string.match(
NormalizedDateStr, "^(%d%d)%-(%d%d)%-(%d%d%d%d)$"
)
Month = tonumber(Month)
-- IF January THEN the number of days is Day, ELSE sum number of days
-- of months before Month and then add Day.
local MonthDays = 0
if Month > 1 then
for I = 1, Month - 1 do
MonthDays = MonthDays + NumberOfDays(Month, Year)
end
end
local TotDays = MonthDays + Day
local PercentDays = tostring(TotDays / YearDays(Year))
-- Trunc at fourth decimal.
PercentDays = string.match(PercentDays, ".%d%d%d%d")
return
tonumber(Year .. PercentDays)
end
对正在发生的事情有什么了解吗?
答案1
您遇到了几个语法问题\foreach
:主要问题是 key 的语法evaluate
。它是/pgf/foreach/evaluate=<\variable> as <\macro> using <formula>
。
这应该可行。
\documentclass{standalone}
\usepackage{tikz}
\directlua{require("stardate.lua")}
\def\StarDate#1{%
\directlua{tex.sprint(StarDate("#1"))}%
}
\begin{document}
\edef\StartingDate{\StarDate{16-11-1965}}
\begin{tikzpicture}
\draw [->] (-.5,0) -- ++(\linewidth,0);
\draw (0,0)
node [below] {\StartingDate}
--
++(0,1ex)
node [above] {Venera 3};
\foreach \Name/\LaunchDate [%
evaluate = \LaunchDate as \Distance using (\StarDate{\LaunchDate}-\StartingDate)] in {%
Galileo/18-10-1989}{%
\draw (\Distance ex,0)
node [below] {\LaunchDate}
--
++(1ex,0)
node [above,align=center] {\Name};
}
\end{tikzpicture}
\end{document}