In order to have a footer at each page that displays the current page number with the total number of pages (Eg.,4 of 12), I used lastpage package and placed the statement:
\rfoot{\thepage\ of \pageref{LastPage}}
just before the \begin{document} statement.
When I run lualatex doc-1.tex, I get the following warnings at the end.
LaTeX Warning: Reference `LastPage' on page 11 undefined on input line 209.
[11]
Package lastpage Warning: Rerun to get the references right on input line 210.
AED: lastpage setting LastPage
LaTeX Warning: Reference `LastPage' on page 12 undefined on input line 210.
[12] (/Users/amanda/ltx/s/build/store/upload/doc-1.aux)
LaTeX Warning: There were undefined references.
LaTeX Warning: Label(s) may have changed. Rerun to get cross-references right.
This results in footer that looks something similar to:
4 of ??
and the generated document does not have the \tableofcontents. Re-running it resolves the issue.
Is there a way, I could avoid this in the first place? I do not want to rerun the command to get it right the second time (since there would be many different documents all being generated at the same time).
If it is helpful, I have shared the lualatex code that I run to generate the document.
\documentclass[a4paper,12pt]{report}
\usepackage[english]{babel}
\usepackage{luacode}
\begin{luacode*}
local function json_parser()
local lpeg = assert(require("lpeg"))
local C, Cf, Cg, Ct, P, R, S, V =
lpeg.C, lpeg.Cf, lpeg.Cg, lpeg.Ct, lpeg.P, lpeg.R, lpeg.S, lpeg.V
-- number parsing
local digit = R"09"
local dot = P"."
local eE = S"eE"
local sign = S"+-"^-1
local mantissa = digit^1 * dot * digit^0 + dot * digit^1 + digit^1
local exponent = (eE * sign * digit^1)^-1
local real = sign * mantissa * exponent / tonumber
-- optional whitespace
local ws = S" \t\n\r"^0
-- match a literal string surrounded by whitespace
local lit = function(str)
return ws * P(str) * ws
end
-- match a literal string and synthesize an attribute
local attr = function(str,attr)
return ws * P(str) / function() return attr end * ws
end
-- JSON grammar
local json = P{
"object",
value =
V"null_value" +
V"bool_value" +
V"string_value" +
V"real_value" +
V"array" +
V"object",
null_value =
attr("null", nil),
bool_value =
attr("true", true) + attr("false", false),
string_value =
ws * P'"' * C((P'\\"' + 1 - P'"')^0) * P'"' * ws,
real_value =
ws * real * ws,
array =
lit"[" * Ct((V"value" * lit","^-1)^0) * lit"]",
member_pair =
Cg(V"string_value" * lit":" * V"value") * lit","^-1,
object =
lit"{" * Cf(Ct"" * V"member_pair"^0, rawset) * lit"}"
}
return { parse = function(str) return assert(json:match(str)) end }
end
local socket = require("socket")
local json = json_parser()
local file = io.open("sample-true.json")
local start = socket.gettime()
tab = json.parse(file:read("*all"))
texio.write_nl("Time passed parsing JSON: " .. socket.gettime() - start .. " s\\string\n")
file:close()
\end{luacode*}
\begin{luacode}
local function isempty(s)
return s == nil or s == ''
end
function renderSections(tab)
for i,k in ipairs(tab['tableOfContents']) do
local sec_start = socket.gettime()
tex.print ("\string\\chapter{" .. k.section.title .. "}")
tex.print("section text here")
for ii,kk in ipairs(k["subsection"]) do
tex.print ("\string\\section{" .. kk.title .. "}")
tex.print ("some text here")
tex.print("\string\\newline")
for iii, kkk in ipairs(kk["content"]) do
if kkk['type'] == "text" then
if not isempty(kkk["line"]) then
tex.print(kkk["line"])
tex.print("\string\\newline")
end
elseif kkk["type"] == "table" then
local column_count = 0
local row_count = 0
col_schema = ""
for _ in ipairs(kkk["columns"]) do
column_count = column_count + 1
col_schema = col_schema .. " |X"
end
col_schema = col_schema .. "|"
for _ in ipairs(kkk["columns"][1]["values"]) do row_count = row_count + 1 end
if not isempty(kkk.title) then
tex.print("\string\\textbf{" .. kkk.title .."}")
tex.print("\\\\[0.1in]")
end
tex.print("\string\\begin{tabularx}{\\linewidth}{" .. col_schema .. "}")
tex.print("\\hline")
for ci, c in ipairs(kkk["columns"]) do
local c_name = string.gsub(c.name, "&","\\&")
tex.print(c_name)
if ci < column_count then
tex.print(" & ")
end
end
tex.print("\\\\")
tex.print("\\hline")
i = 1
while i <= row_count do
local c_c = 1
while c_c <= column_count do
local row_val = kkk["columns"][c_c]["values"][i]
row_val = string.gsub(row_val, "&", "\\&")
tex.print(row_val)
if c_c < column_count then
tex.print(" & ")
end
c_c = c_c + 1
end
tex.print("\\\\")
tex.print("\\hline")
i = i + 1
end
tex.print("\string\\end{tabularx}")
tex.print("\\\\[0.1in]")
end
end
end
texio.write_nl("Time passed rendering section: " .. socket.gettime() - sec_start .. " s\string\n")
end
end
\end{luacode}
\title{\directlua{tex.print(tab['documentName'])}}
\author{\directlua{tex.print(tab['author'])}}
\usepackage{fancyhdr}
\usepackage{pgffor}
\usepackage{lastpage}
\usepackage{tabularx}
%\usepackage[extreme]{savetrees}
\usepackage[landscape, margin=1in]{geometry}
\usepackage[yyyymmdd,hhmmss]{datetime}
\usepackage{hyperref}
\hypersetup{
colorlinks=true,
linkcolor=blue,
filecolor=magenta,
urlcolor=cyan,
pdftitle={MAC Report},
bookmarks=true,
pdfpagemode=FullScreen,
}
% https://en.wikibooks.org/wiki/LaTeX/Colors
\usepackage[svgnames]{xcolor}
\pagestyle{fancy}
\fancyhf{}
\lhead{\directlua{tex.print(tab['headerFooter']['header']['left'])}}
\rhead{\directlua{tex.print(tab['headerFooter']['header']['right'])}}
\lfoot{\directlua{tex.print(tab['headerFooter']['footer']['left'])}}
\rfoot{\thepage\ of \pageref{LastPage}}
\cfoot{}
\renewcommand*\contentsname{TABLE OF CONTENTS}
\begin{document}
\maketitle
\paragraph{Document Information}
\subparagraph{Document information is given in the table below}
\subparagraph{}
\begin{tabular}{|c| c| c|}
\hline
\textbf{S.No} & \textbf{Item} & \textbf{Information} \\
\hline
1 & Document ID & \directlua{tex.print(tab['documentId'])} \\
\hline
2 & Document Generated At & \directlua{tex.print(tab['documentGeneratedAt'])} \\
\hline
3 & Document Generated By & \directlua{tex.print(tab['documentGeneratedBy'])} \\
\hline
4 & MAC Protocol ID & \directlua{tex.print(tab['macProtocolID'])} \\
\hline
\end{tabular}
%\newpage
%\textcolor{NavyBlue}{TABLE OF CONTENTS}
\tableofcontents
\directlua{renderSections(tab)}
\end{document}
Initial part of the document is static. Most part of the document is generated from renderSections function. I have also shared the json file named sample-true.json, in case you would want to reproduce it.
auxfile, but I doubt that this is practical. – Henri Menke May 09 '19 at 10:32LastPage? If we could detect a page-break somehow, we could try to add a footer then maybe? – Amanda May 09 '19 at 11:03LastPageand the table of contents, is that on every run through the document the data is written to theauxfile. Theauxfile is read whenever the document is processed so on subsequent runs the data stored in theauxfile is read in and can be used anywhere in the document. It is possible to write code that does not use theauxfile but it will only be able to add "dynamic" content later in the document. For something like the number of the last page this is of no value because there are no pages after the last page. – May 09 '19 at 11:18\begin{document}, something like this:\newlabel{LastPage}{{}{123}{}{}{}}, then the number of pages will be known. The effect would be the same as running the document twice, however. Even MS Word requires you to write all the text before it can tell you how many pages are there. – Phelype Oleinik May 09 '19 at 11:40lualatex– Amanda May 11 '19 at 20:55\ref{..},\cite{...}, an index, a table of contents etc. There will usually be warnings for anything that is "missing" in he log file. – May 13 '19 at 11:59.logis a good indicator of whether or not you need to rerun LaTeX. But you can always imagine pathological cases where either (1) reruns are not strictly necessary even though the.logsays you should rerun or (2) the.logdoes not warn about a necessary rerun. See for example https://tex.stackexchange.com/q/479394/35864. That's why tools such aslatexmkthat take care of this are so sophisticated. – moewe May 18 '19 at 07:21