# Problem with a Lua function in a \foreach loop

I have written a Lua function to position dates in a timeline that I am drawing with TikZ.

The function seems to work, but when I use it in a \foreach loop I get the following error:

! 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"))}


while if used outside the loop it works.

Here is my MWE (I compile my source file with 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}


and the Lua function (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


Any insight on what is going on?

You had a couple of syntax issues with \foreach: the major was the syntax for evaluate key. It is /pgf/foreach/evaluate=<\variable> as <\macro> using <formula>.

This should work.

\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}

• Thanks for your answer. However, the problem is not solved yet because the nodes with name and date are placed, but the tick is not drawn. Moreover, I have to pay close attention to white spaces, i.e. Galileo/18-10-1989% ,Galileo/18-10-1992% ,Galileo/18-10-1998% ,Galileo/18-10-2010% (if I want to write it as a "list".) Why is that? – Pier Paolo Oct 20 '14 at 16:52