فهرست منبع

:art: Support KaTex macro parameters https://github.com/siyuan-note/siyuan/issues/11448

Daniel 1 سال پیش
والد
کامیت
491a1696c1
2فایلهای تغییر یافته به همراه45 افزوده شده و 0 حذف شده
  1. 10 0
      kernel/model/export.go
  2. 35 0
      kernel/model/export_katex.go

+ 10 - 0
kernel/model/export.go

@@ -1962,6 +1962,16 @@ func processKaTexMacros(n *ast.Node) {
 		depth := 1
 		expanded := resolveKaTexMacro(usedMacro, &macros, &keys, &depth)
 		expanded = unescapeKaTexSupportedFunctions(expanded)
+
+		idx := strings.Index(mathContent, usedMacro)
+		if idx < 0 {
+			continue
+		}
+
+		// 处理宏参数
+		fillKaTexMacrosParams(usedMacro, &mathContent, &expanded)
+
+		// 将宏展开替换到 mathContent 中
 		mathContent = strings.ReplaceAll(mathContent, usedMacro, expanded)
 	}
 	mathContent = unescapeKaTexSupportedFunctions(mathContent)

+ 35 - 0
kernel/model/export_katex.go

@@ -18,7 +18,10 @@ package model
 
 import (
 	"sort"
+	"strconv"
 	"strings"
+
+	"github.com/88250/gulu"
 )
 
 func extractUsedMacros(mathContent string, macrosKeys *[]string) (ret []string) {
@@ -952,3 +955,35 @@ func unescapeKaTexSupportedFunctions(macroVal string) string {
 	}
 	return macroVal
 }
+
+func fillKaTexMacrosParams(macro string, mathContent, expanded *string) {
+	// Support KaTex macro parameters https://github.com/siyuan-note/siyuan/issues/11448
+
+	idx := strings.Index(*mathContent, macro)
+	if idx < 0 {
+		return
+	}
+
+	// 提取 mathContent 中 {} 包裹的实参,这里可能会提取到其他多余的参数,但是后面仅替换宏中的 #1, #2, ...,所以不影响
+	tmp := (*mathContent)[idx:]
+	args := map[int]string{}
+	for i, arg := range gulu.Str.SubstringsBetween(tmp, "{", "}") {
+		args[i+1] = arg
+	}
+
+	// 将宏展开中的 #1, #2, ... 替换为实参
+	// Macros accept up to nine arguments: #1, #2, etc. https://katex.org/docs/supported#macros
+	paramsCount := 0
+	for i := 0; i < len(args); i++ {
+		if strings.Contains(*expanded, "#"+strconv.Itoa(i+1)) {
+			paramsCount++
+			*expanded = strings.ReplaceAll(*expanded, "#"+strconv.Itoa(i+1), args[i+1])
+		}
+	}
+
+	// 根据参数个数将 mathContent 中的实参替换为空
+	for i := 1; i <= paramsCount; i++ {
+		tmp = strings.ReplaceAll(tmp, "{"+args[i]+"}", "")
+		*mathContent = (*mathContent)[:idx] + tmp
+	}
+}