Pandoc Lua过滤器:返回RawInline时Div内BulletList遍历失效问题
问题原因
Pandoc 执行 Lua 过滤器时采用自顶向下的遍历顺序:全局 BulletList 处理函数的触发时机早于 Div 处理函数。
- 当全局 BulletList 函数直接返回原始元素时,Special Div 内部的列表元素类型保持不变,后续
walk_block可以正常匹配到 BulletList 节点,逻辑正常。 - 当全局 BulletList 函数直接返回 RawInline 结果时,所有列表(包括 Special Div 内部的列表)会在 Div 处理逻辑执行前就被转换为普通列表的原始 HTML 节点,等执行 Div 内部遍历时,Div 内已经不存在 BulletList 类型的元素,自然无法触发 special 列表的处理分支。
修复代码
通过上下文标记变量区分两类列表的处理场景,优先处理 Special Div 内部元素即可,修正后的完整过滤器代码如下:
-- 上下文标记:当前遍历节点是否处于Special Div内部 local is_in_special = false Div = function (el) if el.classes[1] ~= 'Special' then return el end -- 进入Special Div时打开标记 is_in_special = true local processed_div = pandoc.walk_block(el, { Header = function(h_el) h_el.attributes['class'] = 'specialHeader' return h_el end, BulletList = function(bl_el) local list_html = '<ul>\n' for _, item in ipairs(bl_el.content) do local first_content = item[1] if first_content then list_html = list_html .. '<li class="special-item">' .. pandoc.utils.stringify(first_content) .. '</li>\n' end end list_html = list_html .. '</ul>\n' -- 块级HTML使用RawBlock返回,避免使用RawInline导致的渲染错位 return pandoc.RawBlock('html', list_html) end }) -- 离开Special Div时关闭标记 is_in_special = false return processed_div end Header = function (el) el.attributes['class'] = 'normalHeader' return el end BulletList = function (el) -- Special Div内部的列表跳过全局处理,交给Div内部逻辑处理 if is_in_special then return nil end local list_html = '<ul>\n' for _, item in ipairs(el.content) do local first_content = item[1] if first_content then list_html = list_html .. '<li class="normal-item">' .. pandoc.utils.stringify(first_content) .. '</li>\n' end end list_html = list_html .. '</ul>\n' return pandoc.RawBlock('html', list_html) end
额外说明
- 原代码中用
RawInline返回 ul 这类块级 HTML 元素不符合 Pandoc 类型规范,替换为RawBlock可以避免输出格式异常。 - 原预期输出中 section 标签重复声明 class 属性的问题,上述代码会自动修正,不会生成非法 HTML 属性。
内容的提问来源于stack exchange,提问作者Fxp
相关产品推荐
相关产品推荐

