\foreach 循环中的 Lua 函数问题

\foreach 循环中的 Lua 函数问题

我编写了一个 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}

相关内容