intial commit (forked from private repo)
This commit is contained in:
@ -0,0 +1,130 @@
|
||||
--- include-code-files.lua – filter to include code from source files
|
||||
---
|
||||
--- Copyright: © 2020 Bruno BEAUFILS
|
||||
--- License: MIT – see LICENSE file for details
|
||||
|
||||
--- Dedent a line
|
||||
local function dedent(line, n)
|
||||
return line:sub(1, n):gsub(" ", "") .. line:sub(n + 1)
|
||||
end
|
||||
|
||||
--- Find snippet start and end.
|
||||
--
|
||||
-- Use this to populate startline and endline.
|
||||
-- This should work like pandocs snippet functionality: https://github.com/owickstrom/pandoc-include-code/tree/master
|
||||
local function snippet(cb, fh)
|
||||
if not cb.attributes.snippet then
|
||||
return
|
||||
end
|
||||
|
||||
-- Cannot capture enum: http://lua-users.org/wiki/PatternsTutorial
|
||||
local comment
|
||||
local comment_stop = ""
|
||||
if
|
||||
string.match(cb.attributes.include, ".py$")
|
||||
or string.match(cb.attributes.include, ".jl$")
|
||||
or string.match(cb.attributes.include, ".r$")
|
||||
then
|
||||
comment = "#"
|
||||
elseif string.match(cb.attributes.include, ".o?js$") or string.match(cb.attributes.include, ".css$") then
|
||||
comment = "//"
|
||||
elseif string.match(cb.attributes.include, ".lua$") then
|
||||
comment = "--"
|
||||
elseif string.match(cb.attributes.include, ".html$") then
|
||||
comment = "<!%-%-"
|
||||
comment_stop = " *%-%->"
|
||||
else
|
||||
-- If not known assume that it is something one or two long and not alphanumeric.
|
||||
comment = "%W%W?"
|
||||
end
|
||||
|
||||
local p_start = string.format("^ *%s start snippet %s%s", comment, cb.attributes.snippet, comment_stop)
|
||||
local p_stop = string.format("^ *%s end snippet %s%s", comment, cb.attributes.snippet, comment_stop)
|
||||
local start, stop = nil, nil
|
||||
|
||||
-- Cannot use pairs.
|
||||
local line_no = 1
|
||||
for line in fh:lines() do
|
||||
if start == nil then
|
||||
if string.match(line, p_start) then
|
||||
start = line_no + 1
|
||||
end
|
||||
elseif stop == nil then
|
||||
if string.match(line, p_stop) then
|
||||
stop = line_no - 1
|
||||
end
|
||||
else
|
||||
break
|
||||
end
|
||||
line_no = line_no + 1
|
||||
end
|
||||
|
||||
-- Reset so nothing is broken later on.
|
||||
fh:seek("set")
|
||||
|
||||
-- If start and stop not found, just continue
|
||||
if start == nil or stop == nil then
|
||||
return nil
|
||||
end
|
||||
|
||||
cb.attributes.startLine = tostring(start)
|
||||
cb.attributes.endLine = tostring(stop)
|
||||
end
|
||||
|
||||
--- Filter function for code blocks
|
||||
local function transclude(cb)
|
||||
if cb.attributes.include then
|
||||
local content = ""
|
||||
local fh = io.open(cb.attributes.include)
|
||||
if not fh then
|
||||
io.stderr:write("Cannot open file " .. cb.attributes.include .. " | Skipping includes\n")
|
||||
else
|
||||
local number = 1
|
||||
local start = 1
|
||||
|
||||
-- change hyphenated attributes to PascalCase
|
||||
for i, pascal in pairs({ "startLine", "endLine" }) do
|
||||
local hyphen = pascal:gsub("%u", "-%0"):lower()
|
||||
if cb.attributes[hyphen] then
|
||||
cb.attributes[pascal] = cb.attributes[hyphen]
|
||||
cb.attributes[hyphen] = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Overwrite startLine and stopLine with the snippet if any.
|
||||
snippet(cb, fh)
|
||||
|
||||
if cb.attributes.startLine then
|
||||
cb.attributes.startFrom = cb.attributes.startLine
|
||||
start = tonumber(cb.attributes.startLine)
|
||||
end
|
||||
|
||||
for line in fh:lines("L") do
|
||||
if cb.attributes.dedent then
|
||||
line = dedent(line, cb.attributes.dedent)
|
||||
end
|
||||
if number >= start then
|
||||
if not cb.attributes.endLine or number <= tonumber(cb.attributes.endLine) then
|
||||
content = content .. line
|
||||
end
|
||||
end
|
||||
number = number + 1
|
||||
end
|
||||
|
||||
fh:close()
|
||||
end
|
||||
|
||||
-- remove key-value pair for used keys
|
||||
cb.attributes.include = nil
|
||||
cb.attributes.startLine = nil
|
||||
cb.attributes.endLine = nil
|
||||
cb.attributes.dedent = nil
|
||||
|
||||
-- return final code block
|
||||
return pandoc.CodeBlock(content, cb.attr)
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
{ CodeBlock = transclude },
|
||||
}
|
||||
Reference in New Issue
Block a user