Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
Vanessa 2022-09-07 17:55:31 +08:00
commit f8842918be
20 changed files with 1081 additions and 53 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

View file

@ -127,10 +127,8 @@ func setExport(c *gin.Context) {
if "" != 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
}
}

View file

@ -180,6 +180,12 @@ func isOutdatedTheme(theme *Theme, bazaarThemes []*Theme) bool {
return false
}
repo := strings.TrimPrefix(theme.URL, "https://github.com/")
parts := strings.Split(repo, "/")
if 2 != len(parts) || "" == strings.TrimSpace(parts[1]) {
return false
}
for _, pkg := range bazaarThemes {
if theme.URL == pkg.URL && theme.Name == pkg.Name && theme.Author == pkg.Author && theme.Version != pkg.Version {
theme.RepoHash = pkg.RepoHash
@ -194,6 +200,12 @@ func isOutdatedIcon(icon *Icon, bazaarIcons []*Icon) bool {
return false
}
repo := strings.TrimPrefix(icon.URL, "https://github.com/")
parts := strings.Split(repo, "/")
if 2 != len(parts) || "" == strings.TrimSpace(parts[1]) {
return false
}
for _, pkg := range bazaarIcons {
if icon.URL == pkg.URL && icon.Name == pkg.Name && icon.Author == pkg.Author && icon.Version != pkg.Version {
icon.RepoHash = pkg.RepoHash
@ -208,6 +220,12 @@ func isOutdatedWidget(widget *Widget, bazaarWidgets []*Widget) bool {
return false
}
repo := strings.TrimPrefix(widget.URL, "https://github.com/")
parts := strings.Split(repo, "/")
if 2 != len(parts) || "" == strings.TrimSpace(parts[1]) {
return false
}
for _, pkg := range bazaarWidgets {
if widget.URL == pkg.URL && widget.Name == pkg.Name && widget.Author == pkg.Author && widget.Version != pkg.Version {
widget.RepoHash = pkg.RepoHash
@ -222,6 +240,12 @@ func isOutdatedTemplate(template *Template, bazaarTemplates []*Template) bool {
return false
}
repo := strings.TrimPrefix(template.URL, "https://github.com/")
parts := strings.Split(repo, "/")
if 2 != len(parts) || "" == strings.TrimSpace(parts[1]) {
return false
}
for _, pkg := range bazaarTemplates {
if template.URL == pkg.URL && template.Name == pkg.Name && template.Author == pkg.Author && template.Version != pkg.Version {
template.RepoHash = pkg.RepoHash

View file

@ -134,7 +134,9 @@ func InstalledThemes() (ret []*Theme) {
theme.Author = themeConf["author"].(string)
theme.URL = themeConf["url"].(string)
theme.Version = themeConf["version"].(string)
theme.Modes = make([]string, 0, len(themeConf["modes"].([]interface{})))
for _, mode := range themeConf["modes"].([]interface{}) {
theme.Modes = append(theme.Modes, mode.(string))
}
theme.RepoURL = theme.URL
theme.PreviewURL = "/appearance/themes/" + dirName + "/preview.png"
theme.PreviewURLThumb = "/appearance/themes/" + dirName + "/preview.png"

View file

@ -7,7 +7,7 @@ require (
github.com/88250/css v0.1.2
github.com/88250/flock v0.8.2
github.com/88250/gulu v1.2.3-0.20220720144315-065ef35ec583
github.com/88250/lute v1.7.5-0.20220904100410-4749a9b16b91
github.com/88250/lute v1.7.5-0.20220906152822-041dfab2593d
github.com/88250/melody v0.0.0-20201115062536-c0b3394adcd1
github.com/88250/pdfcpu v0.3.13
github.com/88250/vitess-sqlparser v0.0.0-20210205111146-56a2ded2aba1

View file

@ -21,6 +21,8 @@ github.com/88250/gulu v1.2.3-0.20220720144315-065ef35ec583 h1:FhA/zJemLrbOYJpdMI
github.com/88250/gulu v1.2.3-0.20220720144315-065ef35ec583/go.mod h1:I1qBzsksFL2ciGSuqDE7R3XW4BUMrfDgOvSXEk7FsAI=
github.com/88250/lute v1.7.5-0.20220904100410-4749a9b16b91 h1:KYIq0WfoNHuvDNZDNv5NxSySgAjzfVQkwlkJSZ9pRfY=
github.com/88250/lute v1.7.5-0.20220904100410-4749a9b16b91/go.mod h1:cEoBGi0zArPqAsp0MdG9SKinvH/xxZZWXU7sRx8vHSA=
github.com/88250/lute v1.7.5-0.20220906152822-041dfab2593d h1:NU9mdTDjbu25MKUu3a66ea6LKE4qsrOX6rto0CU6pWU=
github.com/88250/lute v1.7.5-0.20220906152822-041dfab2593d/go.mod h1:cEoBGi0zArPqAsp0MdG9SKinvH/xxZZWXU7sRx8vHSA=
github.com/88250/melody v0.0.0-20201115062536-c0b3394adcd1 h1:9Cb+iN639vUI2OcIBc+4oGwml9/0J6bL6dWNb8Al+1s=
github.com/88250/melody v0.0.0-20201115062536-c0b3394adcd1/go.mod h1:jH6MMPr8G7AMzaVmWHXZQiB1DKO3giWbcWZ7UoJ1teI=
github.com/88250/pdfcpu v0.3.13 h1:touMWMZkCGalMIbEg9bxYp7rETM+zwb9hXjwhqi4I7Q=

View file

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

View file

@ -985,7 +985,7 @@ func processKaTexMacros(n *ast.Node) {
return
}
mathContent := n.Tokens
mathContent := string(n.Tokens)
macros := map[string]string{}
if err := gulu.JSON.UnmarshalJSON([]byte(Conf.Editor.KaTexMacros), &macros); nil != err {
logging.LogWarnf("parse katex macros failed: %s", err)
@ -993,13 +993,12 @@ func processKaTexMacros(n *ast.Node) {
}
var keys []string
for k, _ := range macros {
for k := range macros {
keys = append(keys, k)
}
useMacro := false
for k, _ := range macros {
if bytes.Contains(mathContent, []byte(k)) {
for k := range macros {
if strings.Contains(mathContent, k) {
useMacro = true
break
}
@ -1007,36 +1006,17 @@ func processKaTexMacros(n *ast.Node) {
if !useMacro {
return
}
sort.Slice(keys, func(i, j int) bool { return len(keys[i]) > len(keys[j]) })
usedMacros := extractUsedMacros(mathContent, macros)
newcommandBuf := bytes.Buffer{}
mathContent = escapeKaTexSupportedFunctions(mathContent)
usedMacros := extractUsedMacros(mathContent, &keys)
for _, usedMacro := range usedMacros {
expanded := resolveKaTexMacro(usedMacro, &macros, &keys)
newcommandBuf.WriteString("\\newcommand" + usedMacro + "{" + expanded + "}\n")
expanded = unescapeKaTexSupportedFunctions(expanded)
mathContent = strings.ReplaceAll(mathContent, usedMacro, expanded)
}
newcommandBuf.WriteString("\n")
mathContent = append(newcommandBuf.Bytes(), mathContent...)
n.Tokens = mathContent
}
func extractUsedMacros(mathContent []byte, macros map[string]string) (ret []string) {
for macro, _ := range macros {
if bytes.Contains(mathContent, []byte(macro)) {
ret = append(ret, macro)
}
}
return
}
func resolveKaTexMacro(macroName string, macros *map[string]string, keys *[]string) string {
v := (*macros)[macroName]
for _, k := range *keys {
if strings.Contains(v, k) {
v = strings.ReplaceAll(v, k, resolveKaTexMacro(k, macros, keys))
(*macros)[macroName] = v
}
}
return v
mathContent = unescapeKaTexSupportedFunctions(mathContent)
n.Tokens = []byte(mathContent)
}
func renderExportMdParagraph(r *render.FormatRenderer, node *ast.Node, entering bool) ast.WalkStatus {

View file

@ -0,0 +1,948 @@
// SiYuan - Build Your Eternal Digital Garden
// Copyright (c) 2020-present, b3log.org
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package model
import (
"sort"
"strings"
)
func extractUsedMacros(mathContent string, macrosKeys *[]string) (ret []string) {
Next:
for {
for _, k := range *macrosKeys {
if idx := strings.Index(mathContent, k); -1 < idx {
mathContent = strings.Replace(mathContent, k, "__@"+k[1:]+"@__", 1)
ret = append(ret, k)
goto Next
}
}
break
}
return
}
var katexSupportedFunctions = []string{ // https://katex.org/docs/supported.html
"\\!",
"\\\"",
"\\#",
"\\$",
"\\%",
"\\&",
"\\'",
"\\,",
"\\.",
"\\:",
"\\;",
"\\=",
"\\>",
"\\Alpha",
"\\And",
"\\Bbb",
"\\Bbbk",
"\\Beta",
"\\Big",
"\\Bigg",
"\\Biggl",
"\\Biggm",
"\\Biggr",
"\\Bigl",
"\\Bigm",
"\\Bigr",
"\\Box",
"\\Bra",
"\\Braket",
"\\Bumpeq",
"\\Cap",
"\\Chi",
"\\Colonapprox",
"\\Coloneq",
"\\Coloneqq",
"\\Colonsim",
"\\Complex",
"\\Cup",
"\\Dagger",
"\\Darr",
"\\Delta",
"\\Diamond",
"\\Doteq",
"\\Downarrow",
"\\Epsilon",
"\\Eqcolon",
"\\Eqqcolon",
"\\Eta",
"\\Finv",
"\\Game",
"\\Gamma",
"\\H",
"\\Harr",
"\\Huge AB",
"\\Im",
"\\Iota",
"\\Join",
"\\KaTeX",
"\\Kappa",
"\\Ket",
"\\LARGE AB",
"\\LaTeX",
"\\Lambda",
"\\Large AB",
"\\Larr",
"\\Leftarrow",
"\\Leftrightarrow",
"\\Lleftarrow",
"\\Longleftarrow",
"\\Longleftrightarrow",
"\\Longrightarrow",
"\\Lrarr",
"\\Lsh",
"\\Mu",
"\\N",
"\\Nu",
"\\Omega",
"\\Omicron",
"\\Overrightarrow",
"\\P",
"\\Phi",
"\\Pi",
"\\Pr",
"\\Psi",
"\\R",
"\\Rarr",
"\\Re",
"\\Reals",
"\\Rho",
"\\Rightarrow",
"\\Rrightarrow",
"\\Rsh",
"\\S",
"\\Set",
"\\Sigma",
"\\Subset",
"\\Supset",
"\\Tau",
"\\TeX",
"\\Theta",
"\\Uarr",
"\\Uparrow",
"\\Updownarrow",
"\\Upsilon",
"\\Vdash",
"\\Vert",
"\\Vvdash",
"\\Xi",
"\\Z",
"\\Zeta",
"\\^",
"\\_",
"\\`",
"\\acute",
"\\alef",
"\\alefsym",
"\\aleph",
"\\alpha",
"\\amalg",
"\\angle",
"\\approx",
"\\approxcolon",
"\\approxcoloncolon",
"\\approxeq",
"\\arccos",
"\\arcctg",
"\\arcsin",
"\\arctan",
"\\arctg",
"\\arg",
"\\argmax",
"\\argmin",
"\\ast",
"\\asymp",
"\\backepsilon",
"\\backprime",
"\\backsim",
"\\backsimeq",
"\\backslash",
"\\bar",
"\\barwedge",
"\\bcancel",
"\\because",
"\\begin",
"\\beta",
"\\beth",
"\\between",
"\\bf Ab0",
"\\big",
"\\bigcap",
"\\bigcirc",
"\\bigcup",
"\\bigg",
"\\biggl",
"\\biggm",
"\\biggr",
"\\bigl",
"\\bigm",
"\\bigodot",
"\\bigoplus",
"\\bigotimes",
"\\bigr",
"\\bigsqcup",
"\\bigstar",
"\\bigtriangledown",
"\\bigtriangleup",
"\\biguplus",
"\\bigvee",
"\\bigwedge",
"\\binom",
"\\blacklozenge",
"\\blacksquare",
"\\blacktriangle",
"\\blacktriangledown",
"\\blacktriangleleft",
"\\blacktriangleright",
"\\bm",
"\\bmod",
"\\bold",
"\\boldsymbol",
"\\bot",
"\\bowtie",
"\\boxdot",
"\\boxed",
"\\boxminus",
"\\boxplus",
"\\boxtimes",
"\\bra",
"\\braket",
"\\breve",
"\\bullet",
"\\bumpeq",
"\\cal AB0",
"\\cancel",
"\\cap",
"\\cdot",
"\\cdotp",
"\\cdots",
"\\centerdot",
"\\cfrac",
"\\ch",
"\\check",
"\\checkmark",
"\\chi",
"\\circ",
"\\circeq",
"\\circlearrowleft",
"\\circlearrowright",
"\\circledR",
"\\circledS",
"\\circledast",
"\\circledcirc",
"\\circleddash",
"\\clubs",
"\\clubsuit",
"\\cnums",
"\\colon",
"\\colonapprox",
"\\coloncolon",
"\\coloncolonapprox",
"\\coloncolonequals",
"\\coloncolonminus",
"\\coloncolonsim",
"\\coloneq",
"\\coloneqq",
"\\colonequals",
"\\colonminus",
"\\colonsim",
"\\complement",
"\\cong",
"\\coprod",
"\\copyright",
"\\cos",
"\\cosec",
"\\cosh",
"\\cot",
"\\cotg",
"\\coth",
"\\csc",
"\\ctg",
"\\cth",
"\\cup",
"\\curlyeqprec",
"\\curlyeqsucc",
"\\curlyvee",
"\\curlywedge",
"\\curvearrowleft",
"\\curvearrowright",
"\\dArr",
"\\dag",
"\\dagger",
"\\daleth",
"\\darr",
"\\dashleftarrow",
"\\dashrightarrow",
"\\dashv",
"\\dbinom",
"\\dblcolon",
"\\ddag",
"\\ddagger",
"\\ddot",
"\\ddots",
"\\def\\arraystretch",
"\\def\\foo",
"\\deg",
"\\degree",
"\\delta",
"\\det",
"\\dfrac",
"\\diagdown",
"\\diagup",
"\\diamond",
"\\diamonds",
"\\diamondsuit",
"\\digamma",
"\\dim",
"\\displaystyle\\sum_",
"\\div",
"\\divideontimes",
"\\dot",
"\\doteq",
"\\doteqdot",
"\\dotplus",
"\\dots",
"\\dotsb",
"\\dotsc",
"\\dotsi",
"\\dotsm",
"\\dotso",
"\\doublebarwedge",
"\\doublecap",
"\\doublecup",
"\\downarrow",
"\\downdownarrows",
"\\downharpoonleft",
"\\downharpoonright",
"\\edef\\macroname#1#2…",
"\\ell",
"\\empty",
"\\emptyset",
"\\end",
"\\enspace",
"\\epsilon",
"\\eqcirc",
"\\eqcolon",
"\\eqqcolon",
"\\eqsim",
"\\eqslantgtr",
"\\eqslantless",
"\\equalscolon",
"\\equalscoloncolon",
"\\equiv",
"\\eta",
"\\eth",
"\\exist",
"\\exists",
"\\exp",
"\\fallingdotseq",
"\\flat",
"\\footnotesize AB",
"\\forall",
"\\frac",
"\\frak",
"\\frown",
"\\futurelet\\foo\\bar x",
"\\gamma",
"\\gcd",
"\\gdef\\bar#1",
"\\ge",
"\\genfrac ( ] ",
"\\geq",
"\\geqq",
"\\geqslant",
"\\gets",
"\\gg",
"\\ggg",
"\\gggtr",
"\\gimel",
"\\global\\def\\macroname#1#2…",
"\\gnapprox",
"\\gneq",
"\\gneqq",
"\\gnsim",
"\\grave",
"\\gt",
"\\gtrapprox",
"\\gtrdot",
"\\gtreqless",
"\\gtreqqless",
"\\gtrless",
"\\gtrsim",
"\\gvertneqq",
"\\hArr",
"\\harr",
"\\hat",
"\\hbar",
"\\hdashline",
"\\hearts",
"\\heartsuit",
"\\hom",
"\\hookleftarrow",
"\\hookrightarrow",
"\\hphantom",
"\\href",
"\\hskip",
"\\hslash",
"\\hspace",
"\\hspace*",
"\\htmlClass",
"\\htmlData",
"\\htmlId",
"\\htmlStyle",
"\\huge AB",
"\\iff",
"\\iiint",
"\\iint",
"\\image",
"\\imageof",
"\\imath",
"\\impliedby",
"\\implies",
"\\in",
"\\includegraphics[height=0.8em, totalheight=0.9em, width=0.9em, alt=KA logo]",
"\\inf",
"\\infin",
"\\infty",
"\\injlim",
"\\int",
"\\intercal",
"\\intop",
"\\iota",
"\\isin",
"\\it Ab0",
"\\jmath",
"\\kappa",
"\\ker",
"\\kern",
"\\ket",
"\\lArr",
"\\lBrace \\rBrace",
"\\lVert",
"\\lambda",
"\\land",
"\\lang",
"\\langle",
"\\large AB",
"\\larr",
"\\lbrace",
"\\lbrack",
"\\lceil",
"\\ldotp",
"\\ldots",
"\\le",
"\\leadsto",
"\\left",
"\\left(x^",
"\\left.",
"\\leftarrow",
"\\leftarrowtail",
"\\leftharpoondown",
"\\leftharpoonup",
"\\leftleftarrows",
"\\leftrightarrow",
"\\leftrightarrows",
"\\leftrightharpoons",
"\\leftrightsquigarrow",
"\\leftthreetimes",
"\\leq",
"\\leqq",
"\\leqslant",
"\\lessapprox",
"\\lessdot",
"\\lesseqgtr",
"\\lesseqqgtr",
"\\lessgtr",
"\\lesssim",
"\\let\\foo=\\bar",
"\\lfloor",
"\\lg",
"\\lgroup",
"\\lhd",
"\\lim",
"\\lim\\limits_x",
"\\lim\\nolimits_x",
"\\liminf",
"\\limsup",
"\\ll",
"\\llbracket",
"\\llcorner",
"\\lll",
"\\llless",
"\\lmoustache",
"\\ln",
"\\lnapprox",
"\\lneq",
"\\lneqq",
"\\lnot",
"\\lnsim",
"\\log",
"\\longleftarrow",
"\\longleftrightarrow",
"\\longmapsto",
"\\longrightarrow",
"\\looparrowleft",
"\\looparrowright",
"\\lor",
"\\lozenge",
"\\lparen",
"\\lq",
"\\lrArr",
"\\lrarr",
"\\lrcorner",
"\\lt",
"\\lt \\gt",
"\\ltimes",
"\\lvert",
"\\lvertneqq",
"\\maltese",
"\\mapsto",
"\\mathbb",
"\\mathbf",
"\\mathcal",
"\\mathellipsis",
"\\mathfrak",
"\\mathit",
"\\mathnormal",
"\\mathring",
"\\mathrlap",
"\\mathrm",
"\\mathscr",
"\\mathsf",
"\\mathsterling",
"\\mathstrut",
"\\mathtt",
"\\max",
"\\measuredangle",
"\\medspace",
"\\mho",
"\\mid",
"\\middle",
"\\min",
"\\minuscolon",
"\\minuscoloncolon",
"\\minuso",
"\\mkern",
"\\models",
"\\mp",
"\\mskip",
"\\mu",
"\\multimap",
"\\nLeftarrow",
"\\nLeftrightarrow",
"\\nRightarrow",
"\\nVDash",
"\\nVdash",
"\\nabla",
"\\natnums",
"\\natural",
"\\ncong",
"\\ne",
"\\nearrow",
"\\neg",
"\\negmedspace",
"\\negthickspace",
"\\negthinspace",
"\\neq",
"\\newcommand\\macroname[numargs]",
"\\nexists",
"\\ngeq",
"\\ngeqq",
"\\ngeqslant",
"\\ngtr",
"\\ni",
"\\nleftarrow",
"\\nleftrightarrow",
"\\nleq",
"\\nleqq",
"\\nleqslant",
"\\nless",
"\\nmid",
"\\nobreakspace",
"\\nonumber",
"\\normalsize AB",
"\\not =",
"\\notag",
"\\notin",
"\\notni",
"\\nparallel",
"\\nprec",
"\\npreceq",
"\\nrightarrow",
"\\nshortmid",
"\\nshortparallel",
"\\nsim",
"\\nsubseteq",
"\\nsubseteqq",
"\\nsucc",
"\\nsucceq",
"\\nsupseteq",
"\\nsupseteqq",
"\\ntriangleleft",
"\\ntrianglelefteq",
"\\ntriangleright",
"\\ntrianglerighteq",
"\\nu",
"\\nvDash",
"\\nvdash",
"\\nwarrow",
"\\odot",
"\\oiiint",
"\\oiint",
"\\oint",
"\\omega",
"\\omicron",
"\\ominus",
"\\operatorname",
"\\operatorname*",
"\\operatornamewithlimits",
"\\oplus",
"\\origof",
"\\oslash",
"\\otimes",
"\\overbrace",
"\\overgroup",
"\\overleftarrow",
"\\overleftharpoon",
"\\overleftrightarrow",
"\\overline",
"\\overlinesegment",
"\\overrightarrow",
"\\overrightharpoon",
"\\overset",
"\\owns",
"\\parallel",
"\\partial",
"\\perp",
"\\phantom",
"\\phase",
"\\phi",
"\\pi",
"\\pitchfork",
"\\plim",
"\\plusmn",
"\\pm",
"\\pounds",
"\\prec",
"\\precapprox",
"\\preccurlyeq",
"\\preceq",
"\\precnapprox",
"\\precneqq",
"\\precnsim",
"\\precsim",
"\\prime",
"\\prod",
"\\projlim",
"\\propto",
"\\providecommand\\macroname[numargs]",
"\\psi",
"\\qquad",
"\\quad",
"\\r",
"\\rArr",
"\\rVert",
"\\rang",
"\\rangle",
"\\rarr",
"\\ratio",
"\\rbrace",
"\\rbrack",
"\\rceil",
"\\real",
"\\reals",
"\\renewcommand\\macroname[numargs]",
"\\restriction",
"\\rfloor",
"\\rgroup",
"\\rhd",
"\\rho",
"\\right",
"\\right.",
"\\rightarrow",
"\\rightarrowtail",
"\\rightharpoondown",
"\\rightharpoonup",
"\\rightleftarrows",
"\\rightleftharpoons",
"\\rightrightarrows",
"\\rightsquigarrow",
"\\rightthreetimes",
"\\risingdotseq",
"\\rm Ab0",
"\\rmoustache",
"\\rparen",
"\\rq",
"\\rrbracket",
"\\rtimes",
"\\rvert",
"\\scriptscriptstyle x",
"\\scriptsize AB",
"\\scriptstyle x",
"\\sdot",
"\\searrow",
"\\sec",
"\\set",
"\\setminus",
"\\sf Ab0",
"\\sh",
"\\sharp",
"\\shortmid",
"\\shortparallel",
"\\sigma",
"\\sim",
"\\simcolon",
"\\simcoloncolon",
"\\simeq",
"\\sin",
"\\sinh",
"\\small AB",
"\\smallfrown",
"\\smallint",
"\\smallsetminus",
"\\smallsmile",
"\\smile",
"\\sout",
"\\space",
"\\spades",
"\\spadesuit",
"\\sphericalangle",
"\\sqcap",
"\\sqcup",
"\\sqrt",
"\\sqsubset",
"\\sqsubseteq",
"\\sqsupset",
"\\sqsupseteq",
"\\square",
"\\stackrel",
"\\star",
"\\sub",
"\\sube",
"\\subset",
"\\subseteq",
"\\subseteqq",
"\\subsetneq",
"\\subsetneqq",
"\\succ",
"\\succapprox",
"\\succcurlyeq",
"\\succeq",
"\\succnapprox",
"\\succneqq",
"\\succnsim",
"\\succsim",
"\\sum",
"\\sum_",
"\\sup",
"\\supe",
"\\supset",
"\\supseteq",
"\\supseteqq",
"\\supsetneq",
"\\supsetneqq",
"\\surd",
"\\swarrow",
"\\tan",
"\\tanh",
"\\tau",
"\\tbinom",
"\\text",
"\\textbf",
"\\textit",
"\\textmd",
"\\textnormal",
"\\textrm",
"\\textsf",
"\\textstyle\\sum_",
"\\texttt",
"\\textup",
"\\tfrac",
"\\tg",
"\\th",
"\\therefore",
"\\theta",
"\\thetasym",
"\\thickapprox",
"\\thicksim",
"\\thickspace",
"\\thinspace",
"\\tilde",
"\\times",
"\\tiny AB",
"\\to",
"\\top",
"\\triangle",
"\\triangledown",
"\\triangleleft",
"\\trianglelefteq",
"\\triangleq",
"\\triangleright",
"\\trianglerighteq",
"\\tt Ab0",
"\\twoheadleftarrow",
"\\twoheadrightarrow",
"\\u",
"\\uArr",
"\\uarr",
"\\ulcorner",
"\\underbar",
"\\underbrace",
"\\undergroup",
"\\underleftarrow",
"\\underleftrightarrow",
"\\underline",
"\\underlinesegment",
"\\underrightarrow",
"\\underset",
"\\unlhd",
"\\unrhd",
"\\uparrow",
"\\updownarrow",
"\\upharpoonleft",
"\\upharpoonright",
"\\uplus",
"\\upsilon",
"\\upuparrows",
"\\urcorner",
"\\url",
"\\utilde",
"\\v",
"\\vDash",
"\\varDelta",
"\\varGamma",
"\\varLambda",
"\\varOmega",
"\\varPhi",
"\\varPi",
"\\varPsi",
"\\varSigma",
"\\varTheta",
"\\varUpsilon",
"\\varXi",
"\\varepsilon",
"\\varinjlim",
"\\varkappa",
"\\varliminf",
"\\varlimsup",
"\\varnothing",
"\\varphi",
"\\varpi",
"\\varprojlim",
"\\varpropto",
"\\varrho",
"\\varsigma",
"\\varsubsetneq",
"\\varsubsetneqq",
"\\varsupsetneq",
"\\varsupsetneqq",
"\\vartheta",
"\\vartriangle",
"\\vartriangleleft",
"\\vartriangleright",
"\\vcentcolon",
"\\vdash",
"\\vdots",
"\\vec",
"\\vee",
"\\veebar",
"\\verb!x^2!",
"\\vert",
"\\vphantom",
"\\wedge",
"\\weierp",
"\\widecheck",
"\\widehat",
"\\widetilde",
"\\wp",
"\\wr",
"\\xLeftarrow",
"\\xLeftrightarrow",
"\\xRightarrow",
"\\xcancel",
"\\xdef\\macroname#1#2…",
"\\xhookleftarrow",
"\\xhookrightarrow",
"\\xi",
"\\xleftarrow",
"\\xleftharpoondown",
"\\xleftharpoonup",
"\\xleftrightarrow",
"\\xleftrightharpoons",
"\\xlongequal",
"\\xmapsto",
"\\xrightarrow[under]",
"\\xrightharpoondown",
"\\xrightharpoonup",
"\\xrightleftharpoons",
"\\xtofrom",
"\\xtwoheadleftarrow",
"\\xtwoheadrightarrow",
"\\yen",
"\\zeta",
"\\|",
"\\~",
}
func init() {
sort.Slice(katexSupportedFunctions, func(i, j int) bool { return len(katexSupportedFunctions[i]) > len(katexSupportedFunctions[j]) })
}
func resolveKaTexMacro(macroName string, macros *map[string]string, keys *[]string) string {
v := (*macros)[macroName]
sort.Slice(*keys, func(i, j int) bool { return len((*keys)[i]) > len((*keys)[j]) })
for _, k := range *keys {
escaped := escapeKaTexSupportedFunctions(v)
if strings.Contains(escaped, k) {
escaped = strings.ReplaceAll(escaped, k, resolveKaTexMacro(k, macros, keys))
v = unescapeKaTexSupportedFunctions(escaped)
(*macros)[macroName] = v
}
}
return v
}
func escapeKaTexSupportedFunctions(macroVal string) string {
Next:
for {
for _, f := range katexSupportedFunctions {
if idx := strings.Index(macroVal, f); -1 < idx {
macroVal = strings.Replace(macroVal, f, "__@"+f[1:]+"@__", 1)
goto Next
}
}
break
}
return macroVal
}
func unescapeKaTexSupportedFunctions(macroVal string) string {
if !strings.Contains(macroVal, "__@") {
return macroVal
}
for _, f := range katexSupportedFunctions {
macroVal = strings.ReplaceAll(macroVal, "__@"+f[1:]+"@__", f)
}
return macroVal
}

View file

@ -20,7 +20,6 @@ import (
"bytes"
"net"
"os"
"os/exec"
"path"
"strings"
@ -135,17 +134,3 @@ func TimeFromID(id string) (ret string) {
ret = id[:14]
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
}

View file

@ -17,6 +17,7 @@
package util
import (
"bytes"
"flag"
"log"
"math/rand"
@ -101,6 +102,7 @@ func Boot() {
initPathDir()
checkPort()
go initPandoc()
bootBanner := figure.NewColorFigure("SiYuan", "isometric3", "green", true)
logging.LogInfof("\n" + bootBanner.String())
@ -161,6 +163,7 @@ var (
DBPath string // SQLite 数据库文件路径
HistoryDBPath string // SQLite 历史数据库文件路径
BlockTreePath string // 区块树文件路径
PandocBinPath string // Pandoc 可执行文件路径
AppearancePath string // 配置目录下的外观目录 appearance/ 路径
ThemesPath string // 配置目录下的外观目录下的 themes/ 路径
IconsPath string // 配置目录下的外观目录下的 icons/ 路径
@ -454,3 +457,76 @@ func PidByPort(port string) (ret string) {
}
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("built-in 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 built-in 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
}