4.55 Some lualatex examples using Lua inside Latex

4.55.1 Making counter

% !TEX TS-program = lualatex 
\documentclass{article} 
\usepackage{luacode} 
\usepackage{amsmath} 
%------------------------ 
\begin{luacode} 
local x = 0 
function add() 
    x = x +1 
    tex.print(x) 
end 
 
function sub() 
    x = x - 1 
    tex.print(x) 
end 
 
function reset() 
    x = 0 
end 
 
\end{luacode} 
\newcommand\add[0]{ \directlua{add()}}% 
\newcommand\sub[0]{ \directlua{sub()}}% 
\newcommand\reset[0]{ \directlua{reset()}}% 
%------------------- 
\begin{document} 
\reset 
\add 
\add 
\sub 
\add 
\end{document}
 

4.55.2 simplify fraction

see http://tex.stackexchange.com/questions/253693/reducing-fraction-using-latex-3/253716\#253716

\documentclass{article} 
\usepackage{luacode} 
\usepackage{amsmath} 
%------------------------ 
\begin{luacode} 
function simplify(a,b) 
  local function gcd(a,b) 
    if b ~= 0 then 
        return gcd(b, a % b) 
    else 
        return math.abs(a) 
    end 
  end 
 
t = gcd(a, b) 
tex.print("\\frac{"..a/t.."}{"..b/t.."}") 
end 
\end{luacode} 
\newcommand\simplify[2]{\directlua{simplify(#1,#2) }}% 
%------------------- 
\begin{document} 
\noindent Can I make \LaTeX{} reduce a fraction automatically?\\[\baselineskip] 
For example, I would like the fraction 
\begin{equation*} 
  \frac{278\,922}{74\,088} 
\end{equation*} 
 
to be reduced to 
 
\begin{equation*} 
  \simplify{278922}{74088} 
\end{equation*} 
\end{document}
 

The output of the above is

\begin{equation*} \frac {278\,922}{74\,088} \end{equation*}

to be reduced to

\begin{equation*} {278922}{74088} \end{equation*}

4.55.3 read CVS field to Latex table

This uses lua function to read the specific field in the CVS file. For example, given this CVS file in the directory

123,Poty city,Poti,red,-295731.42857144,617222.85714285 
124,Lanchhuti city,Poti,red,-299217.14285715,647851.42857142 
125,Ozurgeti city,Poti,red,-317217.14285715,648422.85714285 
126,Samtredia city,Poti,red,-287502.85714287,672022.85714285
 

and you want to insert, say field located at row 2 and column 5, which is -299217.14285715 in the above, and field at row 1 and column 3, which is Poti then do

\begin{tabular}{|l|l|l|l|l|}\hline 
    1  & \getField{1}{2}   & 3  & 4                & 5 \\\hline 
    6  & 7                 & 8  & \getField{2}{5}  & 9  \\\hline 
    10 & 11                & 12 & 13               & 14 \\\hline 
\end{tabular}
 

The full code is below. I googled lua code to parse CVS files, there are few on the net, I found one that worked and used it. The CVS file is read automatically. Change the cvs file name in the code below and its path as needed. The latex file needs to be compiled with lualatex not pdflatex

\documentclass[]{article} 
\usepackage{luacode} 
 
\begin{luacode*} -- CVS API: http://nocurve.com/simple-csv-read-and-write-using-lua/ 
 local function split(str, sep) 
     fields={} 
     local matchfunc = string.gmatch(str, "([^"..sep.."]+)") 
     if not matchfunc then return {str} end 
     for str in matchfunc do 
         table.insert(fields, str) 
     end 
     return fields 
end 
 
function read(path, sep, tonum) 
    tonum = tonum or true 
    sep = sep or ',' 
    local csvFile = {} 
    local file = assert(io.open(path, "r")) 
    for line in file:lines() do 
        fields = split(line, sep) 
        if tonum then -- convert numeric fields to numbers 
            for i=1,#fields do 
                fields[i] = tonumber(fields[i]) or fields[i] 
            end 
        end 
        table.insert(csvFile, fields) 
    end 
    file:close() 
    return csvFile 
end 
 
local m = read('./c.cvs') -- read file csv file to local matrix m 
 
function getField(row,col) -- API to latex command below 
tex.print(m[row][col]) 
end 
 
\end{luacode*} 
\newcommand\getField[2]{\directlua{getField(#1,#2) }}% 
 
\begin{document} 
 
\begin{table}[] 
    \centering 
    \caption{My example} 
    \begin{tabular}{|l|l|l|l|l|}\hline 
        1  & \getField{1}{2}   & 3  & 4                & 5 \\\hline 
        6  & 7                 & 8  & \getField{2}{5}  & 9  \\\hline 
        10 & 11                & 12 & 13               & 14 \\\hline 
    \end{tabular} 
\end{table} 
 
\end{document}
 

reference tex stackexchange

This below reads a while CVS file to a latex table

\documentclass[]{article} 
\usepackage{luacode} 
 
\begin{luacode*} -- CVS API thanks to http://nocurve.com/simple-csv-read-and-write-using-lua/ 
 local function split(str, sep) 
     fields={} 
     local matchfunc = string.gmatch(str, "([^"..sep.."]+)") 
     if not matchfunc then return {str} end 
     for str in matchfunc do 
         table.insert(fields, str) 
     end 
     return fields 
end 
 
function read(path, sep, tonum) 
    tonum = tonum or true 
    sep = sep or ',' 
    local csvFile = {} 
    local file = assert(io.open(path, "r")) 
    for line in file:lines() do 
        fields = split(line, sep) 
        if tonum then -- convert numeric fields to numbers 
            for i=1,#fields do 
                fields[i] = tonumber(fields[i]) or fields[i] 
            end 
        end 
        table.insert(csvFile, fields) 
    end 
    file:close() 
    return csvFile 
end 
 
function getCVS(fileName) 
 local m = read(fileName) -- read file csv1.txt to matrix m 
 local nRow = #m 
 local nCol = #m[1] 
 
 tex.sprint("\\begin{tabular}{") 
 for j=1,#m[1] do 
     tex.sprint("|l") 
 end 
 tex.print("|}\\hline") 
 
 for i = 1,nRow do 
   for j = 1,nCol do 
       tex.sprint(m[i][j]) 
       if j<nCol then tex.sprint("&") end 
   end 
   tex.print("\\\\ \\hline") 
 end 
 tex.print("\\end{tabular}") 
end 
 
\end{luacode*} 
\newcommand\getCVS[1]{\directlua{getCVS(#1) }}% 
 
\begin{document} 
 
\begin{table}[] 
    \centering 
    \caption{My CVS file in a Latex table} 
    \getCVS{"c.cvs"} 
\end{table} 
 
\end{document}
 

4.55.4 reversing enumeration list

Given enumeration list, where each item just uses one line, to reverse it:

% !TEX TS-program = lualatex 
\documentclass{article} 
\usepackage{luacode} 
\usepackage{amsmath} 
%------------------------ 
\begin{luacode*}  -- copy the list here as is. 
data=[[\item 2001 
      \item 2002 
      \item 2003 
      \item 2005 was a very good year 
      \item 2006 was also a very good year 
      \item 2007 
      ]] 
 
function string:split(sep) --http://lua-users.org/wiki/SplitJoin 
        local sep, fields = sep or ":", {} 
        local pattern = string.format("([^%s]+)", sep) 
        self:gsub(pattern, function(c) fields[#fields+1] = c end) 
        return fields 
end 
 
function flip() 
    lines = data:split("\n") 
    tex.print("\\begin{enumerate}") 
    for i=#lines,1,-1 do 
       tex.print(lines[i]) 
    end 
    tex.print("\\end{enumerate}") 
end 
\end{luacode*} 
\newcommand\flip[0]{ \directlua{flip()}}% 
 
\begin{document} 
\flip{} 
\end{document}
 

Another way is

% !TEX TS-program = lualatex 
\documentclass{article} 
\usepackage{luacode} 
\usepackage{amsmath} 
 
%------------------------ 
\begin{luacode*} 
function split(str, pat)  --http://lua-users.org/wiki/SplitJoin 
   local t = {}  -- NOTE: use {n = 0} in Lua-5.0 
   local fpat = "(.-)" .. pat 
   local last_end = 1 
   local s, e, cap = str:find(fpat, 1) 
   while s do 
      if s ~= 1 or cap ~= "" then 
     table.insert(t,cap) 
      end 
      last_end = e+1 
      s, e, cap = str:find(fpat, last_end) 
   end 
   if last_end <= #str then 
      cap = str:sub(last_end) 
      table.insert(t, cap) 
   end 
   return t 
end 
 
function flip(data) 
    items = split(data,"\\item") 
    tex.print("\\begin{enumerate}") 
    for i=#items,1,-1 do 
       tex.print("\\item "..items[i]) 
    end 
    tex.print("\\end{enumerate}") 
end 
\end{luacode*} 
%------------------- 
 
\begin{document} 
This is my enumeration list 
\begin{enumerate} 
      \item 2001 
      \item 2002 
      \item 2003 
\end{enumerate} 
 
Here it is flipped: 
\directlua{flip(\luastring{\unexpanded{% 
      \item 2001 
      \item 2002 
      \item 2003 
      }})} 
\end{document}
 

The result of the above is

This is my enumeration list

  1. 2001
  2. 2002
  3. 2003

Here it is flipped:

\directlua{flip(\luastring{\unexpanded{% 
      \item 2001 
      \item 2002 
      \item 2003 
      }})}