Signed-off-by: Daniel <845765@qq.com>
This commit is contained in:
Daniel 2026-01-19 19:29:58 +08:00
parent a85655eae0
commit f6dd1a7d7e
No known key found for this signature in database
GPG key ID: 86211BA83DF03017
11 changed files with 58 additions and 18 deletions

View file

@ -65,5 +65,5 @@ extraResources:
filter: "!**/{.DS_Store}"
- from: "pandoc/pandoc-darwin-arm64.zip"
to: "pandoc.zip"
- from: "pandoc/pandoc-template.docx"
to: "pandoc-template.docx"
- from: "pandoc/pandoc-resources"
to: "pandoc-resources"

View file

@ -65,5 +65,5 @@ extraResources:
filter: "!**/{.DS_Store}"
- from: "pandoc/pandoc-darwin-amd64.zip"
to: "pandoc.zip"
- from: "pandoc/pandoc-template.docx"
to: "pandoc-template.docx"
- from: "pandoc/pandoc-resources"
to: "pandoc-resources"

View file

@ -69,5 +69,5 @@ extraResources:
filter: "!**/{.DS_Store}"
- from: "pandoc/pandoc-linux-arm64.zip"
to: "pandoc.zip"
- from: "pandoc/pandoc-template.docx"
to: "pandoc-template.docx"
- from: "pandoc/pandoc-resources"
to: "pandoc-resources"

View file

@ -66,5 +66,5 @@ extraResources:
filter: "!**/{.DS_Store}"
- from: "pandoc/pandoc-linux-amd64.zip"
to: "pandoc.zip"
- from: "pandoc/pandoc-template.docx"
to: "pandoc-template.docx"
- from: "pandoc/pandoc-resources"
to: "pandoc-resources"

View file

@ -72,5 +72,5 @@ extraResources:
filter: "!**/{.DS_Store}"
- from: "pandoc/pandoc-windows-amd64.zip"
to: "pandoc.zip"
- from: "pandoc/pandoc-template.docx"
to: "pandoc-template.docx"
- from: "pandoc/pandoc-resources"
to: "pandoc-resources"

View file

@ -0,0 +1,25 @@
function Span(el)
local style = el.attributes.style
if not style then return nil end
-- 1. 提取 Hex 颜色 (支持 #FFF 和 #FFFFFF)
local hex = style:match("color%s*:%s*#(%x+)")
if not hex then return nil end
if #hex == 3 then
hex = hex:sub(1,1):rep(2) .. hex:sub(2,2):rep(2) .. hex:sub(3,3):rep(2)
end
-- 2. 提取文本内容并处理 XML 转义
-- 使用 stringify 快速获取 span 内部所有纯文本(丢弃内部嵌套样式以换取稳定性)
local txt = pandoc.utils.stringify(el.content)
txt = txt:gsub('&', '&amp;'):gsub('<', '&lt;'):gsub('>', '&gt;')
-- 3. 构造完整的 OpenXML 运行块 (Run)
-- 这种结构 Word 识别率 100%,且不会产生标签嵌套冲突
local run_xml = string.format(
'<w:r><w:rPr><w:color w:val="%s"/></w:rPr><w:t xml:space="preserve">%s</w:t></w:r>',
hex:upper(), txt
)
return pandoc.RawInline('openxml', run_xml)
end

View file

@ -8,7 +8,7 @@ require (
github.com/88250/epub v0.0.0-20230830085737-c19055cd1f48
github.com/88250/go-humanize v0.0.0-20240424102817-4f78fac47ea7
github.com/88250/gulu v1.2.3-0.20251208021445-f93f2666eaac
github.com/88250/lute v1.7.7-0.20260114095037-49a2cce7593f
github.com/88250/lute v1.7.7-0.20260119115611-b18a050e4eae
github.com/88250/vitess-sqlparser v0.0.0-20210205111146-56a2ded2aba1
github.com/ClarkThan/ahocorasick v0.0.0-20231011042242-30d1ef1347f4
github.com/ConradIrwin/font v0.2.1

View file

@ -14,8 +14,8 @@ github.com/88250/go-sqlite3 v1.14.13-0.20231214121541-e7f54c482950 h1:Pa5hMiBceT
github.com/88250/go-sqlite3 v1.14.13-0.20231214121541-e7f54c482950/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/88250/gulu v1.2.3-0.20251208021445-f93f2666eaac h1:EC80pY8zyR0gbL8ZLIBB4IPG/ia3ZHScrR/xt8zU8qU=
github.com/88250/gulu v1.2.3-0.20251208021445-f93f2666eaac/go.mod h1:IQ5dXW9CjVmx6B7OfK1Y4ZBKTPMe9q1AkVoLGGzRbS8=
github.com/88250/lute v1.7.7-0.20260114095037-49a2cce7593f h1:KDG/ZiZJ/NMAPH/at561BSJ2ET7MlQfBPhd9uoUXXYg=
github.com/88250/lute v1.7.7-0.20260114095037-49a2cce7593f/go.mod h1:WYyUw//5yVw9BJnoVjx7rI/3szsISxNZCYGOqTIrV0o=
github.com/88250/lute v1.7.7-0.20260119115611-b18a050e4eae h1:XVdbxiLwEJQbTzkRmCNOcfshEPA060MvXvEk5j/ZPcg=
github.com/88250/lute v1.7.7-0.20260119115611-b18a050e4eae/go.mod h1:WYyUw//5yVw9BJnoVjx7rI/3szsISxNZCYGOqTIrV0o=
github.com/88250/pdfcpu v0.3.14-0.20250424122812-f10e8d9d8d46 h1:Bq1JsDfVbHKUxNL/B2JXd8cC/1h6aFjrlXpGycnh0Hk=
github.com/88250/pdfcpu v0.3.14-0.20250424122812-f10e8d9d8d46/go.mod h1:fVfOloBzs2+W2VJCCbq60XIxc3yJHAZ0Gahv1oO0gyI=
github.com/88250/vitess-sqlparser v0.0.0-20210205111146-56a2ded2aba1 h1:48T899JQDwyyRu9yXHePYlPdHtpJfrJEUGBMH3SMBWY=

View file

@ -773,6 +773,7 @@ func ExportDocx(id, savePath string, removeAssets, merge bool) (fullPath string,
"-f", "html+tex_math_dollars",
"--resource-path", tmpDir,
"-o", tmpDocxPath,
"--lua-filter", util.PandocColorFilterPath,
}
params := util.RemoveInvalid(Conf.Export.PandocParams)
@ -946,6 +947,7 @@ func ExportMarkdownHTML(id, savePath string, docx, merge bool) (name, dom string
if docx {
processIFrame(tree)
fillThemeStyleVar(tree)
}
luteEngine := NewLute()

View file

@ -101,8 +101,9 @@ func Pandoc(from, to, o, content string) (err error) {
}
var (
PandocBinPath string // Pandoc 可执行文件路径
PandocTemplatePath string // Pandoc Docx 模板文件路径
PandocBinPath string // Pandoc 可执行文件路径
PandocTemplatePath string // Pandoc Docx 模板文件路径
PandocColorFilterPath string // Pandoc 颜色过滤器路径
)
func InitPandoc() {
@ -129,11 +130,11 @@ func InitPandoc() {
}
}
PandocTemplatePath = filepath.Join(pandocDir, "pandoc-template.docx")
PandocTemplatePath = filepath.Join(pandocDir, "pandoc-resources", "pandoc-template.docx")
if !gulu.File.IsExist(PandocTemplatePath) {
PandocTemplatePath = filepath.Join(WorkingDir, "pandoc-template.docx")
PandocTemplatePath = filepath.Join(WorkingDir, "pandoc-resources", "pandoc-template.docx")
if "dev" == Mode || !gulu.File.IsExist(PandocTemplatePath) {
PandocTemplatePath = filepath.Join(WorkingDir, "pandoc/pandoc-template.docx")
PandocTemplatePath = filepath.Join(WorkingDir, "pandoc", "pandoc-resources", "pandoc-template.docx")
}
}
if !gulu.File.IsExist(PandocTemplatePath) {
@ -141,6 +142,18 @@ func InitPandoc() {
logging.LogWarnf("pandoc template file [%s] not found", PandocTemplatePath)
}
PandocColorFilterPath = filepath.Join(pandocDir, "pandoc-resources", "pandoc_color_filter.lua")
if !gulu.File.IsExist(PandocColorFilterPath) {
PandocColorFilterPath = filepath.Join(WorkingDir, "pandoc-resources", "pandoc_color_filter.lua")
if "dev" == Mode || !gulu.File.IsExist(PandocColorFilterPath) {
PandocColorFilterPath = filepath.Join(WorkingDir, "pandoc", "pandoc-resources", "pandoc_color_filter.lua")
}
}
if !gulu.File.IsExist(PandocColorFilterPath) {
PandocColorFilterPath = ""
logging.LogWarnf("pandoc color filter file [%s] not found", PandocColorFilterPath)
}
defer eventbus.Publish(EvtConfPandocInitialized)
if gulu.OS.IsWindows() {