Files
ExplainableAI/slides/_extensions/quarto-ext/include-code-files/include-code-files.lua

131 lines
3.6 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

--- 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 },
}