mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-17 07:00:12 +01:00
🔥 Remove Settings - Appearance - Customize the current theme https://github.com/siyuan-note/siyuan/issues/8006
This commit is contained in:
parent
a04905836e
commit
d8f4ed846b
5 changed files with 47 additions and 399 deletions
|
|
@ -266,8 +266,6 @@ func ServeAPI(ginServer *gin.Engine) {
|
||||||
ginServer.Handle("POST", "/api/setting/getCloudUser", model.CheckAuth, getCloudUser)
|
ginServer.Handle("POST", "/api/setting/getCloudUser", model.CheckAuth, getCloudUser)
|
||||||
ginServer.Handle("POST", "/api/setting/logoutCloudUser", model.CheckAuth, model.CheckReadonly, logoutCloudUser)
|
ginServer.Handle("POST", "/api/setting/logoutCloudUser", model.CheckAuth, model.CheckReadonly, logoutCloudUser)
|
||||||
ginServer.Handle("POST", "/api/setting/login2faCloudUser", model.CheckAuth, model.CheckReadonly, login2faCloudUser)
|
ginServer.Handle("POST", "/api/setting/login2faCloudUser", model.CheckAuth, model.CheckReadonly, login2faCloudUser)
|
||||||
ginServer.Handle("POST", "/api/setting/getCustomCSS", model.CheckAuth, getCustomCSS)
|
|
||||||
ginServer.Handle("POST", "/api/setting/setCustomCSS", model.CheckAuth, model.CheckReadonly, setCustomCSS)
|
|
||||||
ginServer.Handle("POST", "/api/setting/setEmoji", model.CheckAuth, model.CheckReadonly, setEmoji)
|
ginServer.Handle("POST", "/api/setting/setEmoji", model.CheckAuth, model.CheckReadonly, setEmoji)
|
||||||
ginServer.Handle("POST", "/api/setting/setFlashcard", model.CheckAuth, model.CheckReadonly, setFlashcard)
|
ginServer.Handle("POST", "/api/setting/setFlashcard", model.CheckAuth, model.CheckReadonly, setFlashcard)
|
||||||
ginServer.Handle("POST", "/api/setting/setAI", model.CheckAuth, model.CheckReadonly, setAI)
|
ginServer.Handle("POST", "/api/setting/setAI", model.CheckAuth, model.CheckReadonly, setAI)
|
||||||
|
|
|
||||||
|
|
@ -439,43 +439,6 @@ func login2faCloudUser(c *gin.Context) {
|
||||||
ret.Data = data
|
ret.Data = data
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCustomCSS(c *gin.Context) {
|
|
||||||
ret := gulu.Ret.NewResult()
|
|
||||||
defer c.JSON(http.StatusOK, ret)
|
|
||||||
|
|
||||||
arg, ok := util.JsonArg(c, ret)
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
themeName := arg["theme"].(string)
|
|
||||||
customCSS, err := model.ReadCustomCSS(themeName)
|
|
||||||
if nil != err {
|
|
||||||
ret.Code = -1
|
|
||||||
ret.Msg = err.Error()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ret.Data = customCSS
|
|
||||||
}
|
|
||||||
|
|
||||||
func setCustomCSS(c *gin.Context) {
|
|
||||||
ret := gulu.Ret.NewResult()
|
|
||||||
defer c.JSON(http.StatusOK, ret)
|
|
||||||
|
|
||||||
arg, ok := util.JsonArg(c, ret)
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
themeName := arg["theme"].(string)
|
|
||||||
css := arg["css"].(map[string]interface{})
|
|
||||||
if err := model.WriteCustomCSS(themeName, css); nil != err {
|
|
||||||
ret.Code = -1
|
|
||||||
ret.Msg = err.Error()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setEmoji(c *gin.Context) {
|
func setEmoji(c *gin.Context) {
|
||||||
ret := gulu.Ret.NewResult()
|
ret := gulu.Ret.NewResult()
|
||||||
defer c.JSON(http.StatusOK, ret)
|
defer c.JSON(http.StatusOK, ret)
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ type Appearance struct {
|
||||||
CodeBlockThemeLight string `json:"codeBlockThemeLight"` // 明亮模式下代码块主题
|
CodeBlockThemeLight string `json:"codeBlockThemeLight"` // 明亮模式下代码块主题
|
||||||
CodeBlockThemeDark string `json:"codeBlockThemeDark"` // 暗黑模式下代码块主题
|
CodeBlockThemeDark string `json:"codeBlockThemeDark"` // 暗黑模式下代码块主题
|
||||||
Lang string `json:"lang"` // 选择的界面语言,同 AppConf.Lang
|
Lang string `json:"lang"` // 选择的界面语言,同 AppConf.Lang
|
||||||
CustomCSS bool `json:"customCSS"` // 是否启用自定义主题
|
|
||||||
ThemeJS bool `json:"themeJS"` // 是否启用了主题 JavaScript
|
ThemeJS bool `json:"themeJS"` // 是否启用了主题 JavaScript
|
||||||
CloseButtonBehavior int `json:"closeButtonBehavior"` // 关闭按钮行为,0:退出,1:最小化到托盘
|
CloseButtonBehavior int `json:"closeButtonBehavior"` // 关闭按钮行为,0:退出,1:最小化到托盘
|
||||||
HideStatusBar bool `json:"hideStatusBar"` // 是否隐藏底部状态栏
|
HideStatusBar bool `json:"hideStatusBar"` // 是否隐藏底部状态栏
|
||||||
|
|
@ -48,7 +47,6 @@ func NewAppearance() *Appearance {
|
||||||
CodeBlockThemeLight: "github",
|
CodeBlockThemeLight: "github",
|
||||||
CodeBlockThemeDark: "base16/dracula",
|
CodeBlockThemeDark: "base16/dracula",
|
||||||
Lang: "en_US",
|
Lang: "en_US",
|
||||||
CustomCSS: false,
|
|
||||||
CloseButtonBehavior: 0,
|
CloseButtonBehavior: 0,
|
||||||
HideStatusBar: false,
|
HideStatusBar: false,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,104 +17,14 @@
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"github.com/88250/css"
|
||||||
"fmt"
|
"github.com/siyuan-note/logging"
|
||||||
|
"github.com/siyuan-note/siyuan/kernel/util"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/88250/css"
|
|
||||||
"github.com/88250/gulu"
|
|
||||||
"github.com/siyuan-note/filelock"
|
|
||||||
"github.com/siyuan-note/logging"
|
|
||||||
"github.com/siyuan-note/siyuan/kernel/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var colorKeys = map[string][]string{
|
|
||||||
"colorPrimary": colorPrimary,
|
|
||||||
"colorFont": colorFont,
|
|
||||||
"colorBorder": colorBorder,
|
|
||||||
"colorScroll": colorScroll,
|
|
||||||
"colorTab": colorTab,
|
|
||||||
"colorTip": colorTip,
|
|
||||||
"colorGraph": colorGraph,
|
|
||||||
"colorInline": colorInline,
|
|
||||||
}
|
|
||||||
|
|
||||||
var colorPrimary = []string{
|
|
||||||
"--b3-theme-primary",
|
|
||||||
"--b3-theme-primary-light",
|
|
||||||
"--b3-theme-primary-lighter",
|
|
||||||
"--b3-theme-primary-lightest",
|
|
||||||
"--b3-theme-secondary",
|
|
||||||
"--b3-theme-background",
|
|
||||||
"--b3-theme-surface",
|
|
||||||
"--b3-theme-error",
|
|
||||||
}
|
|
||||||
|
|
||||||
var colorFont = []string{
|
|
||||||
"--b3-theme-on-primary",
|
|
||||||
"--b3-theme-on-secondary",
|
|
||||||
"--b3-theme-on-background",
|
|
||||||
"--b3-theme-on-surface",
|
|
||||||
"--b3-theme-on-error",
|
|
||||||
}
|
|
||||||
|
|
||||||
var colorBorder = []string{
|
|
||||||
"--b3-border-color",
|
|
||||||
}
|
|
||||||
|
|
||||||
var colorScroll = []string{
|
|
||||||
"--b3-scroll-color",
|
|
||||||
}
|
|
||||||
|
|
||||||
var colorTab = []string{
|
|
||||||
"--b3-tab-background",
|
|
||||||
}
|
|
||||||
|
|
||||||
var colorTip = []string{
|
|
||||||
"--b3-tooltips-color",
|
|
||||||
}
|
|
||||||
|
|
||||||
var colorGraph = []string{
|
|
||||||
"--b3-graph-line",
|
|
||||||
"--b3-graph-hl-point",
|
|
||||||
"--b3-graph-hl-line",
|
|
||||||
"--b3-graph-p-point",
|
|
||||||
"--b3-graph-heading-point",
|
|
||||||
"--b3-graph-math-point",
|
|
||||||
"--b3-graph-code-point",
|
|
||||||
"--b3-graph-table-point",
|
|
||||||
"--b3-graph-list-point",
|
|
||||||
"--b3-graph-todo-point",
|
|
||||||
"--b3-graph-olist-point",
|
|
||||||
"--b3-graph-listitem-point",
|
|
||||||
"--b3-graph-bq-point",
|
|
||||||
"--b3-graph-super-point",
|
|
||||||
"--b3-graph-doc-point",
|
|
||||||
"--b3-graph-tag-point",
|
|
||||||
"--b3-graph-asset-point",
|
|
||||||
"--b3-graph-line",
|
|
||||||
"--b3-graph-tag-line",
|
|
||||||
"--b3-graph-ref-line",
|
|
||||||
"--b3-graph-tag-tag-line",
|
|
||||||
"--b3-graph-asset-line",
|
|
||||||
"--b3-graph-hl-point",
|
|
||||||
"--b3-graph-hl-line",
|
|
||||||
}
|
|
||||||
|
|
||||||
var colorInline = []string{
|
|
||||||
"--b3-protyle-inline-strong-color",
|
|
||||||
"--b3-protyle-inline-em-color",
|
|
||||||
"--b3-protyle-inline-s-color",
|
|
||||||
"--b3-protyle-inline-link-color",
|
|
||||||
"--b3-protyle-inline-tag-color",
|
|
||||||
"--b3-protyle-inline-blockref-color",
|
|
||||||
"--b3-protyle-inline-mark-background",
|
|
||||||
"--b3-protyle-inline-mark-color",
|
|
||||||
}
|
|
||||||
|
|
||||||
func currentCSSValue(key string) string {
|
func currentCSSValue(key string) string {
|
||||||
var themeName string
|
var themeName string
|
||||||
if 0 == Conf.Appearance.Mode {
|
if 0 == Conf.Appearance.Mode {
|
||||||
|
|
@ -125,19 +35,11 @@ func currentCSSValue(key string) string {
|
||||||
|
|
||||||
themePath := filepath.Join(util.ThemesPath, themeName)
|
themePath := filepath.Join(util.ThemesPath, themeName)
|
||||||
theme := filepath.Join(themePath, "theme.css")
|
theme := filepath.Join(themePath, "theme.css")
|
||||||
custom := filepath.Join(themePath, "custom.css")
|
|
||||||
|
|
||||||
var data []byte
|
data, err := os.ReadFile(theme)
|
||||||
var err error
|
if nil != err {
|
||||||
if Conf.Appearance.CustomCSS {
|
logging.LogErrorf("read theme css [%s] failed: %s", theme, err)
|
||||||
data, _ = os.ReadFile(custom)
|
return "#ffffff"
|
||||||
}
|
|
||||||
if 1 > len(data) {
|
|
||||||
data, err = os.ReadFile(theme)
|
|
||||||
if nil != err {
|
|
||||||
logging.LogErrorf("read theme css [%s] failed: %s", theme, err)
|
|
||||||
return "#ffffff"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ss := css.Parse(string(data))
|
ss := css.Parse(string(data))
|
||||||
|
|
@ -154,143 +56,6 @@ func currentCSSValue(key string) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadCustomCSS(themeName string) (ret map[string]map[string]string, err error) {
|
|
||||||
ret = map[string]map[string]string{}
|
|
||||||
|
|
||||||
themePath := filepath.Join(util.ThemesPath, themeName)
|
|
||||||
theme := filepath.Join(themePath, "theme.css")
|
|
||||||
custom := filepath.Join(themePath, "custom.css")
|
|
||||||
|
|
||||||
if !gulu.File.IsExist(custom) {
|
|
||||||
if err = filelock.Copy(theme, custom); nil != err {
|
|
||||||
logging.LogErrorf("copy theme [%s] to [%s] failed: %s", theme, custom, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err := os.ReadFile(custom)
|
|
||||||
if nil != err {
|
|
||||||
logging.LogErrorf("read custom css [%s] failed: %s", custom, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fullColorMap := map[string]string{}
|
|
||||||
ss := css.Parse(string(data))
|
|
||||||
rules := ss.GetCSSRuleList()
|
|
||||||
for _, rule := range rules {
|
|
||||||
for _, style := range rule.Style.Styles {
|
|
||||||
fixStyle(style)
|
|
||||||
|
|
||||||
fullColorMap[style.Property] = style.Value.Text()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 补充现有主题中的样式
|
|
||||||
data, err = os.ReadFile(theme)
|
|
||||||
if nil != err {
|
|
||||||
logging.LogErrorf("read theme css [%s] failed: %s", theme, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ss = css.Parse(string(data))
|
|
||||||
rules = ss.GetCSSRuleList()
|
|
||||||
for _, rule := range rules {
|
|
||||||
for _, style := range rule.Style.Styles {
|
|
||||||
fixStyle(style)
|
|
||||||
if _, ok := fullColorMap[style.Property]; !ok {
|
|
||||||
fullColorMap[style.Property] = style.Value.ParsedText()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buildColor(&ret, fullColorMap, "colorPrimary")
|
|
||||||
buildColor(&ret, fullColorMap, "colorFont")
|
|
||||||
buildColor(&ret, fullColorMap, "colorBorder")
|
|
||||||
buildColor(&ret, fullColorMap, "colorScroll")
|
|
||||||
buildColor(&ret, fullColorMap, "colorTab")
|
|
||||||
buildColor(&ret, fullColorMap, "colorTip")
|
|
||||||
buildColor(&ret, fullColorMap, "colorGraph")
|
|
||||||
buildColor(&ret, fullColorMap, "colorInline")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildColor(ret *map[string]map[string]string, fullColorMap map[string]string, colorMapKey string) {
|
|
||||||
colorMap := map[string]string{}
|
|
||||||
for _, colorKey := range colorKeys[colorMapKey] {
|
|
||||||
colorMap[colorKey] = fullColorMap[colorKey]
|
|
||||||
}
|
|
||||||
(*ret)[colorMapKey] = colorMap
|
|
||||||
}
|
|
||||||
|
|
||||||
func WriteCustomCSS(themeName string, cssMap map[string]interface{}) (err error) {
|
|
||||||
customCSS := map[string]string{}
|
|
||||||
for _, vMap := range cssMap {
|
|
||||||
cssKV := vMap.(map[string]interface{})
|
|
||||||
for k, v := range cssKV {
|
|
||||||
customCSS[k] = v.(string)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
themePath := filepath.Join(util.ThemesPath, themeName)
|
|
||||||
custom := filepath.Join(themePath, "custom.css")
|
|
||||||
data, err := os.ReadFile(custom)
|
|
||||||
if nil != err {
|
|
||||||
logging.LogErrorf("read custom css [%s] failed: %s", custom, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
cssData := gulu.Str.RemoveInvisible(string(data))
|
|
||||||
customStyleSheet := css.Parse(cssData)
|
|
||||||
|
|
||||||
buf := &bytes.Buffer{}
|
|
||||||
customRules := customStyleSheet.CssRuleList
|
|
||||||
for _, customRule := range customRules {
|
|
||||||
if css.KEYFRAMES_RULE == customRule.Type {
|
|
||||||
keyframes(customRule, buf)
|
|
||||||
continue
|
|
||||||
} else if css.STYLE_RULE != customRule.Type {
|
|
||||||
buf.WriteString(customRule.Type.Text())
|
|
||||||
buf.WriteString(customRule.Style.Text())
|
|
||||||
buf.WriteString("\n\n")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, style := range customRule.Style.Styles {
|
|
||||||
fixStyle(style)
|
|
||||||
|
|
||||||
if val, ok := customCSS[style.Property]; ok {
|
|
||||||
style.Value = css.NewCSSValue(val)
|
|
||||||
delete(customCSS, style.Property)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for k, v := range customCSS {
|
|
||||||
customRule.Style.Styles = append(customRule.Style.Styles, &css.CSSStyleDeclaration{Property: k, Value: css.NewCSSValue(v)})
|
|
||||||
}
|
|
||||||
buf.WriteString(customRule.Style.Text())
|
|
||||||
buf.WriteString("\n\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := gulu.File.WriteFileSafer(custom, buf.Bytes(), 0644); nil != err {
|
|
||||||
logging.LogErrorf("write custom css [%s] failed: %s", custom, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
util.BroadcastByType("main", "refreshtheme", 0, "", map[string]interface{}{
|
|
||||||
"theme": "/appearance/themes/" + themeName + "/custom.css?" + fmt.Sprintf("%d", time.Now().Unix()),
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func keyframes(rule *css.CSSRule, buf *bytes.Buffer) {
|
|
||||||
buf.WriteString(rule.Type.Text())
|
|
||||||
buf.WriteString(" ")
|
|
||||||
buf.WriteString(rule.Style.Selector.Text())
|
|
||||||
buf.WriteString(" {\n")
|
|
||||||
for _, r := range rule.Rules {
|
|
||||||
buf.WriteString(r.Style.Text())
|
|
||||||
buf.WriteString("\n")
|
|
||||||
}
|
|
||||||
buf.WriteString("\n\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
func fixStyle(style *css.CSSStyleDeclaration) {
|
func fixStyle(style *css.CSSStyleDeclaration) {
|
||||||
// css 解析库似乎有 bug,这里做修正
|
// css 解析库似乎有 bug,这里做修正
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,32 +33,22 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type GraphNode struct {
|
type GraphNode struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Box string `json:"box"`
|
Box string `json:"box"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
Size float64 `json:"size"`
|
Size float64 `json:"size"`
|
||||||
Title string `json:"title,omitempty"`
|
Title string `json:"title,omitempty"`
|
||||||
Label string `json:"label"`
|
Label string `json:"label"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Refs int `json:"refs"`
|
Refs int `json:"refs"`
|
||||||
Defs int `json:"defs"`
|
Defs int `json:"defs"`
|
||||||
Color *GraphNodeColor `json:"color"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type GraphNodeColor struct {
|
|
||||||
Background string `json:"background"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type GraphLink struct {
|
type GraphLink struct {
|
||||||
From string `json:"from"`
|
From string `json:"from"`
|
||||||
To string `json:"to"`
|
To string `json:"to"`
|
||||||
Ref bool `json:"-"`
|
Ref bool `json:"-"`
|
||||||
Color *GraphLinkColor `json:"color"`
|
Arrows *GraphArrows `json:"arrows"`
|
||||||
Arrows *GraphArrows `json:"arrows"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type GraphLinkColor struct {
|
|
||||||
Color string `json:"color"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type GraphArrows struct {
|
type GraphArrows struct {
|
||||||
|
|
@ -158,15 +148,15 @@ func BuildTreeGraph(id, query string) (boxID string, nodes []*GraphNode, links [
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
style := graphStyle(true)
|
|
||||||
genTreeNodes(blocks, &nodes, &links, true, style)
|
genTreeNodes(blocks, &nodes, &links, true)
|
||||||
growTreeGraph(&forwardlinks, &backlinks, &nodes)
|
growTreeGraph(&forwardlinks, &backlinks, &nodes)
|
||||||
blocks = append(blocks, forwardlinks...)
|
blocks = append(blocks, forwardlinks...)
|
||||||
blocks = append(blocks, backlinks...)
|
blocks = append(blocks, backlinks...)
|
||||||
buildLinks(&blocks, &links, style, true)
|
buildLinks(&blocks, &links, true)
|
||||||
if Conf.Graph.Local.Tag {
|
if Conf.Graph.Local.Tag {
|
||||||
p := sqlBlock.Path
|
p := sqlBlock.Path
|
||||||
linkTagBlocks(&blocks, &nodes, &links, p, style)
|
linkTagBlocks(&blocks, &nodes, &links, p)
|
||||||
}
|
}
|
||||||
markLinkedNodes(&nodes, &links, true)
|
markLinkedNodes(&nodes, &links, true)
|
||||||
nodes = removeDuplicatedUnescape(nodes)
|
nodes = removeDuplicatedUnescape(nodes)
|
||||||
|
|
@ -186,7 +176,6 @@ func BuildGraph(query string) (boxID string, nodes []*GraphNode, links []*GraphL
|
||||||
|
|
||||||
var blocks []*Block
|
var blocks []*Block
|
||||||
roots := sql.GetAllRootBlocks()
|
roots := sql.GetAllRootBlocks()
|
||||||
style := graphStyle(false)
|
|
||||||
if 0 < len(roots) {
|
if 0 < len(roots) {
|
||||||
boxID = roots[0].Box
|
boxID = roots[0].Box
|
||||||
}
|
}
|
||||||
|
|
@ -198,7 +187,7 @@ func BuildGraph(query string) (boxID string, nodes []*GraphNode, links []*GraphL
|
||||||
|
|
||||||
sqlBlocks := sql.GetAllChildBlocks(rootIDs, stmt)
|
sqlBlocks := sql.GetAllChildBlocks(rootIDs, stmt)
|
||||||
treeBlocks := fromSQLBlocks(&sqlBlocks, "", 0)
|
treeBlocks := fromSQLBlocks(&sqlBlocks, "", 0)
|
||||||
genTreeNodes(treeBlocks, &nodes, &links, false, style)
|
genTreeNodes(treeBlocks, &nodes, &links, false)
|
||||||
blocks = append(blocks, treeBlocks...)
|
blocks = append(blocks, treeBlocks...)
|
||||||
|
|
||||||
// 文档块关联
|
// 文档块关联
|
||||||
|
|
@ -216,9 +205,9 @@ func BuildGraph(query string) (boxID string, nodes []*GraphNode, links []*GraphL
|
||||||
growTreeGraph(&forwardlinks, &backlinks, &nodes)
|
growTreeGraph(&forwardlinks, &backlinks, &nodes)
|
||||||
blocks = append(blocks, forwardlinks...)
|
blocks = append(blocks, forwardlinks...)
|
||||||
blocks = append(blocks, backlinks...)
|
blocks = append(blocks, backlinks...)
|
||||||
buildLinks(&blocks, &links, style, false)
|
buildLinks(&blocks, &links, false)
|
||||||
if Conf.Graph.Global.Tag {
|
if Conf.Graph.Global.Tag {
|
||||||
linkTagBlocks(&blocks, &nodes, &links, "", style)
|
linkTagBlocks(&blocks, &nodes, &links, "")
|
||||||
}
|
}
|
||||||
markLinkedNodes(&nodes, &links, false)
|
markLinkedNodes(&nodes, &links, false)
|
||||||
pruneUnref(&nodes, &links)
|
pruneUnref(&nodes, &links)
|
||||||
|
|
@ -226,7 +215,7 @@ func BuildGraph(query string) (boxID string, nodes []*GraphNode, links []*GraphL
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func linkTagBlocks(blocks *[]*Block, nodes *[]*GraphNode, links *[]*GraphLink, p string, style map[string]string) {
|
func linkTagBlocks(blocks *[]*Block, nodes *[]*GraphNode, links *[]*GraphLink, p string) {
|
||||||
tagSpans := sql.QueryTagSpans(p)
|
tagSpans := sql.QueryTagSpans(p)
|
||||||
if 1 > len(tagSpans) {
|
if 1 > len(tagSpans) {
|
||||||
return
|
return
|
||||||
|
|
@ -247,7 +236,6 @@ func linkTagBlocks(blocks *[]*Block, nodes *[]*GraphNode, links *[]*GraphLink, p
|
||||||
Label: tagSpan.Content,
|
Label: tagSpan.Content,
|
||||||
Size: nodeSize,
|
Size: nodeSize,
|
||||||
Type: tagSpan.Type,
|
Type: tagSpan.Type,
|
||||||
Color: &GraphNodeColor{Background: style["--b3-graph-tag-point"]},
|
|
||||||
}
|
}
|
||||||
*nodes = append(*nodes, node)
|
*nodes = append(*nodes, node)
|
||||||
tagNodes = append(tagNodes, node)
|
tagNodes = append(tagNodes, node)
|
||||||
|
|
@ -260,17 +248,15 @@ func linkTagBlocks(blocks *[]*Block, nodes *[]*GraphNode, links *[]*GraphLink, p
|
||||||
if isGlobal { // 全局关系图将标签链接到文档块上
|
if isGlobal { // 全局关系图将标签链接到文档块上
|
||||||
if block.RootID == tagSpan.RootID { // 局部关系图将标签链接到子块上
|
if block.RootID == tagSpan.RootID { // 局部关系图将标签链接到子块上
|
||||||
*links = append(*links, &GraphLink{
|
*links = append(*links, &GraphLink{
|
||||||
From: tagSpan.Content,
|
From: tagSpan.Content,
|
||||||
To: block.RootID,
|
To: block.RootID,
|
||||||
Color: &GraphLinkColor{Color: style["--b3-graph-tag-line"]},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if block.ID == tagSpan.BlockID { // 局部关系图将标签链接到子块上
|
if block.ID == tagSpan.BlockID { // 局部关系图将标签链接到子块上
|
||||||
*links = append(*links, &GraphLink{
|
*links = append(*links, &GraphLink{
|
||||||
From: tagSpan.Content,
|
From: tagSpan.Content,
|
||||||
To: block.ID,
|
To: block.ID,
|
||||||
Color: &GraphLinkColor{Color: style["--b3-graph-tag-line"]},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -288,9 +274,8 @@ func linkTagBlocks(blocks *[]*Block, nodes *[]*GraphNode, links *[]*GraphLink, p
|
||||||
if targetTag := tagNodeIn(tagNodes, targetID); nil != targetTag {
|
if targetTag := tagNodeIn(tagNodes, targetID); nil != targetTag {
|
||||||
|
|
||||||
*links = append(*links, &GraphLink{
|
*links = append(*links, &GraphLink{
|
||||||
From: tagNode.ID,
|
From: tagNode.ID,
|
||||||
To: targetID,
|
To: targetID,
|
||||||
Color: &GraphLinkColor{Color: style["--b3-graph-tag-tag-line"]},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -388,14 +373,13 @@ func existNodes(nodes *[]*GraphNode, id string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildLinks(defs *[]*Block, links *[]*GraphLink, style map[string]string, local bool) {
|
func buildLinks(defs *[]*Block, links *[]*GraphLink, local bool) {
|
||||||
for _, def := range *defs {
|
for _, def := range *defs {
|
||||||
for _, ref := range def.Refs {
|
for _, ref := range def.Refs {
|
||||||
link := &GraphLink{
|
link := &GraphLink{
|
||||||
From: ref.ID,
|
From: ref.ID,
|
||||||
To: def.ID,
|
To: def.ID,
|
||||||
Ref: true,
|
Ref: true,
|
||||||
Color: linkColor(true, style),
|
|
||||||
}
|
}
|
||||||
if local {
|
if local {
|
||||||
if Conf.Graph.Local.Arrow {
|
if Conf.Graph.Local.Arrow {
|
||||||
|
|
@ -411,7 +395,7 @@ func buildLinks(defs *[]*Block, links *[]*GraphLink, style map[string]string, lo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func genTreeNodes(blocks []*Block, nodes *[]*GraphNode, links *[]*GraphLink, local bool, style map[string]string) {
|
func genTreeNodes(blocks []*Block, nodes *[]*GraphNode, links *[]*GraphLink, local bool) {
|
||||||
nodeSize := Conf.Graph.Local.NodeSize
|
nodeSize := Conf.Graph.Local.NodeSize
|
||||||
if !local {
|
if !local {
|
||||||
nodeSize = Conf.Graph.Global.NodeSize
|
nodeSize = Conf.Graph.Global.NodeSize
|
||||||
|
|
@ -419,21 +403,19 @@ func genTreeNodes(blocks []*Block, nodes *[]*GraphNode, links *[]*GraphLink, loc
|
||||||
|
|
||||||
for _, block := range blocks {
|
for _, block := range blocks {
|
||||||
node := &GraphNode{
|
node := &GraphNode{
|
||||||
ID: block.ID,
|
ID: block.ID,
|
||||||
Box: block.Box,
|
Box: block.Box,
|
||||||
Path: block.Path,
|
Path: block.Path,
|
||||||
Type: block.Type,
|
Type: block.Type,
|
||||||
Size: nodeSize,
|
Size: nodeSize,
|
||||||
Color: &GraphNodeColor{Background: nodeColor(block.Type, style)},
|
|
||||||
}
|
}
|
||||||
nodeTitleLabel(node, nodeContentByBlock(block))
|
nodeTitleLabel(node, nodeContentByBlock(block))
|
||||||
*nodes = append(*nodes, node)
|
*nodes = append(*nodes, node)
|
||||||
|
|
||||||
*links = append(*links, &GraphLink{
|
*links = append(*links, &GraphLink{
|
||||||
From: block.ParentID,
|
From: block.ParentID,
|
||||||
To: block.ID,
|
To: block.ID,
|
||||||
Ref: false,
|
Ref: false,
|
||||||
Color: linkColor(false, style),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -554,42 +536,6 @@ func nodeContentByNode(node *ast.Node, text string) (ret string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func linkColor(ref bool, style map[string]string) (ret *GraphLinkColor) {
|
|
||||||
ret = &GraphLinkColor{}
|
|
||||||
if ref {
|
|
||||||
ret.Color = style["--b3-graph-ref-line"]
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ret.Color = style["--b3-graph-line"]
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func nodeColor(typ string, style map[string]string) string {
|
|
||||||
switch typ {
|
|
||||||
case "NodeDocument":
|
|
||||||
return style["--b3-graph-doc-point"]
|
|
||||||
case "NodeParagraph":
|
|
||||||
return style["--b3-graph-p-point"]
|
|
||||||
case "NodeHeading":
|
|
||||||
return style["--b3-graph-heading-point"]
|
|
||||||
case "NodeMathBlock":
|
|
||||||
return style["--b3-graph-math-point"]
|
|
||||||
case "NodeCodeBlock":
|
|
||||||
return style["--b3-graph-code-point"]
|
|
||||||
case "NodeTable":
|
|
||||||
return style["--b3-graph-table-point"]
|
|
||||||
case "NodeList":
|
|
||||||
return style["--b3-graph-list-point"]
|
|
||||||
case "NodeListItem":
|
|
||||||
return style["--b3-graph-listitem-point"]
|
|
||||||
case "NodeBlockquote":
|
|
||||||
return style["--b3-graph-bq-point"]
|
|
||||||
case "NodeSuperBlock":
|
|
||||||
return style["--b3-graph-super-point"]
|
|
||||||
}
|
|
||||||
return style["--b3-graph-p-point"]
|
|
||||||
}
|
|
||||||
|
|
||||||
func graphTypeFilter(local bool) string {
|
func graphTypeFilter(local bool) string {
|
||||||
var inList []string
|
var inList []string
|
||||||
|
|
||||||
|
|
@ -703,28 +649,6 @@ func dailyNotePaths(local bool) (ret []string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func graphStyle(local bool) (ret map[string]string) {
|
|
||||||
ret = map[string]string{}
|
|
||||||
ret["--b3-graph-doc-point"] = currentCSSValue("--b3-graph-doc-point")
|
|
||||||
ret["--b3-graph-p-point"] = currentCSSValue("--b3-graph-p-point")
|
|
||||||
ret["--b3-graph-heading-point"] = currentCSSValue("--b3-graph-heading-point")
|
|
||||||
ret["--b3-graph-math-point"] = currentCSSValue("--b3-graph-math-point")
|
|
||||||
ret["--b3-graph-code-point"] = currentCSSValue("--b3-graph-code-point")
|
|
||||||
ret["--b3-graph-table-point"] = currentCSSValue("--b3-graph-table-point")
|
|
||||||
ret["--b3-graph-list-point"] = currentCSSValue("--b3-graph-list-point")
|
|
||||||
ret["--b3-graph-listitem-point"] = currentCSSValue("--b3-graph-listitem-point")
|
|
||||||
ret["--b3-graph-bq-point"] = currentCSSValue("--b3-graph-bq-point")
|
|
||||||
ret["--b3-graph-super-point"] = currentCSSValue("--b3-graph-super-point")
|
|
||||||
|
|
||||||
ret["--b3-graph-line"] = currentCSSValue("--b3-graph-line")
|
|
||||||
ret["--b3-graph-ref-line"] = currentCSSValue("--b3-graph-ref-line")
|
|
||||||
ret["--b3-graph-tag-line"] = currentCSSValue("--b3-graph-tag-line")
|
|
||||||
ret["--b3-graph-tag-tag-line"] = currentCSSValue("--b3-graph-tag-tag-line")
|
|
||||||
ret["--b3-graph-asset-line"] = currentCSSValue("--b3-graph-asset-line")
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func nodeTitleLabel(node *GraphNode, blockContent string) {
|
func nodeTitleLabel(node *GraphNode, blockContent string) {
|
||||||
if "NodeDocument" != node.Type && "NodeHeading" != node.Type {
|
if "NodeDocument" != node.Type && "NodeHeading" != node.Type {
|
||||||
node.Title = blockContent
|
node.Title = blockContent
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue