I want to loop over section
in the following JSON and print name
the number of times it appears under section. How could I do this?
{
"ID": "23",
"section": [
{
"name": "A",
"text": "This is the start of section",
"subsection": [
{
name: "Sub section AA",
text: " This is some text"
},
{
name: "Sub section BB",
text: " This is some text"
}
]
},
{
"name": "B",
"text": "This is the start of the section",
"subsection": [
{
name: "Sub section EE",
text: " This is some text"
},
{
name: "Sub section DD",
text: " This is some text"
}
]
}
]
}
Here is how I am reading and parsing the JSON:
\documentclass{report}
\usepackage{luacode}
% load json file
\begin{luacode}
local json = require("json")
local file = io.open("sample.json")
tab = json.parse(file:read("*all"))
file:close()
\end{luacode}
\begin{document}
The ID of the document is \directlua{tex.print(tab['ID'])}
Here is the list of all the sections:
\end{document}
json.lua
file that parses the JSON (Taken from answer by Henri Menke):
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 }
Update:
I am trying to add dynamic sections / sub-sections using the for loop. For example,
\section{ A }
This is the A section
\addcontentsline{toc}{section}{ Some Sub Section }
\addcontentsline{toc}{section}{Another Sub Section}
\section{ B }
This is the B section
\section{ C }
This is the C section
Like sections and sub-sections, I will also dynamically generate tables from the JSON read.
Best Answer
You can just iterate over the returned Lua table:
The updated json was invalid, I assume this was intended:
So just change the Lua iterations to
A more complete version would need to escape any tex-special characters and guard against empty fields.