use a bipartite graph
This commit is contained in:
88
filter.lua
88
filter.lua
@@ -1,11 +1,18 @@
|
||||
|
||||
local label_map = {} -- label has to be unique!
|
||||
|
||||
-- helper functions for debugging
|
||||
local function show(s)
|
||||
io.stderr:write("[Debug] " .. s .. "\n")
|
||||
end
|
||||
|
||||
------------------------------------------------
|
||||
local label_map = {} -- label has to be unique!
|
||||
local adj = {} -- graph
|
||||
local function add_edge(u, v)
|
||||
if not adj[u] then
|
||||
adj[u] = {}
|
||||
end
|
||||
table.insert(adj[u], v)
|
||||
end
|
||||
|
||||
local function collect_labels(blk)
|
||||
if blk.identifier and blk.identifier ~= "" then
|
||||
label_map[blk.identifier] = blk:clone()
|
||||
@@ -13,27 +20,6 @@ local function collect_labels(blk)
|
||||
return nil
|
||||
end
|
||||
|
||||
local function dfs(blk, stack) -- depth first search on a top level blk
|
||||
-- check for identifier and build label_map
|
||||
if blk.identifier and blk.identifier ~= "" then
|
||||
label_map[blk.identifier] = blk:clone()
|
||||
table.insert(stack, blk.identifier)
|
||||
end
|
||||
|
||||
-- recurse into child blocks
|
||||
-- type matters. see https://hackage-content.haskell.org/package/pandoc-types-1.23.1/docs/Text-Pandoc-Definition.html#t:Block
|
||||
-- fortunately, we only need to recurse on divs.
|
||||
if blk.t == 'Div' then
|
||||
for _, inner in ipairs(blk.content) do
|
||||
dfs(inner, stack)
|
||||
end
|
||||
end
|
||||
-- pop
|
||||
if blk.identifier and blk.identifier ~= "" then
|
||||
table.remove(stack) -- pop
|
||||
end
|
||||
end
|
||||
|
||||
local function words(s)
|
||||
local res = {}
|
||||
for part in s:gmatch("[^,]+") do -- split by commas
|
||||
@@ -45,6 +31,49 @@ local function words(s)
|
||||
return res
|
||||
end
|
||||
|
||||
local function dfs(blk, stack) -- depth first search on a top level blk
|
||||
-- check for identifier and build label_map
|
||||
-- look for 2 types of AST node: divs with include attr and divs with labels
|
||||
local labelled = false
|
||||
local include = false
|
||||
if blk.attributes and blk.attributes["include"] then -- this must be a leaf node
|
||||
include = true
|
||||
-- labels in include may appears later in the dfs than this include-node
|
||||
-- but we assume every label will be there and build the graph now
|
||||
-- This is a directed bipartite grpah.
|
||||
-- one side for labeled nodes and one side for include-nodes
|
||||
for _, l in ipairs(words(blk.attributes["include"])) do
|
||||
-- insert edges
|
||||
-- what's the identifier of this include-node?...
|
||||
-- well... you must write a label for each include-node...
|
||||
-- this can be done using another filter
|
||||
add_edge(blk.identifier, l)
|
||||
end
|
||||
-- insert more edges
|
||||
for _, l in ipairs(stack) do
|
||||
add_edge(l, blk.identifier)
|
||||
end
|
||||
elseif blk.identifier and blk.identifier ~= "" then
|
||||
-- collect labelled nodes & maintain the stack
|
||||
labelled = true
|
||||
label_map[blk.identifier] = blk:clone()
|
||||
table.insert(stack, blk.identifier)
|
||||
end
|
||||
|
||||
-- recurse into child blocks
|
||||
-- type matters. see https://hackage-content.haskell.org/package/pandoc-types-1.23.1/docs/Text-Pandoc-Definition.html#t:Block
|
||||
-- fortunately, we only need to recurse on divs.
|
||||
if not include and blk.t == 'Div' then
|
||||
for _, inner in ipairs(blk.content) do
|
||||
dfs(inner, stack)
|
||||
end
|
||||
end
|
||||
-- pop
|
||||
if labelled then
|
||||
table.remove(stack)
|
||||
end
|
||||
end
|
||||
|
||||
local function replace(e)
|
||||
local include = e.attributes["include"]
|
||||
if include then
|
||||
@@ -66,9 +95,16 @@ end
|
||||
return {
|
||||
-- traverse = 'topdown',
|
||||
Pandoc = function(doc)
|
||||
-- collect labels
|
||||
-- collect labels & build the graph
|
||||
for _, blk in ipairs(doc.blocks) do
|
||||
dfs(blk,{})
|
||||
dfs(blk, {})
|
||||
end
|
||||
|
||||
show("edges:")
|
||||
for u, vs in pairs(adj) do
|
||||
for _, v in ipairs(vs) do
|
||||
show(u .. "->" .. v)
|
||||
end
|
||||
end
|
||||
|
||||
-- replace
|
||||
|
||||
33
input.md
33
input.md
@@ -1,31 +1,42 @@
|
||||
|
||||
::: {#lorem}
|
||||
Lorem ipsum dolor sit amet
|
||||
:::
|
||||
::: {#structure}
|
||||
inc (need thm2 and a fake label)
|
||||
|
||||
:::{include="lorem, thm2 , fakelabel , ,inthm1 ," #inc}
|
||||
:::
|
||||
thm1 - inthm1
|
||||
|
||||
thm2 - inthm2 (need thm1)
|
||||
|
||||
::::::::::::::::
|
||||
|
||||
:::{include="thm2 , fakelabel" #inc}
|
||||
This line will be ignored
|
||||
:::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
|
||||
::: Theorem
|
||||
::: {.Theorem #thm1} ::::::::::::::::::::::
|
||||
test thm1
|
||||
|
||||
::: {.Definition #inthm1} :::
|
||||
something
|
||||
:::::::::::::::::::::::::::::
|
||||
|
||||
:::
|
||||
:::::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
:::{.Theorem #thm2}
|
||||
:::{.Theorem #thm2}:::::::::::::::::::::
|
||||
test thm2
|
||||
:::
|
||||
|
||||
::::{#inthm2 include="thm1"}
|
||||
i need theorem 1
|
||||
::::::::::::::::::::::::::::
|
||||
|
||||
::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
:::{class="Theorem" id="thm3"}
|
||||
test thm3
|
||||
:::
|
||||
::::::::::::::::::::::::::::::
|
||||
|
||||
::::: {#special .sidebar}
|
||||
Here is a paragraph.
|
||||
|
||||
And another.
|
||||
:::::
|
||||
:::::::::::::::::::::::::
|
||||
22
output.html
22
output.html
@@ -1,18 +1,17 @@
|
||||
<div id="lorem">
|
||||
<p>Lorem ipsum dolor sit amet</p>
|
||||
</div>
|
||||
<div id="inc" data-include="lorem, thm2 , fakelabel , ,inthm1 ,">
|
||||
<div id="lorem">
|
||||
<p>Lorem ipsum dolor sit amet</p>
|
||||
<div id="structure">
|
||||
<p>inc (need thm2 and a fake label)</p>
|
||||
<p>thm1 - inthm1</p>
|
||||
<p>thm2 - inthm2 (need thm1)</p>
|
||||
</div>
|
||||
<div id="inc" data-include="thm2 , fakelabel">
|
||||
<div id="thm2" class="Theorem">
|
||||
<p>test thm2</p>
|
||||
</div>
|
||||
<div id="inthm1" class="Definition">
|
||||
<p>something</p>
|
||||
<div id="inthm2" data-include="thm1">
|
||||
<p>i need theorem 1</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="Theorem">
|
||||
</div>
|
||||
<div id="thm1" class="Theorem">
|
||||
<p>test thm1</p>
|
||||
<div id="inthm1" class="Definition">
|
||||
<p>something</p>
|
||||
@@ -20,6 +19,9 @@
|
||||
</div>
|
||||
<div id="thm2" class="Theorem">
|
||||
<p>test thm2</p>
|
||||
<div id="inthm2" data-include="thm1">
|
||||
<p>i need theorem 1</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="thm3" class="Theorem">
|
||||
<p>test thm3</p>
|
||||
|
||||
Reference in New Issue
Block a user