I have a file structured like this: we can call it input.tex
\begin{document}
\import{./}{Capitolo1.tex}
\import{./}{Capitolo2.tex}
\end{document}
Using this function I can perform a serger operation, replacing the \import command with the content of the desired file (Chapter 1, Chapter 2)
function file_exists(name)
local f = io.open(name, "r")
if f ~= nil then
io.close(f)
return true
else
return false
end
end
function rows_from(file)
if not file_exists(file) then
return {}
end
local rows = {}
for line in io.lines(file) do
rows[#rows + 1] = line
end
return rows
end
function search_for_import(tex)
local tbl = {}
for j = 1, #rows_from(tex) do
if string.sub(rows[j],1,7) == "\\import" then
table.insert(tbl,{
[1] = j, --line
[2] = string.sub(rows[j],13,-2), --file name
})
print(string.sub(rows[j],13,-2))
search_for_import(string.sub(rows[j],13,-2))
end
end
if #tbl > 0 then
temp = tex..".mirror" --create mirror file
io.output(temp)
local line
row = rows_from(tex)
for i = 1, #row do
line = row[i]
for key, value in pairs(tbl) do
if i == value[1] then
print(value[2])
line = row[i+1]
for j = 1, #rows_from(value[2]) do
io.write(rows_from(value[2])[j], "\n")
end
end
end
io.write(line, "\n")
end
io.close()
end
os.execute("move "..temp.." "..tex) --final result
end
This function works fine. But what if the imported file itself had an \import command? My attempt is to use the recursive function
for j = 1, #rows_from(tex) do
if string.sub(rows[j],1,7) == "\\import" then
table.insert(tbl,{
[1] = j,
[2] = string.sub(rows[j],13,-2),
})
print(string.sub(rows[j],13,-2))
search_for_import(string.sub(rows[j],13,-2)) --this
end
end
But this end with an infinite loop.
Ant ideas?
You could set a recursion limit so that it will recursively load the imports until it reaches a certain depth.
function search_for_import(tex, depth) -- First time this is called set depth to 0
if depth > 5 then
return
end
local tbl = {}
for j = 1, #rows_from(tex) do
if string.sub(rows[j],1,7) == "\\import" then
table.insert(tbl,{
[1] = j, --line
[2] = string.sub(rows[j],13,-2), --file name
})
print(string.sub(rows[j],13,-2))
search_for_import(string.sub(rows[j],13,-2), depth + 1)
end
end
... Rest of the code
This way it only ever recurses to a depth of 5.
If you want it to recurse for any depth you could also implement some logic to detect if you have already visited this node. (This may require some tweaking to make it work properly)
function tableContains(haystack, needle)
for _, v in ipairs(haystack)
if v == needle then
return true
end
end
end
function search_for_import(tex, visited) -- First time this is called set visited to an empty array
if tableContains(visited, tex) then
return -- Dont visit an import weve already seen.
end
table.insert(visited, tex)
local tbl = {}
for j = 1, #rows_from(tex) do
if string.sub(rows[j],1,7) == "\\import" then
...
search_for_import(string.sub(rows[j],13,-2), visited)
end
end
... Rest of the code
os.execute("move "..temp.." "..tex) --final result
table.remove(visited, #visited)
end