includes multiple files

This commit is contained in:
2025-10-10 11:06:34 +08:00
parent a0aa9e611b
commit 5a20323b59
4 changed files with 93 additions and 19 deletions

9
README.md Normal file
View File

@@ -0,0 +1,9 @@
# Piecewise Readable Filter
This is a pandoc filter manipulating [fenced_divs](https://pandoc.org/MANUAL.html#extension-fenced_divs) in pandoc markdown.
Inspired by [this joke](https://www.zhihu.com/question/586807834/answer/2973535981).
useful refs:
- https://pandoc.org/lua-filters.html

View File

@@ -1,18 +1,34 @@
function File2Block(filename)
local fh = io.open(filename, "r")
if not fh then
io.stderr:write("Cannot open file: " .. filename .. "\n")
return { pandoc.Plain { pandoc.Str("[Error: cannot read file " .. filename .. "]") } }
local function words(s)
local res = {}
for part in s:gmatch("[^,]+") do -- split by commas
local trimmed = part:match("^%s*(.-)%s*$") -- remove leading/trailing spaces
if trimmed ~= "" then
table.insert(res, trimmed)
end
end
return res
end
local function label2Block(labels)
local contents = ""
for _,l in ipairs(words(labels)) do
-- use file for now.
local fh = io.open(l, "r")
if not fh then
io.stderr:write("Cannot open file: " .. l .. "\n")
return { pandoc.Plain { pandoc.Str("[Error: cannot read file " .. l .. "]") } }
end
contents = contents .. fh:read("*a")
fh:close()
end
local contents = fh:read("*a")
fh:close()
return { pandoc.Plain { pandoc.Str(contents) } }
end
function Div(e)
local include = e.attributes["include"]
if include then
local blocks = File2Block(include)
local blocks = label2Block(include)
-- Replace the Div contents
return pandoc.Div(blocks, e.attr)
end

View File

@@ -1,10 +1,7 @@
Here's the pandoc README:
```haskell {include="filter.hs" style="background-color: red"}
Foo:: Div -> Div
```
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce porta mattis neque, quis molestie nunc faucibus vitae. Phasellus vel commodo dolor, at faucibus arcu. Curabitur sit amet magna a neque euismod feugiat non et diam. Aliquam sit amet libero enim. Integer dignissim ullamcorper felis, ac ultrices turpis congue vel. Nulla id tempus orci. Curabitur ac vulputate tellus. Integer fermentum tempor facilisis. Duis egestas luctus tristique. Maecenas vitae arcu sit amet justo feugiat imperdiet. Nunc luctus erat sed ligula convallis hendrerit.
:::{include="filter.hs"}
:::{include="filter.hs , filter.lua , ,"}
:::
@@ -18,4 +15,10 @@ test thm2
:::{class="Theorem" id="thm3"}
test thm3
:::
:::
::::: {#special .sidebar}
Here is a paragraph.
And another.
:::::

View File

@@ -1,8 +1,12 @@
<p>Heres the pandoc README:</p>
<div class="sourceCode" id="cb1" data-include="filter.hs"
style="background-color: red"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="dt">Foo</span><span class="ot">::</span> <span class="dt">Div</span> <span class="ot">-&gt;</span> <span class="dt">Div</span></span></code></pre></div>
<div data-include="filter.hs">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce porta
mattis neque, quis molestie nunc faucibus vitae. Phasellus vel commodo
dolor, at faucibus arcu. Curabitur sit amet magna a neque euismod
feugiat non et diam. Aliquam sit amet libero enim. Integer dignissim
ullamcorper felis, ac ultrices turpis congue vel. Nulla id tempus orci.
Curabitur ac vulputate tellus. Integer fermentum tempor facilisis. Duis
egestas luctus tristique. Maecenas vitae arcu sit amet justo feugiat
imperdiet. Nunc luctus erat sed ligula convallis hendrerit.</p>
<div data-include="filter.hs , filter.lua , ,">
#!/usr/bin/env runhaskell
-- filter.hs
import Text.Pandoc.JSON
@@ -24,6 +28,44 @@ doInclude x = return x
main :: IO ()
main = toJSONFilter doInclude
local function words(s)
local res = {}
for part in s:gmatch("[^,]+") do -- split by commas
local trimmed = part:match("^%s*(.-)%s*$") -- remove
leading/trailing spaces
if trimmed ~= "" then
table.insert(res, trimmed)
end
end
return res
end
local function label2Block(labels)
local contents = ""
for _,l in ipairs(words(labels)) do
-- use file for now.
local fh = io.open(l, "r")
if not fh then
io.stderr:write("Cannot open file: " .. l .. "\n")
return { pandoc.Plain { pandoc.Str("[Error: cannot read file
" .. l .. "]") } }
end
contents = contents .. fh:read("*a")
fh:close()
end
return { pandoc.Plain { pandoc.Str(contents) } }
end
function Div(e)
local include = e.attributes["include"]
if include then
local blocks = label2Block(include)
-- Replace the Div contents
return pandoc.Div(blocks, e.attr)
end
return nil -- no change
end
</div>
<div class="Theorem">
<p>test thm1</p>
@@ -34,3 +76,7 @@ main = toJSONFilter doInclude
<div id="thm3" class="Theorem">
<p>test thm3</p>
</div>
<div id="special" class="sidebar">
<p>Here is a paragraph.</p>
<p>And another.</p>
</div>