local params = {...}
local inputPath = params[1]
local outputPath = params[2]
assert(inputPath, 'no inputPath')
assert(outputPath, 'no outputPath')
local inputFile = io.open(inputPath, 'r')
assert(inputFile, 'could not open '..inputPath)
local macrosByName = {}
local function createMacro(name)
assert(macrosByName[name] == nil, 'macro '..tostring(name)..' doubly declared')
local macro = {}
macrosByName[name] = macro
macro.args = {}
function macro:addArg(arg)
macro.args[#macro.args + 1] = arg
end
macro.lines = {}
function macro:addLine(line)
macro.lines[#macro.lines + 1] = line
end
return macro
end
local curMacro = nil
local inLines = {}
for line in inputFile:lines() do
local name, argLine = line:match('^%s*//!%s+textmacro ([%w%d]+) takes (.+)')
if (name ~= nil) then
curMacro = createMacro(name)
for arg in string.gmatch(argLine, '([%w%d]+)') do
curMacro:addArg(arg)
end
else
if (curMacro ~= nil) then
if line:match('^%s*//! endtextmacro%s*$') then
curMacro = nil
else
if (line:match('^%s*//!%s+runtextmacro%s+([%w%d]+)%((.*)%)%s*$') == nil) then
line = line:match('^%s*//!%s*(.*)')
end
if (line ~= nil) then
curMacro:addLine(line)
end
end
else
inLines[#inLines + 1] = line
end
end
end
inputFile:close()
local outLines = {}
local function addLineToOutput(line)
local name, argLine = line:match('^%s*//!%s+runtextmacro%s+([%w%d]+)%((.*)%)%s*$')
if (name ~= nil) then
print('exec', name)
local macro = macrosByName[name]
assert(macro ~= nil, 'macro '..tostring(name)..' unknown')
outLines[#outLines + 1] = '// textmacro run start: '..tostring(name)..'('..tostring(argLine)..')'
local args = {}
local c = 0
local argLineEx = argLine:gsub('%\\%"', '\n')
for arg in string.gmatch(argLineEx, '%"(.-)%"') do
c = c + 1
arg = arg:gsub('\n', '"')
args[macro.args[c]] = arg
end
for i = 1, #macro.lines, 1 do
local line = macro.lines[i]
local pos, posEnd, arg = line:find('%$([%w%d]+)%$')
while (pos ~= nil) do
print('found', arg)
if (args[arg] ~= nil) then
line = line:sub(1, pos - 1)..args[arg]..line:sub(posEnd + 1, line:len())
posEnd = posEnd + args[arg]:len() - arg:len() - 2
end
pos, posEnd, arg = line:find('%$([%w%d]+)%$', posEnd + 1)
end
addLineToOutput(line)
end
outLines[#outLines + 1] = '// textmacro run end: '..tostring(name)..'('..tostring(argLine)..')'
else
outLines[#outLines + 1] = line
end
end
for i = 1, #inLines, 1 do
addLineToOutput(inLines[i])
end
local outputFile = io.open(outputPath, 'w+')
assert(outputFile, 'could not open '..outputPath)
for i = 1, #outLines, 1 do
outputFile:write(outLines[i], '\n')
end
outputFile:close()