浏览代码

:art: 桌面端内置 Pandoc 可执行文件 https://github.com/siyuan-note/siyuan/issues/5835

Liang Ding 2 年之前
父节点
当前提交
d134045a60

+ 2 - 0
app/electron-builder-darwin-arm64.yml

@@ -50,3 +50,5 @@ extraResources:
   - from: "appearance/themes/daylight"
   - from: "appearance/themes/daylight"
     to: "appearance/themes/daylight"
     to: "appearance/themes/daylight"
     filter: "!**/{.DS_Store,custom.css}"
     filter: "!**/{.DS_Store,custom.css}"
+  - from: "pandoc/pandoc-darwin-amd64.zip"
+    to: "pandoc.zip"

+ 2 - 0
app/electron-builder-darwin.yml

@@ -49,3 +49,5 @@ extraResources:
   - from: "appearance/themes/daylight"
   - from: "appearance/themes/daylight"
     to: "appearance/themes/daylight"
     to: "appearance/themes/daylight"
     filter: "!**/{.DS_Store,custom.css}"
     filter: "!**/{.DS_Store,custom.css}"
+  - from: "pandoc/pandoc-darwin-amd64.zip"
+    to: "pandoc.zip"

+ 2 - 0
app/electron-builder-linux.yml

@@ -48,3 +48,5 @@ extraResources:
   - from: "appearance/themes/daylight"
   - from: "appearance/themes/daylight"
     to: "appearance/themes/daylight"
     to: "appearance/themes/daylight"
     filter: "!**/{.DS_Store,custom.css}"
     filter: "!**/{.DS_Store,custom.css}"
+  - from: "pandoc/pandoc-linux-amd64.zip"
+    to: "pandoc.zip"

+ 2 - 0
app/electron-builder-win32.yml

@@ -62,3 +62,5 @@ extraResources:
   - from: "appearance/themes/daylight"
   - from: "appearance/themes/daylight"
     to: "appearance/themes/daylight"
     to: "appearance/themes/daylight"
     filter: "!**/{.DS_Store,custom.css}"
     filter: "!**/{.DS_Store,custom.css}"
+  - from: "pandoc/pandoc-windows-386.zip"
+    to: "pandoc.zip"

+ 2 - 0
app/electron-builder.yml

@@ -62,3 +62,5 @@ extraResources:
   - from: "appearance/themes/daylight"
   - from: "appearance/themes/daylight"
     to: "appearance/themes/daylight"
     to: "appearance/themes/daylight"
     filter: "!**/{.DS_Store,custom.css}"
     filter: "!**/{.DS_Store,custom.css}"
+  - from: "pandoc/pandoc-windows-amd64.zip"
+    to: "pandoc.zip"

二进制
app/pandoc/pandoc-darwin-amd64.zip


二进制
app/pandoc/pandoc-linux-amd64.zip


二进制
app/pandoc/pandoc-windows-386.zip


二进制
app/pandoc/pandoc-windows-amd64.zip


+ 2 - 4
kernel/api/setting.go

@@ -127,10 +127,8 @@ func setExport(c *gin.Context) {
 
 
 	if "" != export.PandocBin {
 	if "" != export.PandocBin {
 		if !util.IsValidPandocBin(export.PandocBin) {
 		if !util.IsValidPandocBin(export.PandocBin) {
-			ret.Code = -1
-			ret.Msg = fmt.Sprintf(model.Conf.Language(117), export.PandocBin)
-			ret.Data = map[string]interface{}{"closeTimeout": 5000}
-			return
+			util.PushErrMsg(fmt.Sprintf(model.Conf.Language(117), export.PandocBin), 5000)
+			export.PandocBin = util.PandocBinPath
 		}
 		}
 	}
 	}
 
 

+ 3 - 0
kernel/model/conf.go

@@ -187,6 +187,9 @@ func InitConf() {
 		// 废弃导出选项引用块转换为原始块和引述块 https://github.com/siyuan-note/siyuan/issues/3155
 		// 废弃导出选项引用块转换为原始块和引述块 https://github.com/siyuan-note/siyuan/issues/3155
 		Conf.Export.BlockRefMode = 4 // 改为脚注
 		Conf.Export.BlockRefMode = 4 // 改为脚注
 	}
 	}
+	if "" == Conf.Export.PandocBin {
+		Conf.Export.PandocBin = util.PandocBinPath
+	}
 	if 9 > Conf.Editor.FontSize || 72 < Conf.Editor.FontSize {
 	if 9 > Conf.Editor.FontSize || 72 < Conf.Editor.FontSize {
 		Conf.Editor.FontSize = 16
 		Conf.Editor.FontSize = 16
 	}
 	}

+ 0 - 15
kernel/util/path.go

@@ -20,7 +20,6 @@ import (
 	"bytes"
 	"bytes"
 	"net"
 	"net"
 	"os"
 	"os"
-	"os/exec"
 	"path"
 	"path"
 	"strings"
 	"strings"
 
 
@@ -135,17 +134,3 @@ func TimeFromID(id string) (ret string) {
 	ret = id[:14]
 	ret = id[:14]
 	return
 	return
 }
 }
-
-func IsValidPandocBin(binPath string) bool {
-	if "" == binPath {
-		return false
-	}
-
-	cmd := exec.Command(binPath, "--version")
-	CmdAttr(cmd)
-	data, err := cmd.CombinedOutput()
-	if nil == err && strings.HasPrefix(string(data), "pandoc") {
-		return true
-	}
-	return false
-}

+ 76 - 0
kernel/util/working.go

@@ -17,6 +17,7 @@
 package util
 package util
 
 
 import (
 import (
+	"bytes"
 	"flag"
 	"flag"
 	"log"
 	"log"
 	"math/rand"
 	"math/rand"
@@ -101,6 +102,7 @@ func Boot() {
 
 
 	initPathDir()
 	initPathDir()
 	checkPort()
 	checkPort()
+	go initPandoc()
 
 
 	bootBanner := figure.NewColorFigure("SiYuan", "isometric3", "green", true)
 	bootBanner := figure.NewColorFigure("SiYuan", "isometric3", "green", true)
 	logging.LogInfof("\n" + bootBanner.String())
 	logging.LogInfof("\n" + bootBanner.String())
@@ -161,6 +163,7 @@ var (
 	DBPath         string        // SQLite 数据库文件路径
 	DBPath         string        // SQLite 数据库文件路径
 	HistoryDBPath  string        // SQLite 历史数据库文件路径
 	HistoryDBPath  string        // SQLite 历史数据库文件路径
 	BlockTreePath  string        // 区块树文件路径
 	BlockTreePath  string        // 区块树文件路径
+	PandocBinPath  string        // Pandoc 可执行文件路径
 	AppearancePath string        // 配置目录下的外观目录 appearance/ 路径
 	AppearancePath string        // 配置目录下的外观目录 appearance/ 路径
 	ThemesPath     string        // 配置目录下的外观目录下的 themes/ 路径
 	ThemesPath     string        // 配置目录下的外观目录下的 themes/ 路径
 	IconsPath      string        // 配置目录下的外观目录下的 icons/ 路径
 	IconsPath      string        // 配置目录下的外观目录下的 icons/ 路径
@@ -454,3 +457,76 @@ func PidByPort(port string) (ret string) {
 	}
 	}
 	return
 	return
 }
 }
+
+func initPandoc() {
+	if ContainerStd != Container {
+		return
+	}
+
+	pandocDir := filepath.Join(TempDir, "pandoc")
+	if gulu.OS.IsWindows() {
+		PandocBinPath = filepath.Join(pandocDir, "bin", "pandoc.exe")
+	} else if gulu.OS.IsDarwin() || gulu.OS.IsLinux() {
+		PandocBinPath = filepath.Join(pandocDir, "bin", "pandoc")
+	}
+	pandocVer := getPandocVer(PandocBinPath)
+	if "" != pandocVer {
+		logging.LogInfof("pandoc [ver=%s, bin=%s]", pandocVer, PandocBinPath)
+		return
+	}
+
+	pandocZip := filepath.Join(WorkingDir, "pandoc.zip")
+	if "dev" == Mode {
+		if gulu.OS.IsWindows() {
+			pandocZip = filepath.Join(WorkingDir, "pandoc/pandoc-windows-amd64.zip")
+		} else if gulu.OS.IsDarwin() {
+			pandocZip = filepath.Join(WorkingDir, "pandoc/pandoc-darwin-amd64.zip")
+		} else if gulu.OS.IsLinux() {
+			pandocZip = filepath.Join(WorkingDir, "pandoc/pandoc-linux-amd64.zip")
+		}
+	}
+	if err := gulu.Zip.Unzip(pandocZip, pandocDir); nil != err {
+		logging.LogErrorf("unzip pandoc failed: %s", err)
+		return
+	}
+
+	if gulu.OS.IsDarwin() || gulu.OS.IsLinux() {
+		exec.Command("chmod", "+x", PandocBinPath).CombinedOutput()
+	}
+	pandocVer = getPandocVer(PandocBinPath)
+	logging.LogInfof("initialized pandoc [ver=%s, bin=%s]", pandocVer, PandocBinPath)
+}
+
+func getPandocVer(binPath string) (ret string) {
+	if "" == binPath {
+		return
+	}
+
+	cmd := exec.Command(binPath, "--version")
+	CmdAttr(cmd)
+	data, err := cmd.CombinedOutput()
+	if nil == err && strings.HasPrefix(string(data), "pandoc") {
+		parts := bytes.Split(data, []byte("\n"))
+		if 0 < len(parts) {
+			ret = strings.TrimPrefix(string(parts[0]), "pandoc")
+			ret = strings.ReplaceAll(ret, ".exe", "")
+			ret = strings.TrimSpace(ret)
+		}
+		return
+	}
+	return
+}
+
+func IsValidPandocBin(binPath string) bool {
+	if "" == binPath {
+		return false
+	}
+
+	cmd := exec.Command(binPath, "--version")
+	CmdAttr(cmd)
+	data, err := cmd.CombinedOutput()
+	if nil == err && strings.HasPrefix(string(data), "pandoc") {
+		return true
+	}
+	return false
+}