mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-29 21:08:49 +01:00
Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
7034ab30c1
15 changed files with 261 additions and 100 deletions
2
app/stage/protyle/js/lute/lute.min.js
vendored
2
app/stage/protyle/js/lute/lute.min.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -21,6 +21,7 @@ import (
|
|||
|
||||
"github.com/88250/gulu"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/siyuan-note/siyuan/kernel/bazaar"
|
||||
"github.com/siyuan-note/siyuan/kernel/model"
|
||||
"github.com/siyuan-note/siyuan/kernel/util"
|
||||
)
|
||||
|
|
@ -164,6 +165,15 @@ func getBazaarTemplate(c *gin.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
func getInstalledTemplate(c *gin.Context) {
|
||||
ret := gulu.Ret.NewResult()
|
||||
defer c.JSON(http.StatusOK, ret)
|
||||
|
||||
ret.Data = map[string]interface{}{
|
||||
"packages": bazaar.InstalledTemplates(),
|
||||
}
|
||||
}
|
||||
|
||||
func installBazaarTemplate(c *gin.Context) {
|
||||
ret := gulu.Ret.NewResult()
|
||||
defer c.JSON(http.StatusOK, ret)
|
||||
|
|
@ -221,6 +231,15 @@ func getBazaarTheme(c *gin.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
func getInstalledTheme(c *gin.Context) {
|
||||
ret := gulu.Ret.NewResult()
|
||||
defer c.JSON(http.StatusOK, ret)
|
||||
|
||||
ret.Data = map[string]interface{}{
|
||||
"packages": bazaar.InstalledThemes(),
|
||||
}
|
||||
}
|
||||
|
||||
func installBazaarTheme(c *gin.Context) {
|
||||
ret := gulu.Ret.NewResult()
|
||||
defer c.JSON(http.StatusOK, ret)
|
||||
|
|
|
|||
|
|
@ -240,9 +240,11 @@ func ServeAPI(ginServer *gin.Engine) {
|
|||
ginServer.Handle("POST", "/api/bazaar/installBazaarIcon", model.CheckAuth, installBazaarIcon)
|
||||
ginServer.Handle("POST", "/api/bazaar/uninstallBazaarIcon", model.CheckAuth, uninstallBazaarIcon)
|
||||
ginServer.Handle("POST", "/api/bazaar/getBazaarTemplate", model.CheckAuth, getBazaarTemplate)
|
||||
ginServer.Handle("POST", "/api/bazaar/getInstalledTemplate", model.CheckAuth, getInstalledTemplate)
|
||||
ginServer.Handle("POST", "/api/bazaar/installBazaarTemplate", model.CheckAuth, installBazaarTemplate)
|
||||
ginServer.Handle("POST", "/api/bazaar/uninstallBazaarTemplate", model.CheckAuth, uninstallBazaarTemplate)
|
||||
ginServer.Handle("POST", "/api/bazaar/getBazaarTheme", model.CheckAuth, getBazaarTheme)
|
||||
ginServer.Handle("POST", "/api/bazaar/getInstalledTheme", model.CheckAuth, getInstalledTheme)
|
||||
ginServer.Handle("POST", "/api/bazaar/installBazaarTheme", model.CheckAuth, installBazaarTheme)
|
||||
ginServer.Handle("POST", "/api/bazaar/uninstallBazaarTheme", model.CheckAuth, uninstallBazaarTheme)
|
||||
ginServer.Handle("POST", "/api/bazaar/getBazaarPackageREAME", model.CheckAuth, getBazaarPackageREAME)
|
||||
|
|
|
|||
|
|
@ -57,26 +57,13 @@ type Icon struct {
|
|||
|
||||
func Icons() (icons []*Icon) {
|
||||
icons = []*Icon{}
|
||||
result, err := util.GetRhyResult(false)
|
||||
if nil != err {
|
||||
return
|
||||
}
|
||||
|
||||
bazaarIndex := getBazaarIndex()
|
||||
bazaarHash := result["bazaar"].(string)
|
||||
result = map[string]interface{}{}
|
||||
request := httpclient.NewBrowserRequest()
|
||||
u := util.BazaarOSSServer + "/bazaar@" + bazaarHash + "/stage/icons.json"
|
||||
resp, err := request.SetResult(&result).Get(u)
|
||||
pkgIndex, err := getPkgIndex("icons")
|
||||
if nil != err {
|
||||
logging.LogErrorf("get community stage index [%s] failed: %s", u, err)
|
||||
return
|
||||
}
|
||||
if 200 != resp.StatusCode {
|
||||
logging.LogErrorf("get community stage index [%s] failed: %d", u, resp.StatusCode)
|
||||
return
|
||||
}
|
||||
repos := result["repos"].([]interface{})
|
||||
bazaarIndex := getBazaarIndex()
|
||||
repos := pkgIndex["repos"].([]interface{})
|
||||
waitGroup := &sync.WaitGroup{}
|
||||
lock := &sync.Mutex{}
|
||||
p, _ := ants.NewPoolWithFunc(2, func(arg interface{}) {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,90 @@ import (
|
|||
"golang.org/x/text/transform"
|
||||
)
|
||||
|
||||
func TemplateJSON(templateDirName string) (ret map[string]interface{}, err error) {
|
||||
p := filepath.Join(util.ThemesPath, templateDirName, "template.json")
|
||||
if !gulu.File.IsExist(p) {
|
||||
err = os.ErrNotExist
|
||||
return
|
||||
}
|
||||
data, err := os.ReadFile(p)
|
||||
if nil != err {
|
||||
logging.LogErrorf("read template.json [%s] failed: %s", p, err)
|
||||
return
|
||||
}
|
||||
if err = gulu.JSON.UnmarshalJSON(data, &ret); nil != err {
|
||||
logging.LogErrorf("parse template.json [%s] failed: %s", p, err)
|
||||
return
|
||||
}
|
||||
if 4 > len(ret) {
|
||||
logging.LogWarnf("invalid template.json [%s]", p)
|
||||
return nil, errors.New("invalid template.json")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func ThemeJSON(themeDirName string) (ret map[string]interface{}, err error) {
|
||||
p := filepath.Join(util.ThemesPath, themeDirName, "theme.json")
|
||||
if !gulu.File.IsExist(p) {
|
||||
err = os.ErrNotExist
|
||||
return
|
||||
}
|
||||
data, err := os.ReadFile(p)
|
||||
if nil != err {
|
||||
logging.LogErrorf("read theme.json [%s] failed: %s", p, err)
|
||||
return
|
||||
}
|
||||
if err = gulu.JSON.UnmarshalJSON(data, &ret); nil != err {
|
||||
logging.LogErrorf("parse theme.json [%s] failed: %s", p, err)
|
||||
return
|
||||
}
|
||||
if 5 > len(ret) {
|
||||
logging.LogWarnf("invalid theme.json [%s]", p)
|
||||
return nil, errors.New("invalid theme.json")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getPkgIndex(pkgType string) (ret map[string]interface{}, err error) {
|
||||
ret, err = util.GetRhyResult(false)
|
||||
if nil != err {
|
||||
return
|
||||
}
|
||||
|
||||
bazaarHash := ret["bazaar"].(string)
|
||||
ret = map[string]interface{}{}
|
||||
request := httpclient.NewBrowserRequest()
|
||||
u := util.BazaarOSSServer + "/bazaar@" + bazaarHash + "/stage/" + pkgType + ".json"
|
||||
resp, reqErr := request.SetResult(&ret).Get(u)
|
||||
if nil != reqErr {
|
||||
logging.LogErrorf("get community stage index [%s] failed: %s", u, reqErr)
|
||||
return
|
||||
}
|
||||
if 200 != resp.StatusCode {
|
||||
logging.LogErrorf("get community stage index [%s] failed: %d", u, resp.StatusCode)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func isOutdatedPkg(fullURL, version string, pkgIndex map[string]interface{}) bool {
|
||||
if !strings.HasPrefix(fullURL, "https://github.com/") {
|
||||
return false
|
||||
}
|
||||
|
||||
url := strings.TrimPrefix(fullURL, "https://github.com/")
|
||||
repos := pkgIndex["repos"].([]interface{})
|
||||
for _, repo := range repos {
|
||||
r := repo.(map[string]interface{})
|
||||
repoURL := r["url"].(string)
|
||||
repoVer := r["version"].(string)
|
||||
if url == repoURL && version != repoVer {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func GetPackageREADME(repoURL, repoHash string, systemID string) (ret string) {
|
||||
repoURLHash := repoURL + "@" + repoHash
|
||||
data, err := downloadPackage(repoURLHash+"/README.md", false, systemID)
|
||||
|
|
|
|||
|
|
@ -19,11 +19,13 @@ package bazaar
|
|||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/88250/gulu"
|
||||
"github.com/dustin/go-humanize"
|
||||
"github.com/panjf2000/ants/v2"
|
||||
"github.com/siyuan-note/httpclient"
|
||||
|
|
@ -57,27 +59,13 @@ type Template struct {
|
|||
|
||||
func Templates() (templates []*Template) {
|
||||
templates = []*Template{}
|
||||
result, err := util.GetRhyResult(false)
|
||||
|
||||
pkgIndex, err := getPkgIndex("templates")
|
||||
if nil != err {
|
||||
return
|
||||
}
|
||||
|
||||
bazaarIndex := getBazaarIndex()
|
||||
bazaarHash := result["bazaar"].(string)
|
||||
result = map[string]interface{}{}
|
||||
request := httpclient.NewBrowserRequest()
|
||||
u := util.BazaarOSSServer + "/bazaar@" + bazaarHash + "/stage/templates.json"
|
||||
resp, reqErr := request.SetResult(&result).Get(u)
|
||||
if nil != reqErr {
|
||||
logging.LogErrorf("get community stage index [%s] failed: %s", u, reqErr)
|
||||
return
|
||||
}
|
||||
if 200 != resp.StatusCode {
|
||||
logging.LogErrorf("get community stage index [%s] failed: %d", u, resp.StatusCode)
|
||||
return
|
||||
}
|
||||
|
||||
repos := result["repos"].([]interface{})
|
||||
repos := pkgIndex["repos"].([]interface{})
|
||||
waitGroup := &sync.WaitGroup{}
|
||||
lock := &sync.Mutex{}
|
||||
p, _ := ants.NewPoolWithFunc(2, func(arg interface{}) {
|
||||
|
|
@ -130,6 +118,53 @@ func Templates() (templates []*Template) {
|
|||
return
|
||||
}
|
||||
|
||||
func InstalledTemplates() (ret []*Template) {
|
||||
dir, err := os.Open(filepath.Join(util.DataDir, "templates"))
|
||||
if nil != err {
|
||||
logging.LogWarnf("open templates folder [%s] failed: %s", util.ThemesPath, err)
|
||||
return
|
||||
}
|
||||
templateDirs, err := dir.Readdir(-1)
|
||||
if nil != err {
|
||||
logging.LogWarnf("read templates folder failed: %s", err)
|
||||
return
|
||||
}
|
||||
dir.Close()
|
||||
|
||||
for _, templateDir := range templateDirs {
|
||||
if !templateDir.IsDir() {
|
||||
continue
|
||||
}
|
||||
dirName := templateDir.Name()
|
||||
templateConf, parseErr := TemplateJSON(dirName)
|
||||
if nil != parseErr || nil == templateConf {
|
||||
continue
|
||||
}
|
||||
|
||||
template := &Template{}
|
||||
template.Name = templateConf["name"].(string)
|
||||
template.Author = templateConf["author"].(string)
|
||||
template.URL = templateConf["url"].(string)
|
||||
template.Version = templateConf["version"].(string)
|
||||
template.RepoURL = template.URL
|
||||
template.PreviewURL = "/templates/" + dirName + "/preview.png"
|
||||
template.PreviewURLThumb = "/templates/" + dirName + "/preview.png"
|
||||
template.Updated = templateDir.ModTime().Format("2006-01-02 15:04:05")
|
||||
template.Size = templateDir.Size()
|
||||
template.HSize = humanize.Bytes(uint64(template.Size))
|
||||
template.HUpdated = formatUpdated(template.Updated)
|
||||
readme, readErr := os.ReadFile(filepath.Join(util.DataDir, "templates", dirName, "README.md"))
|
||||
if nil != readErr {
|
||||
logging.LogWarnf("read install template README.md failed: %s", readErr)
|
||||
continue
|
||||
}
|
||||
template.README = gulu.Str.FromBytes(readme)
|
||||
|
||||
ret = append(ret, template)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func InstallTemplate(repoURL, repoHash, installPath string, systemID string) error {
|
||||
repoURLHash := repoURL + "@" + repoHash
|
||||
data, err := downloadPackage(repoURLHash, true, systemID)
|
||||
|
|
|
|||
|
|
@ -19,10 +19,12 @@ package bazaar
|
|||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/88250/gulu"
|
||||
"github.com/dustin/go-humanize"
|
||||
ants "github.com/panjf2000/ants/v2"
|
||||
"github.com/siyuan-note/httpclient"
|
||||
|
|
@ -58,27 +60,13 @@ type Theme struct {
|
|||
|
||||
func Themes() (ret []*Theme) {
|
||||
ret = []*Theme{}
|
||||
result, err := util.GetRhyResult(false)
|
||||
|
||||
pkgIndex, err := getPkgIndex("themes")
|
||||
if nil != err {
|
||||
return
|
||||
}
|
||||
|
||||
bazaarIndex := getBazaarIndex()
|
||||
bazaarHash := result["bazaar"].(string)
|
||||
result = map[string]interface{}{}
|
||||
request := httpclient.NewBrowserRequest()
|
||||
u := util.BazaarOSSServer + "/bazaar@" + bazaarHash + "/stage/themes.json"
|
||||
resp, reqErr := request.SetResult(&result).Get(u)
|
||||
if nil != reqErr {
|
||||
logging.LogErrorf("get community stage index [%s] failed: %s", u, reqErr)
|
||||
return
|
||||
}
|
||||
if 200 != resp.StatusCode {
|
||||
logging.LogErrorf("get community stage index [%s] failed: %d", u, resp.StatusCode)
|
||||
return
|
||||
}
|
||||
|
||||
repos := result["repos"].([]interface{})
|
||||
repos := pkgIndex["repos"].([]interface{})
|
||||
waitGroup := &sync.WaitGroup{}
|
||||
lock := &sync.Mutex{}
|
||||
p, _ := ants.NewPoolWithFunc(8, func(arg interface{}) {
|
||||
|
|
@ -95,7 +83,7 @@ func Themes() (ret []*Theme) {
|
|||
return
|
||||
}
|
||||
if 200 != innerResp.StatusCode {
|
||||
logging.LogErrorf("get bazaar package [%s] failed: %d", innerU, resp.StatusCode)
|
||||
logging.LogErrorf("get bazaar package [%s] failed: %d", innerU, innerResp.StatusCode)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -129,6 +117,67 @@ func Themes() (ret []*Theme) {
|
|||
return
|
||||
}
|
||||
|
||||
func InstalledThemes() (ret []*Theme) {
|
||||
dir, err := os.Open(util.ThemesPath)
|
||||
if nil != err {
|
||||
logging.LogWarnf("open appearance themes folder [%s] failed: %s", util.ThemesPath, err)
|
||||
return
|
||||
}
|
||||
themeDirs, err := dir.Readdir(-1)
|
||||
if nil != err {
|
||||
logging.LogWarnf("read appearance themes folder failed: %s", err)
|
||||
return
|
||||
}
|
||||
dir.Close()
|
||||
|
||||
pkgIndex, err := getPkgIndex("themes")
|
||||
if nil != err {
|
||||
return
|
||||
}
|
||||
|
||||
for _, themeDir := range themeDirs {
|
||||
if !themeDir.IsDir() {
|
||||
continue
|
||||
}
|
||||
dirName := themeDir.Name()
|
||||
if isBuiltInTheme(dirName) {
|
||||
continue
|
||||
}
|
||||
|
||||
themeConf, parseErr := ThemeJSON(dirName)
|
||||
if nil != parseErr || nil == themeConf {
|
||||
continue
|
||||
}
|
||||
|
||||
theme := &Theme{}
|
||||
theme.Name = themeConf["name"].(string)
|
||||
theme.Author = themeConf["author"].(string)
|
||||
theme.URL = themeConf["url"].(string)
|
||||
theme.Version = themeConf["version"].(string)
|
||||
theme.Modes = make([]string, 0, len(themeConf["modes"].([]interface{})))
|
||||
theme.RepoURL = theme.URL
|
||||
theme.PreviewURL = "/appearance/themes/" + dirName + "/preview.png"
|
||||
theme.PreviewURLThumb = "/appearance/themes/" + dirName + "/preview.png"
|
||||
theme.Updated = themeDir.ModTime().Format("2006-01-02 15:04:05")
|
||||
theme.Size = themeDir.Size()
|
||||
theme.HSize = humanize.Bytes(uint64(theme.Size))
|
||||
theme.HUpdated = formatUpdated(theme.Updated)
|
||||
readme, readErr := os.ReadFile(filepath.Join(util.ThemesPath, dirName, "README.md"))
|
||||
if nil != readErr {
|
||||
logging.LogWarnf("read install theme README.md failed: %s", readErr)
|
||||
continue
|
||||
}
|
||||
theme.README = gulu.Str.FromBytes(readme)
|
||||
theme.Outdated = isOutdatedPkg(theme.URL, theme.Version, pkgIndex)
|
||||
ret = append(ret, theme)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func isBuiltInTheme(dirName string) bool {
|
||||
return "daylight" == dirName || "midnight" == dirName
|
||||
}
|
||||
|
||||
func InstallTheme(repoURL, repoHash, installPath string, systemID string) error {
|
||||
repoURLHash := repoURL + "@" + repoHash
|
||||
data, err := downloadPackage(repoURLHash, true, systemID)
|
||||
|
|
|
|||
|
|
@ -57,27 +57,14 @@ type Widget struct {
|
|||
|
||||
func Widgets() (widgets []*Widget) {
|
||||
widgets = []*Widget{}
|
||||
result, err := util.GetRhyResult(false)
|
||||
|
||||
pkgIndex, err := getPkgIndex("widgets")
|
||||
if nil != err {
|
||||
return
|
||||
}
|
||||
|
||||
bazaarIndex := getBazaarIndex()
|
||||
bazaarHash := result["bazaar"].(string)
|
||||
result = map[string]interface{}{}
|
||||
request := httpclient.NewBrowserRequest()
|
||||
u := util.BazaarOSSServer + "/bazaar@" + bazaarHash + "/stage/widgets.json"
|
||||
resp, err := request.SetResult(&result).Get(u)
|
||||
if nil != err {
|
||||
logging.LogErrorf("get community stage index [%s] failed: %s", u, err)
|
||||
return
|
||||
}
|
||||
if 200 != resp.StatusCode {
|
||||
logging.LogErrorf("get community stage index [%s] failed: %d", u, resp.StatusCode)
|
||||
return
|
||||
}
|
||||
|
||||
repos := result["repos"].([]interface{})
|
||||
repos := pkgIndex["repos"].([]interface{})
|
||||
waitGroup := &sync.WaitGroup{}
|
||||
lock := &sync.Mutex{}
|
||||
p, _ := ants.NewPoolWithFunc(8, func(arg interface{}) {
|
||||
|
|
|
|||
|
|
@ -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.20220829155050-5c5d032f7b68
|
||||
github.com/88250/lute v1.7.5-0.20220901071335-8565d1e64571
|
||||
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
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ github.com/88250/go-sqlite3 v1.14.13-0.20220714142610-fbbda1ee84f5 h1:8HdZozCsXS
|
|||
github.com/88250/go-sqlite3 v1.14.13-0.20220714142610-fbbda1ee84f5/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/88250/gulu v1.2.3-0.20220720144315-065ef35ec583 h1:FhA/zJemLrbOYJpdMIMBezO5rGigQSdPR1kv+aztHfA=
|
||||
github.com/88250/gulu v1.2.3-0.20220720144315-065ef35ec583/go.mod h1:I1qBzsksFL2ciGSuqDE7R3XW4BUMrfDgOvSXEk7FsAI=
|
||||
github.com/88250/lute v1.7.5-0.20220829155050-5c5d032f7b68 h1:BSVqhd18YpBEECvek7lJu13qcmQGJgQwaiLrnsUyRvw=
|
||||
github.com/88250/lute v1.7.5-0.20220829155050-5c5d032f7b68/go.mod h1:Bdu9LRNjQhtL3TftbtpjIWTwDVAXoS7AD8QsZQPk7zo=
|
||||
github.com/88250/lute v1.7.5-0.20220901071335-8565d1e64571 h1:InniTKfj4OZjE0VFhLZmJT6PKGZQfqw6k06/Zvwh35c=
|
||||
github.com/88250/lute v1.7.5-0.20220901071335-8565d1e64571/go.mod h1:Bdu9LRNjQhtL3TftbtpjIWTwDVAXoS7AD8QsZQPk7zo=
|
||||
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=
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import (
|
|||
"github.com/88250/gulu"
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/siyuan-note/logging"
|
||||
"github.com/siyuan-note/siyuan/kernel/bazaar"
|
||||
"github.com/siyuan-note/siyuan/kernel/util"
|
||||
)
|
||||
|
||||
|
|
@ -115,8 +116,8 @@ func loadThemes() {
|
|||
continue
|
||||
}
|
||||
name := themeDir.Name()
|
||||
themeConf, err := themeJSON(name)
|
||||
if nil != err || nil == themeConf {
|
||||
themeConf, parseErr := bazaar.ThemeJSON(name)
|
||||
if nil != parseErr || nil == themeConf {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
@ -145,28 +146,6 @@ func loadThemes() {
|
|||
}
|
||||
}
|
||||
|
||||
func themeJSON(themeName string) (ret map[string]interface{}, err error) {
|
||||
p := filepath.Join(util.ThemesPath, themeName, "theme.json")
|
||||
if !gulu.File.IsExist(p) {
|
||||
err = os.ErrNotExist
|
||||
return
|
||||
}
|
||||
data, err := os.ReadFile(p)
|
||||
if nil != err {
|
||||
logging.LogErrorf("read theme.json [%s] failed: %s", p, err)
|
||||
return
|
||||
}
|
||||
if err = gulu.JSON.UnmarshalJSON(data, &ret); nil != err {
|
||||
logging.LogErrorf("parse theme.json [%s] failed: %s", p, err)
|
||||
return
|
||||
}
|
||||
if 5 > len(ret) {
|
||||
logging.LogWarnf("invalid theme.json [%s]", p)
|
||||
return nil, errors.New("invalid theme.json")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func iconJSON(iconName string) (ret map[string]interface{}, err error) {
|
||||
p := filepath.Join(util.IconsPath, iconName, "icon.json")
|
||||
if !gulu.File.IsExist(p) {
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ func BazaarThemes() (ret []*bazaar.Theme) {
|
|||
for _, theme := range ret {
|
||||
if installed == theme.Name {
|
||||
theme.Installed = true
|
||||
if themeConf, err := themeJSON(theme.Name); nil == err {
|
||||
if themeConf, err := bazaar.ThemeJSON(theme.Name); nil == err {
|
||||
theme.Outdated = theme.Version != themeConf["version"].(string)
|
||||
}
|
||||
theme.Current = theme.Name == Conf.Appearance.ThemeDark || theme.Name == Conf.Appearance.ThemeLight
|
||||
|
|
|
|||
|
|
@ -210,18 +210,22 @@ func ExportDocx(id, savePath string, removeAssets bool) (err error) {
|
|||
}
|
||||
|
||||
tmpDir := filepath.Join(util.TempDir, "export", gulu.Rand.String(7))
|
||||
if err = os.MkdirAll(tmpDir, 0755); nil != err {
|
||||
return
|
||||
}
|
||||
defer os.Remove(tmpDir)
|
||||
name, dom := ExportMarkdownHTML(id, tmpDir, true)
|
||||
name, content := ExportMarkdownHTML(id, tmpDir, true)
|
||||
|
||||
tmpDocxPath := filepath.Join(tmpDir, name+".docx")
|
||||
args := []string{ // pandoc -f html --resource-path=请从这里开始 请从这里开始\index.html -o test.docx
|
||||
"-f", "html",
|
||||
"-f", "html+tex_math_dollars",
|
||||
"--resource-path", tmpDir,
|
||||
"-o", tmpDocxPath,
|
||||
}
|
||||
|
||||
pandoc := exec.Command(Conf.Export.PandocBin, args...)
|
||||
util.CmdAttr(pandoc)
|
||||
pandoc.Stdin = bytes.NewBufferString(dom)
|
||||
pandoc.Stdin = bytes.NewBufferString(content)
|
||||
output, err := pandoc.CombinedOutput()
|
||||
if nil != err {
|
||||
logging.LogErrorf("export docx failed: %s", gulu.Str.FromBytes(output))
|
||||
|
|
@ -323,7 +327,14 @@ func ExportMarkdownHTML(id, savePath string, docx bool) (name, dom string) {
|
|||
}
|
||||
return ast.WalkContinue
|
||||
})
|
||||
dom = luteEngine.ProtylePreview(tree, luteEngine.RenderOptions)
|
||||
|
||||
if docx {
|
||||
renderer := render.NewProtyleExportDocxRenderer(tree, luteEngine.RenderOptions)
|
||||
output := renderer.Render()
|
||||
dom = gulu.Str.FromBytes(output)
|
||||
} else {
|
||||
dom = luteEngine.ProtylePreview(tree, luteEngine.RenderOptions)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -964,6 +975,7 @@ func renderExportMdMathBlockContent(r *render.FormatRenderer, node *ast.Node, en
|
|||
func renderExportMdInlineMathContent(r *render.FormatRenderer, node *ast.Node, entering bool) ast.WalkStatus {
|
||||
if entering {
|
||||
tokens := html.UnescapeHTML(node.Tokens)
|
||||
tokens = gulu.Str.ToBytes("a" + gulu.Str.FromBytes(tokens) + "b")
|
||||
r.Write(tokens)
|
||||
}
|
||||
return ast.WalkContinue
|
||||
|
|
|
|||
|
|
@ -606,6 +606,9 @@ func imgHtmlBlock2InlineImg(tree *parse.Tree) {
|
|||
logging.LogErrorf("parse html block [%s] failed: %s", n.Tokens, pErr)
|
||||
return ast.WalkContinue
|
||||
}
|
||||
if 1 > len(htmlNodes) {
|
||||
return ast.WalkContinue
|
||||
}
|
||||
if atom.Img == htmlNodes[0].DataAtom {
|
||||
imgHtmlBlocks[n] = htmlNodes[0]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,6 +97,10 @@ func serveEmojis(ginServer *gin.Engine) {
|
|||
ginServer.Static("/emojis/", filepath.Join(util.DataDir, "emojis"))
|
||||
}
|
||||
|
||||
func serveTemplates(ginServer *gin.Engine) {
|
||||
ginServer.Static("/templates/", filepath.Join(util.DataDir, "templates"))
|
||||
}
|
||||
|
||||
func serveAppearance(ginServer *gin.Engine) {
|
||||
siyuan := ginServer.Group("", model.CheckAuth)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue