# Getting cross references for the total pages correct the first time

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.

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()
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{
filecolor=magenta,
urlcolor=cyan,
pdftitle={MAC Report},
bookmarks=true,
pdfpagemode=FullScreen,
}
% https://en.wikibooks.org/wiki/LaTeX/Colors
\usepackage[svgnames]{xcolor}
\pagestyle{fancy}
\fancyhf{}

\rfoot{\thepage\ of \pageref{LastPage}}
\cfoot{}

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

• If you know in advance what ends up on which page, you can just generate an aux file, but I doubt that this is practical. – Henri Menke May 9 '19 at 10:32
• Then it is not possible unless you invent time travel. – Henri Menke May 9 '19 at 10:43
• The way that all references work, including LastPage and the table of contents, is that on every run through the document the data is written to the aux file. The aux file is read whenever the document is processed so on subsequent runs the data stored in the aux file is read in and can be used anywhere in the document. It is possible to write code that does not use the aux file 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. – Andrew May 9 '19 at 11:18
• If you know how many pages there are you can say, before the \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 9 '19 at 11:40
• If anything the second compilation will take a fraction more time as pages such as the table of contents or indexes are not and cannot be put together on the first run through. I am not aware of any way to reduce the compilation time. As far as LaTeX is concerned there is no difference between the first and subsequent compilations, except that there is more data in the aux, toc, ind, ... files – Andrew May 11 '19 at 13:09