From 5a20323b5905e7326bcc07d884120601bf7a059e Mon Sep 17 00:00:00 2001 From: Yu Cong Date: Fri, 10 Oct 2025 11:06:34 +0800 Subject: [PATCH] includes multiple files --- README.md | 9 +++++++++ filter.lua | 32 ++++++++++++++++++++++-------- input.md | 15 ++++++++------ output.html | 56 ++++++++++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 93 insertions(+), 19 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..2bc3658 --- /dev/null +++ b/README.md @@ -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 \ No newline at end of file diff --git a/filter.lua b/filter.lua index a8fb00f..67d911b 100644 --- a/filter.lua +++ b/filter.lua @@ -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 diff --git a/input.md b/input.md index b5f778b..db59039 100644 --- a/input.md +++ b/input.md @@ -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 -::: \ No newline at end of file +::: + +::::: {#special .sidebar} +Here is a paragraph. + +And another. +::::: \ No newline at end of file diff --git a/output.html b/output.html index a1d447e..2eab6ac 100644 --- a/output.html +++ b/output.html @@ -1,8 +1,12 @@ -

Here’s the pandoc README:

-
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.

+
#!/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 +

test thm1

@@ -34,3 +76,7 @@ main = toJSONFilter doInclude

test thm3

+