From 156899cb44a8b863739ddc9256e09471d1ffbd5a Mon Sep 17 00:00:00 2001
From: Daniel <845765@qq.com>
Date: Thu, 9 Oct 2025 20:42:17 +0800
Subject: [PATCH 1/3] :art: Improve export of empty documents with subdocuments
https://github.com/siyuan-note/siyuan/issues/16040
Signed-off-by: Daniel <845765@qq.com>
---
kernel/model/export.go | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/kernel/model/export.go b/kernel/model/export.go
index 34ccac57a..b734689a5 100644
--- a/kernel/model/export.go
+++ b/kernel/model/export.go
@@ -2039,15 +2039,18 @@ func exportMarkdownContent(id, ext string, exportRefMode int, defBlockIDs []stri
return
}
- for c := tree.Root.FirstChild; nil != c; c = c.Next {
- if ast.NodeParagraph == c.Type {
- isEmpty = nil == c.FirstChild
- if !isEmpty {
+ refCount := sql.QueryRootChildrenRefCount(tree.ID)
+ if !Conf.Export.MarkdownYFM && 5 > len(tree.Root.KramdownIAL) && 1 > len(refCount) {
+ for c := tree.Root.FirstChild; nil != c; c = c.Next {
+ if ast.NodeParagraph == c.Type {
+ isEmpty = nil == c.FirstChild
+ if !isEmpty {
+ break
+ }
+ } else {
+ isEmpty = false
break
}
- } else {
- isEmpty = false
- break
}
}
From 4c0d3365f1ae4db41fce2546eca8830f4a73ed42 Mon Sep 17 00:00:00 2001
From: Daniel <845765@qq.com>
Date: Thu, 9 Oct 2025 22:48:22 +0800
Subject: [PATCH 2/3] :art: Improve export of empty documents with subdocuments
https://github.com/siyuan-note/siyuan/issues/16040
Signed-off-by: Daniel <845765@qq.com>
---
kernel/model/export.go | 2 +-
kernel/treenode/tree.go | 4 ++++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/kernel/model/export.go b/kernel/model/export.go
index b734689a5..a0c9716ef 100644
--- a/kernel/model/export.go
+++ b/kernel/model/export.go
@@ -2040,7 +2040,7 @@ func exportMarkdownContent(id, ext string, exportRefMode int, defBlockIDs []stri
}
refCount := sql.QueryRootChildrenRefCount(tree.ID)
- if !Conf.Export.MarkdownYFM && 5 > len(tree.Root.KramdownIAL) && 1 > len(refCount) {
+ if !Conf.Export.MarkdownYFM && treenode.ContainOnlyDefaultIAL(tree) && 1 > len(refCount) {
for c := tree.Root.FirstChild; nil != c; c = c.Next {
if ast.NodeParagraph == c.Type {
isEmpty = nil == c.FirstChild
diff --git a/kernel/treenode/tree.go b/kernel/treenode/tree.go
index f089c39ac..871a3d31e 100644
--- a/kernel/treenode/tree.go
+++ b/kernel/treenode/tree.go
@@ -125,3 +125,7 @@ func NewParagraph(id string) (ret *ast.Node) {
func NewSpanAnchor(id string) (ret *ast.Node) {
return &ast.Node{Type: ast.NodeInlineHTML, Tokens: []byte("")}
}
+
+func ContainOnlyDefaultIAL(tree *parse.Tree) bool {
+ return 5 > len(tree.Root.KramdownIAL)
+}
From 86431cc106fc4c845acb588b0d0931f79f55ca78 Mon Sep 17 00:00:00 2001
From: Daniel <845765@qq.com>
Date: Thu, 9 Oct 2025 23:01:21 +0800
Subject: [PATCH 3/3] :art: Change `Search asset content` and `Add watermark to
exported PDF or image` from paid features to free features
Signed-off-by: Daniel <845765@qq.com>
---
app/src/protyle/export/index.ts | 9 ---------
app/src/protyle/export/util.ts | 9 ---------
app/src/search/assets.ts | 16 ----------------
kernel/api/search.go | 5 -----
kernel/model/export.go | 4 ----
5 files changed, 43 deletions(-)
diff --git a/app/src/protyle/export/index.ts b/app/src/protyle/export/index.ts
index 3737e3d8d..81cb941cc 100644
--- a/app/src/protyle/export/index.ts
+++ b/app/src/protyle/export/index.ts
@@ -12,8 +12,6 @@ import {fetchPost, fetchSyncPost} from "../../util/fetch";
import {Dialog} from "../../dialog";
import {replaceLocalPath} from "../../editor/rename";
import {setStorageVal} from "../util/compatibility";
-import {isPaidUser} from "../../util/needSubscribe";
-import {getCloudURL} from "../../config/util/about";
import {getFrontend} from "../../util/functions";
const getPluginStyle = async () => {
@@ -269,7 +267,6 @@ const renderPDF = async (id: string) => {
-
${window.siyuan.languages._kernel[214].replaceAll("${accountServer}", getCloudURL(""))}
@@ -477,12 +474,6 @@ const renderPDF = async (id: string) => {
refreshPreview();
});
const watermarkElement = actionElement.querySelector('#watermark');
- watermarkElement.addEventListener('change', () => {
- if (watermarkElement.checked && ${!isPaidUser()}) {
- watermarkElement.nextElementSibling.style.display = "";
- watermarkElement.checked = false;
- }
- });
const refreshPreview = () => {
previewElement.innerHTML = '

'
fetchPost("/api/export/exportPreviewHTML", {
diff --git a/app/src/protyle/export/util.ts b/app/src/protyle/export/util.ts
index 69ed4e248..ab2ccdfa5 100644
--- a/app/src/protyle/export/util.ts
+++ b/app/src/protyle/export/util.ts
@@ -12,8 +12,6 @@ import {highlightRender} from "../render/highlightRender";
import {processRender} from "../util/processCode";
import {isIPhone, isSafari, openByMobile, setStorageVal} from "../util/compatibility";
import {useShell} from "../../util/pathName";
-import {isPaidUser} from "../../util/needSubscribe";
-import {getCloudURL} from "../../config/util/about";
export const afterExport = (exportPath: string, msgId: string) => {
/// #if !BROWSER
@@ -121,16 +119,9 @@ export const exportImage = (id: string) => {
const watermarkElement = (exportDialog.element.querySelector("#watermark") as HTMLInputElement);
watermarkElement.addEventListener("change", () => {
window.siyuan.storage[Constants.LOCAL_EXPORTIMG].watermark = watermarkElement.checked;
- if (watermarkElement.checked && !isPaidUser()) {
- watermarkElement.checked = false;
- showMessage(window.siyuan.languages._kernel[214].replaceAll("${accountServer}", getCloudURL("")));
- }
updateWatermark();
});
const updateWatermark = () => {
- if (!isPaidUser()) {
- return;
- }
const watermarkPreviewElement = exportDialog.element.querySelector(".export-img__watermark") as HTMLElement;
watermarkPreviewElement.innerHTML = "";
if (watermarkElement.checked) {
diff --git a/app/src/search/assets.ts b/app/src/search/assets.ts
index d754cc54b..01540c4db 100644
--- a/app/src/search/assets.ts
+++ b/app/src/search/assets.ts
@@ -8,10 +8,7 @@ import {genQueryHTML} from "./util";
import {MenuItem} from "../menus/Menu";
import {Dialog} from "../dialog";
import {addClearButton} from "../util/addClearButton";
-import {isPaidUser} from "../util/needSubscribe";
-import {showMessage} from "../dialog/message";
import {saveAssetKeyList} from "./toggleHistory";
-import {getCloudURL} from "../config/util/about";
export const openSearchAsset = (element: HTMLElement, isStick: boolean) => {
/// #if !MOBILE
@@ -165,15 +162,6 @@ export const openSearchAsset = (element: HTMLElement, isStick: boolean) => {
let inputTimeout: number;
export const assetInputEvent = (element: Element, localSearch?: ISearchAssetOption, page = 1) => {
const loadingElement = element.parentElement.querySelector(".fn__loading--top");
- if (!isPaidUser()) {
- loadingElement.classList.add("fn__none");
- element.querySelector(".search__drag")?.classList.add("fn__none");
- element.querySelector("#searchAssetPreview").classList.add("fn__none");
- element.querySelector("#searchAssetList").innerHTML = `
- ${window.siyuan.languages["_kernel"][214].replaceAll("${accountServer}", getCloudURL(""))}
-
`;
- return;
- }
loadingElement.classList.remove("fn__none");
clearTimeout(inputTimeout);
inputTimeout = window.setTimeout(() => {
@@ -449,10 +437,6 @@ export const assetMoreMenu = (target: Element, element: Element, cb: () => void)
iconHTML: "",
label: window.siyuan.languages.rebuildIndex,
click() {
- if (!isPaidUser()) {
- showMessage(window.siyuan.languages["_kernel"][214].replaceAll("${accountServer}", getCloudURL("")));
- return;
- }
element.parentElement.querySelector(".fn__loading--top").classList.remove("fn__none");
fetchPost("/api/asset/fullReindexAssetContent", {}, () => {
assetInputEvent(element, localData);
diff --git a/kernel/api/search.go b/kernel/api/search.go
index 0ea003394..39786db3c 100644
--- a/kernel/api/search.go
+++ b/kernel/api/search.go
@@ -88,11 +88,6 @@ func fullTextSearchAssetContent(c *gin.Context) {
return
}
- if !model.IsPaidUser() {
- ret.Code = 1
- return
- }
-
page, pageSize, query, types, method, orderBy := parseSearchAssetContentArgs(arg)
assetContents, matchedAssetCount, pageCount := model.FullTextSearchAssetContent(query, types, method, orderBy, page, pageSize)
ret.Data = map[string]interface{}{
diff --git a/kernel/model/export.go b/kernel/model/export.go
index a0c9716ef..d5e2f87c1 100644
--- a/kernel/model/export.go
+++ b/kernel/model/export.go
@@ -1110,10 +1110,6 @@ func processPDFWatermark(pdfCtx *model.Context, watermark bool) {
return
}
- if !IsPaidUser() {
- return
- }
-
mode := "text"
if gulu.File.IsExist(str) {
if ".pdf" == strings.ToLower(filepath.Ext(str)) {