mirror of
https://github.com/siyuan-note/siyuan.git
synced 2026-01-27 10:46:09 +01:00
🎨 Improve export to Word .docx format https://github.com/siyuan-note/siyuan/issues/14970
Signed-off-by: Daniel <845765@qq.com>
This commit is contained in:
parent
a85655eae0
commit
f6dd1a7d7e
11 changed files with 58 additions and 18 deletions
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
25
app/pandoc/pandoc-resources/pandoc_color_filter.lua
Normal file
25
app/pandoc/pandoc-resources/pandoc_color_filter.lua
Normal 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('&', '&'):gsub('<', '<'):gsub('>', '>')
|
||||
|
||||
-- 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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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=
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue