用 Lua 编写的 Pandoc 过滤器,将跨度插入现有字符串中

我正在编写一个 Lua 过滤器,用于向 markdown 文件的 HTML 输出添加术语表功能。目标是为文档中每个首字母缩写词或关键定义都添加鼠标悬浮文本。

我希望在列表中出现首字母缩写词时(被标点符号包围),但不是字母时(例如,钴这样的单词中不会突出显示 CO),能够包括首字母缩写词。

我的 MWE 无法达到此目的,因为 Pandoc AST 中的字符串包括相邻的标点符号(例如,Str "CO/DBP/SBP,"Str "CO,",Space,Str "SBP,")。

-- # MWE
-- 解析术语表文件(此处为了简明起见而概述)
local glossary = {CO = "心脏输出量", DBP = "舒张压", SBP = "收缩压"}

-- 用带有鼠标悬浮链接的跨度替换术语表术语
function Str(elem)
  for key, value in next, glossary do
    if elem.text == key then
      return pandoc.Span (key, {title = value, class = "glossary"})
    end
  end
end

我使用了 string.substring.find 进行一些尝试,但无法得到可行的结果,主要是因为我不确定如何同时返回新 Span 和 Str(减去它的新 Span)。任何帮助都将不胜感激!


我的测试 markdown 包含:

# 首字母缩略词:SBP、DBP 和 CO

间隔的首字母缩略词:CO  SBP  DBP。

逗号分隔列表中的项目:CO、SBP、DBP;带有反斜杠:CO/DBP/SBP;以及项目符号:

* CO
* SBP
* DBP

原文链接 https://stackoverflow.com/questions/69059026

点赞
stackoverflow用户1997085
stackoverflow用户1997085

你可以只返回一个具有多个元素的表格。我的想法是寻找第一个分隔符,然后用 Span 替换词汇表条目:

-- 解析词汇表文件(此处只摘要了一部分)
local glossary = { CO = "心输出量", DBP = "舒张压", SBP = "收缩压" }

local Set = function(list)
    local set = {}
    for i,v in ipairs(list) do
        set[v] = true
    end
    return set
end

local findSeparator = function(text)
    local separator = Set{",", "/", " "}
    for i = 1, #text do
        local s = string.sub(text,i,i)
        if separator[s] then
            return s
        end
    end
end

local separatedList = function(text)
    local found
    local t = {}
    local separator = findSeparator(text)
    if not separator then return end
    for abb in string.gmatch(text, "%P+") do
        if glossary[abb] then
            found = true
            t[#t+1] = pandoc.Span(abb, {title = abb, class = "glossary"})
            t[#t+1] = pandoc.Str(separator)
        end
    end
    if found then
        -- 如果列表中有多个元素,移除最后一个分隔符
        -- 否则分隔符是元素的一部分,需要保留
        if #t > 2 then t[#t] = nil end
        return t
    end
end

local glossarize = {
    Str = function(el)
        if glossary[el.text] then
            return pandoc.Span(el.text, {title = glossary[el.text], class = "glossary"})
        else
            return separatedList(el.text)
        end
    end
}

function Pandoc(doc)
    local div = pandoc.Div(doc.blocks)
    local blocks = pandoc.walk_block(div, glossarize).content
    return pandoc.Pandoc(blocks, doc.meta)
end
2021-09-21 12:26:29