@lancc/cmark 1.1.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/LICENSE +21 -21
- package/README.md +54 -82
- package/assets/abnfDiagram-WEYOIA3C-CKV_7Upb.js +1 -0
- package/assets/architectureDiagram-ZHVYKT53-BvLudDvk.js +1 -0
- package/assets/blockDiagram-RJAE7QA3--gzkMGi2.js +1 -0
- package/assets/c4Diagram-XDPPPE54-ByfRiJGR.js +1 -0
- package/assets/chunk-2E7WHVMD-TfbC_dmh.js +1 -0
- package/assets/chunk-2Q5K7J3B-0YJgChVo.js +1 -0
- package/assets/chunk-4EMNKR2T-DHoYW7g5.js +1 -0
- package/assets/chunk-55XCU76K-Cq25Yw_G.js +1 -0
- package/assets/chunk-5VM5RSS4-CJaRXFHK.js +1 -0
- package/assets/chunk-JWPE2WC7-BP2iXBhe.js +1 -0
- package/assets/chunk-VQ5W62QI-B95zur4F.js +1 -0
- package/assets/chunk-XXDRQBXY-Ct0MhvQo.js +1 -0
- package/assets/chunk-ZCHMQSOR-C5VhW-wL.js +2 -0
- package/assets/classDiagram-v2-4MYWR3UA-C1G-Vkj0.js +1 -0
- package/assets/cose-bilkent-JH36ORCC-qIQoIBv0.js +1 -0
- package/assets/cynefin-EF2NZ3EQ-CR1E3YiZ.js +1 -0
- package/assets/cynefinDiagram-WF24UDRP-DaJFvZ3b.js +1 -0
- package/assets/cytoscape.esm-SjxgSg6I.js +9 -0
- package/assets/dagre-NK4GIZVX-BFRQhpii.js +1 -0
- package/assets/diagram-CBK3MWTC-DlueL6XZ.js +1 -0
- package/assets/diagram-I5XIIV2D-bITyafYX.js +1 -0
- package/assets/diagram-ODIL2UCW-Dlb4hg_-.js +1 -0
- package/assets/diagram-PFBEJUXE-CRfen0O7.js +1 -0
- package/assets/diagram-RJA3I4VV-CK-FlhGV.js +1 -0
- package/assets/diagram-TYUNFSNR-DmgVsxqa.js +1 -0
- package/assets/ebnfDiagram-V4P3TTPT-B9KGI9eQ.js +1 -0
- package/assets/echarts-CytsvCdp.js +25 -0
- package/assets/elk-QONTBCTQ-VgDftvsU.js +1 -0
- package/assets/erDiagram-KYQIGQAA-DkpP7sS4.js +1 -0
- package/assets/flowDiagram-IUGLLWBU-CRXa9Kxy.js +1 -0
- package/assets/ganttDiagram-R7GPNTJY-Cu2I55Wb.js +1 -0
- package/assets/gitGraphDiagram-PDYL7XHY-CwSo663I.js +1 -0
- package/assets/graph-Dz7AM1Q5.js +1 -0
- package/assets/index-BJ-NdQc4.js +100 -0
- package/assets/index-eB_q_VA3.css +1 -0
- package/assets/infoDiagram-MVDRKAX5-D3Qknzuo.js +1 -0
- package/assets/ishikawaDiagram-HPEHV2GE-9qYT75tk.js +1 -0
- package/assets/journeyDiagram-BOSHW7O7-DeSrJg9o.js +1 -0
- package/assets/kanban-definition-FNSA4HC5-DINkB6G7.js +1 -0
- package/assets/katex-DN8cTsI3.js +1 -0
- package/assets/markdown-S2mWvoE-.js +5 -0
- package/assets/mermaid-T_6Ze_cT.js +7 -0
- package/assets/mindmap-definition-6OY57UG3-DW5hqiAe.js +1 -0
- package/assets/pegDiagram-ECIUJNBX-BWy_tkzy.js +1 -0
- package/assets/pieDiagram-GNMPY74T-CniJbr6l.js +1 -0
- package/assets/quadrantDiagram-D57K4MC3-BVnDJkCv.js +1 -0
- package/assets/railroadDiagram-Y72NRBL7-BNKZpJJb.js +1 -0
- package/assets/requirementDiagram-EQYSW5RA-BETipHj0.js +1 -0
- package/assets/sankeyDiagram-SY24JHO5-ByEYqT7T.js +1 -0
- package/assets/sequenceDiagram-BLEHNHQU-BqCJ2tKG.js +1 -0
- package/assets/sizeCapture-INFHLROL-DlhrWFj-.js +1 -0
- package/assets/stateDiagram-v2-A6IESKWZ-DJUBWLTP.js +1 -0
- package/assets/swimlanes-B3ENRKFQ-D7k7tF5U.js +1 -0
- package/assets/swimlanesDiagram-AYQRV4AK-DoQBgB9o.js +1 -0
- package/assets/timeline-definition-JXYKGLGB-BCNhwnn6.js +1 -0
- package/assets/usecaseDiagram-WPOLBNNX-DRa_Rgl3.js +1 -0
- package/assets/vennDiagram-Q3Y3IDCW-Ba2eaO68.js +1 -0
- package/assets/wardleyDiagram-IVAIDKWA-W_i9vzY-.js +1 -0
- package/assets/xychartDiagram-4URNHDU4-ByfaGjvc.js +1 -0
- package/export-file/github-markdown.css +549 -549
- package/export-file/index.html +32 -32
- package/index.html +4 -4
- package/logo.png +0 -0
- package/package.json +1 -1
- package/plugin.json +8 -218
- package/preload/branch-bar.js +44 -2
- package/preload/export-css.js +59 -0
- package/preload/git-panel.js +102 -23
- package/preload/git-service.js +99 -6
- package/preload/host.js +130 -0
- package/preload/remote-setup.js +425 -0
- package/preload/remote-wizard.js +330 -0
- package/preload/rename-note.js +4 -5
- package/preload/services.js +6 -15
- package/preload/settings-panel.js +468 -356
- package/preload/ws-prefs.js +55 -0
- package/preload.js +291 -6
- package/assets/abnfDiagram-WEYOIA3C-BgXsTF7a.js +0 -1
- package/assets/architectureDiagram-ZHVYKT53-BsCWa_qC.js +0 -36
- package/assets/blockDiagram-RJAE7QA3-wbIxEiYN.js +0 -140
- package/assets/c4Diagram-XDPPPE54-5zdyxFvA.js +0 -38
- package/assets/chunk-2E7WHVMD-F85Lca-i.js +0 -88
- package/assets/chunk-2Q5K7J3B-CjpAZ0OI.js +0 -1
- package/assets/chunk-4EMNKR2T-C8Kbh83c.js +0 -1
- package/assets/chunk-55XCU76K-BINcFiLN.js +0 -1
- package/assets/chunk-5VM5RSS4-Diy5h2LS.js +0 -15
- package/assets/chunk-JWPE2WC7-BXnjDdh1.js +0 -1
- package/assets/chunk-VQ5W62QI-BM7ZZo1I.js +0 -1
- package/assets/chunk-XXDRQBXY-CW8CjB1w.js +0 -1
- package/assets/chunk-ZCHMQSOR-C7ATz1L1.js +0 -2
- package/assets/classDiagram-v2-4MYWR3UA-CMoqNk-b.js +0 -217
- package/assets/cose-bilkent-JH36ORCC-6rqR5iJk.js +0 -1
- package/assets/cynefin-EF2NZ3EQ-DypLIJxl.js +0 -141
- package/assets/cynefinDiagram-WF24UDRP-8b2CEBlR.js +0 -62
- package/assets/cytoscape.esm-CjX6Hyah.js +0 -331
- package/assets/dagre-NK4GIZVX-Dv6vuUbR.js +0 -4
- package/assets/diagram-CBK3MWTC-DJgMDeYd.js +0 -24
- package/assets/diagram-I5XIIV2D-BB9cMoRW.js +0 -24
- package/assets/diagram-ODIL2UCW-BVcRtsdy.js +0 -30
- package/assets/diagram-PFBEJUXE-BbGSOtJx.js +0 -3
- package/assets/diagram-RJA3I4VV-CzkY_8Fo.js +0 -41
- package/assets/diagram-TYUNFSNR-YTl5QdfL.js +0 -200
- package/assets/ebnfDiagram-V4P3TTPT-COVjPAjE.js +0 -1
- package/assets/echarts-BAPDkhe3.js +0 -61
- package/assets/elk-QONTBCTQ-DHsjY8Z_.js +0 -27
- package/assets/erDiagram-KYQIGQAA-CUAbTUl1.js +0 -99
- package/assets/flowDiagram-IUGLLWBU-CWsiqTQC.js +0 -213
- package/assets/ganttDiagram-R7GPNTJY-DetBW0Wm.js +0 -292
- package/assets/gitGraphDiagram-PDYL7XHY-ByrdgJmw.js +0 -106
- package/assets/graph-D8UmR1vK.js +0 -1
- package/assets/index-BLONSItV.css +0 -1
- package/assets/index-Cz6qaZbV.js +0 -744
- package/assets/infoDiagram-MVDRKAX5-BM48fjhU.js +0 -2
- package/assets/ishikawaDiagram-HPEHV2GE-DtHYywHZ.js +0 -70
- package/assets/journeyDiagram-BOSHW7O7-DJ1LiRh3.js +0 -139
- package/assets/kanban-definition-FNSA4HC5-DPPt8pwJ.js +0 -89
- package/assets/katex-CQL9J12G.js +0 -257
- package/assets/markdown-DVehI1Sg.js +0 -314
- package/assets/mermaid-C_q9pug0.js +0 -312
- package/assets/mindmap-definition-6OY57UG3-zbqYOEY6.js +0 -98
- package/assets/pegDiagram-ECIUJNBX-e7QG7TMq.js +0 -1
- package/assets/pieDiagram-GNMPY74T-Duf6YP0N.js +0 -39
- package/assets/quadrantDiagram-D57K4MC3-B2eYoUUy.js +0 -7
- package/assets/railroadDiagram-Y72NRBL7-BWCzPcI_.js +0 -1
- package/assets/requirementDiagram-EQYSW5RA-HhPMEqB1.js +0 -84
- package/assets/sankeyDiagram-SY24JHO5-CMUTwFBB.js +0 -40
- package/assets/sequenceDiagram-BLEHNHQU-C9wR2ll7.js +0 -169
- package/assets/sizeCapture-INFHLROL-DXfz37S6.js +0 -1
- package/assets/stateDiagram-v2-A6IESKWZ-D_gtonhE.js +0 -291
- package/assets/swimlanes-B3ENRKFQ-DdJOuuMV.js +0 -1
- package/assets/swimlanesDiagram-AYQRV4AK-BWt3HxHV.js +0 -8
- package/assets/timeline-definition-JXYKGLGB-DQsdwJe-.js +0 -120
- package/assets/usecaseDiagram-WPOLBNNX-DTRyFq7d.js +0 -370
- package/assets/vennDiagram-Q3Y3IDCW-dihYszm0.js +0 -34
- package/assets/wardleyDiagram-IVAIDKWA-BoPpgYfK.js +0 -78
- package/assets/xychartDiagram-4URNHDU4-DoLjYxeB.js +0 -7
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ws-prefs.js —— 按工作区隔离的插件偏好
|
|
3
|
+
*
|
|
4
|
+
* 为什么需要:
|
|
5
|
+
* 全局 ~/.cmark-config.json 只适合放「所有工作区共用」的东西(当前工作区指针、主题)。
|
|
6
|
+
* Git 集成开关、远程凭据这类跟具体笔记库绑定的信息,必须按工作区分开存,
|
|
7
|
+
* 否则换一个工作区还沿用上一个库的开关和 token,会出现「绑了 A 库却拿 B 库凭据推送」。
|
|
8
|
+
*
|
|
9
|
+
* 存哪:
|
|
10
|
+
* %LOCALAPPDATA%\znotes-data\<工作区哈希>\prefs.json
|
|
11
|
+
* 哈希算法与 git-service 的 git-config.json 完全一致(md5(小写路径) 前 12 位),
|
|
12
|
+
* 保证同一个工作区的各类配置落在同一个目录里。
|
|
13
|
+
* 注意:绝不写进笔记仓库(不进 .cmark,也不进 git)。
|
|
14
|
+
*/
|
|
15
|
+
const fs = require('fs')
|
|
16
|
+
const os = require('os')
|
|
17
|
+
const path = require('path')
|
|
18
|
+
const crypto = require('crypto')
|
|
19
|
+
|
|
20
|
+
function hashOf (ws) {
|
|
21
|
+
// 与 git-service.js 保持一致:只做小写,不再做别的规范化,避免老配置目录变位置
|
|
22
|
+
return crypto.createHash('md5').update(String(ws || '').toLowerCase()).digest('hex').slice(0, 12)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function dirOf (ws) {
|
|
26
|
+
const base = process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local')
|
|
27
|
+
return path.join(base, 'znotes-data', hashOf(ws))
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function fileOf (ws) {
|
|
31
|
+
return path.join(dirOf(ws), 'prefs.json')
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function read (ws) {
|
|
35
|
+
if (!ws) return {}
|
|
36
|
+
try {
|
|
37
|
+
return JSON.parse(fs.readFileSync(fileOf(ws), 'utf8')) || {}
|
|
38
|
+
} catch (e) {
|
|
39
|
+
return {}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function patch (ws, obj) {
|
|
44
|
+
if (!ws) return { ok: false, message: '工作区为空' }
|
|
45
|
+
const next = Object.assign({}, read(ws), obj || {})
|
|
46
|
+
try {
|
|
47
|
+
fs.mkdirSync(dirOf(ws), { recursive: true })
|
|
48
|
+
fs.writeFileSync(fileOf(ws), JSON.stringify(next, null, 2), 'utf8')
|
|
49
|
+
return { ok: true, data: next }
|
|
50
|
+
} catch (e) {
|
|
51
|
+
return { ok: false, message: '偏好保存失败:' + e.message }
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
module.exports = { hashOf, dirOf, fileOf, read, patch }
|
package/preload.js
CHANGED
|
@@ -12,8 +12,22 @@
|
|
|
12
12
|
*
|
|
13
13
|
* 另加 window.__CMARK 作为本版本新增的控制面(配置读写、选目录、重扫)。
|
|
14
14
|
*/
|
|
15
|
+
// 宿主适配必须在一切之前:uTools 只注入 window.utools,ZTools 只注入 window.ztools,
|
|
16
|
+
// 补齐之后下面的代码才能统一用 window.ztools.xxx(两套 API 名字一致)
|
|
17
|
+
try { require('./preload/host').applyHostShim() } catch (e) {}
|
|
18
|
+
|
|
15
19
|
const path = require('path')
|
|
20
|
+
|
|
21
|
+
/** 启动期模块挂载失败时记一笔,方便用户/开发者直接在控制台看原因 */
|
|
22
|
+
function bootError(label, err) {
|
|
23
|
+
try {
|
|
24
|
+
window.__CMARK_BOOT_ERRORS = (window.__CMARK_BOOT_ERRORS || []).concat(
|
|
25
|
+
label + ': ' + ((err && err.stack) || (err && err.message) || String(err))
|
|
26
|
+
)
|
|
27
|
+
} catch (e) {}
|
|
28
|
+
}
|
|
16
29
|
const fs = require('fs')
|
|
30
|
+
const { exportDocCss, exportDocColors } = require('./preload/export-css')
|
|
17
31
|
const os = require('os')
|
|
18
32
|
|
|
19
33
|
const CFG_PATH = path.join(os.homedir(), '.cmark-config.json')
|
|
@@ -65,6 +79,116 @@ function saveConfig(patch) {
|
|
|
65
79
|
|
|
66
80
|
let config = loadConfig()
|
|
67
81
|
|
|
82
|
+
/* ---------------- 主题:light / dark / system ----------------
|
|
83
|
+
* 用户在设置里选,配置存在 ~/.cmark-config.json 的 theme 字段。
|
|
84
|
+
* 这里在 document-start 阶段就把 data-theme 写到 <html>,
|
|
85
|
+
* 避免首帧先渲染浅色再跳深色。
|
|
86
|
+
*/
|
|
87
|
+
const THEME_MODES = ['light', 'dark', 'system']
|
|
88
|
+
|
|
89
|
+
function themeMode () {
|
|
90
|
+
const m = (config || {}).theme
|
|
91
|
+
return THEME_MODES.indexOf(m) >= 0 ? m : 'system'
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function resolveTheme (mode) {
|
|
95
|
+
if (mode === 'light' || mode === 'dark') return mode
|
|
96
|
+
// system:优先跟随宿主(ZTools/uTools 的主题设置,而宿主自己也可以设为跟随系统)。
|
|
97
|
+
// 为什么不用 prefers-color-scheme:宿主的标题栏是它自己的 UI,颜色由宿主的主题决定,
|
|
98
|
+
// 插件改不了;只有让「跟随」这一档跟宿主同源,插件页面和顶部那条才不会一深一浅。
|
|
99
|
+
// preload 跑在 document-start,宿主可能还没注入 window.ztools(host shim 会先给 no-op),
|
|
100
|
+
// 此时拿到的是 undefined,必须回退到系统媒体查询。
|
|
101
|
+
try {
|
|
102
|
+
const z = window.ztools
|
|
103
|
+
const v = z && typeof z.isDarkColors === 'function' ? z.isDarkColors() : undefined
|
|
104
|
+
if (typeof v === 'boolean') return v ? 'dark' : 'light'
|
|
105
|
+
} catch (e) {}
|
|
106
|
+
try {
|
|
107
|
+
return typeof matchMedia === 'function' && matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
|
|
108
|
+
} catch (e) {
|
|
109
|
+
return 'light'
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
let themeRetryArmed = false
|
|
114
|
+
|
|
115
|
+
function applyTheme () {
|
|
116
|
+
const mode = themeMode()
|
|
117
|
+
const resolved = resolveTheme(mode)
|
|
118
|
+
let applied = false
|
|
119
|
+
try {
|
|
120
|
+
const el = document && document.documentElement
|
|
121
|
+
if (el) {
|
|
122
|
+
el.setAttribute('data-theme', resolved)
|
|
123
|
+
el.setAttribute('data-theme-mode', mode)
|
|
124
|
+
el.style.colorScheme = resolved
|
|
125
|
+
applied = true
|
|
126
|
+
}
|
|
127
|
+
} catch (e) {}
|
|
128
|
+
// document-start 阶段 <html> 可能还不存在(页面重载时尤其明显):
|
|
129
|
+
// 之前这里静默失败后不再重试,结果 data-theme 永远没写上,
|
|
130
|
+
// 界面回退浅色,而设置面板读配置仍显示「深色」——两边对不上。
|
|
131
|
+
if (!applied && !themeRetryArmed) {
|
|
132
|
+
themeRetryArmed = true
|
|
133
|
+
try {
|
|
134
|
+
if (document && typeof document.addEventListener === 'function') {
|
|
135
|
+
document.addEventListener('DOMContentLoaded', function () { themeRetryArmed = false; applyTheme() }, { once: true })
|
|
136
|
+
}
|
|
137
|
+
} catch (e) {}
|
|
138
|
+
setTimeout(function () { themeRetryArmed = false; try { applyTheme() } catch (e) {} }, 80)
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
if (window && typeof window.dispatchEvent === 'function') {
|
|
142
|
+
window.dispatchEvent(new CustomEvent('cmark-theme', { detail: { mode: mode, resolved: resolved } }))
|
|
143
|
+
}
|
|
144
|
+
} catch (e) {}
|
|
145
|
+
return { mode: mode, resolved: resolved }
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const themeApi = {
|
|
149
|
+
get: function () { return { mode: themeMode(), resolved: resolveTheme(themeMode()) } },
|
|
150
|
+
set: function (mode) {
|
|
151
|
+
if (THEME_MODES.indexOf(mode) < 0) mode = 'system'
|
|
152
|
+
config = saveConfig({ theme: mode })
|
|
153
|
+
return applyTheme()
|
|
154
|
+
},
|
|
155
|
+
apply: applyTheme
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
try {
|
|
159
|
+
if (window) window.__CMARK_THEME = themeApi
|
|
160
|
+
} catch (e) {}
|
|
161
|
+
|
|
162
|
+
applyTheme()
|
|
163
|
+
|
|
164
|
+
// 跟随系统时,系统深浅色切换要实时生效
|
|
165
|
+
try {
|
|
166
|
+
const mq = matchMedia('(prefers-color-scheme: dark)')
|
|
167
|
+
const onChange = function () { if (themeMode() === 'system') applyTheme() }
|
|
168
|
+
if (mq.addEventListener) mq.addEventListener('change', onChange)
|
|
169
|
+
else if (mq.addListener) mq.addListener(onChange)
|
|
170
|
+
} catch (e) {}
|
|
171
|
+
|
|
172
|
+
// 「跟随」这一档还要跟宿主的主题变化走:用户在 ZTools 里切浅/深时,
|
|
173
|
+
// 插件页面要跟着换,否则会出现「顶部变了、页面没变」的反向不一致。
|
|
174
|
+
// preload 早期宿主可能还没注入,所以延后一段时间再注册一次。
|
|
175
|
+
function watchHostTheme () {
|
|
176
|
+
try {
|
|
177
|
+
const z = window.ztools
|
|
178
|
+
if (!z || typeof z.onThemeChange !== 'function') return false
|
|
179
|
+
z.onThemeChange(function () { if (themeMode() === 'system') applyTheme() })
|
|
180
|
+
return true
|
|
181
|
+
} catch (e) {
|
|
182
|
+
return false
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (!watchHostTheme()) {
|
|
186
|
+
setTimeout(watchHostTheme, 600)
|
|
187
|
+
setTimeout(watchHostTheme, 2000)
|
|
188
|
+
}
|
|
189
|
+
// 宿主注入晚于首帧时,system 档的首帧可能按系统色算错了,补算一次
|
|
190
|
+
setTimeout(function () { if (themeMode() === 'system') applyTheme() }, 300)
|
|
191
|
+
|
|
68
192
|
// 工作区未设置或不存在时,退到 ~/Documents/CMark,不弹任何框
|
|
69
193
|
let workspace = config.workspace
|
|
70
194
|
if (!workspace || !fs.existsSync(workspace)) {
|
|
@@ -75,12 +199,48 @@ if (!workspace || !fs.existsSync(workspace)) {
|
|
|
75
199
|
} catch (e) {}
|
|
76
200
|
}
|
|
77
201
|
|
|
202
|
+
/* ---------------- Git 集成开关 ----------------
|
|
203
|
+
* 存配置文件而不是 localStorage:插件跑在 file:// origin 下,localStorage 可能直接抛 SecurityError
|
|
204
|
+
* (被 try/catch 静默吞掉,表现就是「开关点了没生效、状态读不到」)。
|
|
205
|
+
* 这里给渲染层与注入脚本一个同步读写的入口,set 时广播事件让各界面同步。
|
|
206
|
+
*/
|
|
207
|
+
const wsPrefs = require('./preload/ws-prefs.js')
|
|
208
|
+
|
|
209
|
+
function currentWs () {
|
|
210
|
+
try {
|
|
211
|
+
if (config && config.workspace) return config.workspace
|
|
212
|
+
// workspace 在下方才声明;这里用 typeof 兜住 TDZ,读取时它通常已初始化
|
|
213
|
+
return typeof workspace === 'string' ? workspace : ''
|
|
214
|
+
} catch (e) { return '' }
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const gitApi = {
|
|
218
|
+
// 返回 true / false / null(null = 该工作区还没设置过)
|
|
219
|
+
// 存在「按工作区」的 prefs.json 里:换笔记库不会沿用上一个库的开关
|
|
220
|
+
get: function () {
|
|
221
|
+
const p = wsPrefs.read(currentWs())
|
|
222
|
+
if (typeof p.gitEnabled === 'boolean') return p.gitEnabled
|
|
223
|
+
// 兼容上一版写在全局配置里的值
|
|
224
|
+
if (config && typeof config.gitEnabled === 'boolean') return config.gitEnabled
|
|
225
|
+
return null
|
|
226
|
+
},
|
|
227
|
+
set: function (on) {
|
|
228
|
+
wsPrefs.patch(currentWs(), { gitEnabled: !!on })
|
|
229
|
+
try {
|
|
230
|
+
if (window) window.dispatchEvent(new CustomEvent('cmark-git-changed', { detail: { enabled: !!on } }))
|
|
231
|
+
} catch (e) {}
|
|
232
|
+
return !!on
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
try { if (window) window.__CMARK_GIT = gitApi } catch (e) {}
|
|
236
|
+
|
|
78
237
|
/* ---------------- 挂载数据层 ---------------- */
|
|
79
238
|
// ndb.js 的第二个参数是"能读到 workspace 字段的 JSON 路径"
|
|
80
239
|
try {
|
|
81
240
|
require('./preload/ndb.js')(window, CFG_PATH)
|
|
82
241
|
} catch (e) {
|
|
83
242
|
console.error('[cmark] ndb 挂载失败', e)
|
|
243
|
+
bootError('ndb', e)
|
|
84
244
|
}
|
|
85
245
|
|
|
86
246
|
/* ---------------- 挂载版本控制 ---------------- */
|
|
@@ -88,6 +248,7 @@ try {
|
|
|
88
248
|
require('./preload/git-service.js')(window, workspace)
|
|
89
249
|
} catch (e) {
|
|
90
250
|
console.error('[cmark] git 服务挂载失败', e)
|
|
251
|
+
bootError('git-service', e)
|
|
91
252
|
}
|
|
92
253
|
|
|
93
254
|
/* ---------------- 挂载导出/附件/剪贴板 ---------------- */
|
|
@@ -95,6 +256,7 @@ try {
|
|
|
95
256
|
window.services = require('./preload/services.js')(window)
|
|
96
257
|
} catch (e) {
|
|
97
258
|
console.error('[cmark] services 挂载失败', e)
|
|
259
|
+
bootError('services', e)
|
|
98
260
|
window.services = {}
|
|
99
261
|
}
|
|
100
262
|
|
|
@@ -151,18 +313,35 @@ try {
|
|
|
151
313
|
require('./preload/git-panel.js')(window, workspace)
|
|
152
314
|
} catch (e) {
|
|
153
315
|
console.error('[cmark] git-panel 挂载失败', e)
|
|
316
|
+
bootError('git-panel', e)
|
|
154
317
|
}
|
|
155
318
|
|
|
319
|
+
// 每个模块单独 try:之前三个挤在一个 try 里,前面任一个抛错,设置面板就整块不挂载,
|
|
320
|
+
// 表现就是「点设置没反应」(uTools 里尤其容易踩到)。
|
|
321
|
+
try {
|
|
322
|
+
require('./preload/remote-setup.js')(window)
|
|
323
|
+
} catch (e) {
|
|
324
|
+
console.error('[cmark] remote-setup 挂载失败', e)
|
|
325
|
+
bootError('remote-setup', e)
|
|
326
|
+
}
|
|
327
|
+
try {
|
|
328
|
+
require('./preload/remote-wizard.js')(window)
|
|
329
|
+
} catch (e) {
|
|
330
|
+
console.error('[cmark] remote-wizard 挂载失败', e)
|
|
331
|
+
bootError('remote-wizard', e)
|
|
332
|
+
}
|
|
156
333
|
try {
|
|
157
334
|
require('./preload/settings-panel.js')(window)
|
|
158
335
|
} catch (e) {
|
|
159
336
|
console.error('[cmark] settings-panel 挂载失败', e)
|
|
337
|
+
bootError('settings-panel', e)
|
|
160
338
|
}
|
|
161
339
|
|
|
162
340
|
try {
|
|
163
341
|
require('./preload/rename-note.js')(window, window.__znotesFindInstance)
|
|
164
342
|
} catch (e) {
|
|
165
343
|
console.error('[cmark] rename-note 挂载失败', e)
|
|
344
|
+
bootError('rename-note', e)
|
|
166
345
|
}
|
|
167
346
|
|
|
168
347
|
/* ---------------- 控制面 ---------------- */
|
|
@@ -223,7 +402,7 @@ window.__CMARK = {
|
|
|
223
402
|
return this._writeNoteFile(dir, name, content, attachments || [], 'md', false)
|
|
224
403
|
},
|
|
225
404
|
|
|
226
|
-
writeHtmlFile(dir, name, html, attachments, withKatex, selfContained) {
|
|
405
|
+
writeHtmlFile(dir, name, html, attachments, withKatex, selfContained, theme) {
|
|
227
406
|
let css = ''
|
|
228
407
|
// 自包含快照(每个元素都内联了 computed style)不能再套 github-markdown.css,
|
|
229
408
|
// 那套样式会覆盖内联结果,导出的东西又和编辑区不一样了
|
|
@@ -236,10 +415,10 @@ window.__CMARK = {
|
|
|
236
415
|
} catch (e) {}
|
|
237
416
|
}
|
|
238
417
|
const katexLink = withKatex ? '<link rel="stylesheet" href="./katex.min.css">' : ''
|
|
418
|
+
// 导出跟随当前主题;selfContained 快照已内联深/浅色值,壳背景必须匹配,
|
|
419
|
+
// 否则深色文字配白底几乎不可读
|
|
239
420
|
const full = '<!doctype html>\n<html>\n<head>\n<meta charset="utf-8"/>\n<title>' + (name || '') + '</title>\n' +
|
|
240
|
-
katexLink + '\n<style>\
|
|
241
|
-
'.markdown-body { box-sizing: border-box; min-width: 200px; max-width: 980px; margin: 0 auto; padding: 45px; }\n' +
|
|
242
|
-
'@media (max-width: 767px) { .markdown-body { padding: 15px; } }\n' + css + '\n</style>\n</head>\n<body>\n' +
|
|
421
|
+
katexLink + '\n<style>\n' + exportDocCss(theme) + '\n' + css + '\n</style>\n</head>\n<body>\n' +
|
|
243
422
|
'<article class="markdown-body">\n' + String(html || '').trim() + '\n</article>\n</body>\n</html>'
|
|
244
423
|
const extra = Array.isArray(attachments) ? attachments.slice() : []
|
|
245
424
|
if (withKatex) {
|
|
@@ -251,7 +430,7 @@ window.__CMARK = {
|
|
|
251
430
|
},
|
|
252
431
|
|
|
253
432
|
/** 用隐藏窗口渲染后截图/打印成 PDF(V1.0.0 的做法) */
|
|
254
|
-
exportFile(type, html, css, cb, outDir) {
|
|
433
|
+
exportFile(type, html, css, cb, outDir, theme) {
|
|
255
434
|
if (!window.ztools || typeof window.ztools.createBrowserWindow !== 'function') {
|
|
256
435
|
cb(new Error('当前宿主没有 createBrowserWindow,无法导出 ' + type))
|
|
257
436
|
return
|
|
@@ -278,7 +457,30 @@ window.__CMARK = {
|
|
|
278
457
|
try {
|
|
279
458
|
let buf
|
|
280
459
|
await new Promise((r) => setTimeout(r, 50))
|
|
281
|
-
|
|
460
|
+
// Electron 的 insertCSS 会插到 <head> 最前面,被 export-file/index.html
|
|
461
|
+
// 自带的 background:#fff 覆盖(深色导出曾经导出白底)。改成把 <style>
|
|
462
|
+
// 追加到 body 末尾 + 直接内联背景,一定压得住。
|
|
463
|
+
const colors = exportDocColors(theme)
|
|
464
|
+
await win.webContents.executeJavaScript(
|
|
465
|
+
'(() => {' +
|
|
466
|
+
// export-file/index.html 会加载 github-markdown.css(浅色配色),
|
|
467
|
+
// 它的 .markdown-body / td / blockquote 规则特异性比我们的高,
|
|
468
|
+
// 深色导出会出现「深底 + 深字」和「白底表格」。直接禁用它,
|
|
469
|
+
// 全部改用 exportDocCss 这套随主题的样式。
|
|
470
|
+
' Array.from(document.querySelectorAll("link[rel=stylesheet]")).forEach(function (l) {' +
|
|
471
|
+
' if (l.href && l.href.indexOf("github-markdown") >= 0) l.disabled = true;' +
|
|
472
|
+
' });' +
|
|
473
|
+
' const css = ' + JSON.stringify(exportDocCss(theme) + '\n' + (css || '')) + ';' +
|
|
474
|
+
' const st = document.createElement("style");' +
|
|
475
|
+
' st.id = "__cmark-export-theme";' +
|
|
476
|
+
' st.textContent = css;' +
|
|
477
|
+
' document.body.appendChild(st);' +
|
|
478
|
+
' document.documentElement.style.background = ' + JSON.stringify(colors.bg) + ';' +
|
|
479
|
+
' document.body.style.background = ' + JSON.stringify(colors.bg) + ';' +
|
|
480
|
+
' document.body.style.color = ' + JSON.stringify(colors.fg) + ';' +
|
|
481
|
+
' return "ok";' +
|
|
482
|
+
'})()'
|
|
483
|
+
)
|
|
282
484
|
await win.webContents.executeJavaScript(
|
|
283
485
|
'document.querySelector(".markdown-body").innerHTML = ' + JSON.stringify(String(html || ''))
|
|
284
486
|
)
|
|
@@ -364,6 +566,85 @@ window.__CMARK = {
|
|
|
364
566
|
})
|
|
365
567
|
},
|
|
366
568
|
|
|
569
|
+
/**
|
|
570
|
+
* 工作区(仓库根)。
|
|
571
|
+
* 语义:工作区永远是 git 仓库根,笔记可以放在它下面的任意子目录(甚至就是根)。
|
|
572
|
+
* 没显式配置时回退到已探测的仓库根,再回退到当前笔记目录(兼容老数据)。
|
|
573
|
+
*/
|
|
574
|
+
repoDir() {
|
|
575
|
+
if (config && config.repoDir) return config.repoDir
|
|
576
|
+
try {
|
|
577
|
+
const st = window.__znotesGit && window.__znotesGit.inspect ? window.__znotesGit.inspect() : null
|
|
578
|
+
if (st && st.repoRoot) return st.repoRoot
|
|
579
|
+
} catch (e) {}
|
|
580
|
+
return workspace
|
|
581
|
+
},
|
|
582
|
+
|
|
583
|
+
/** 修改工作区(仓库根):只校验可写,不搬任何文件 */
|
|
584
|
+
pickRepoDir() {
|
|
585
|
+
let dir
|
|
586
|
+
try {
|
|
587
|
+
dir = window.ztools.showOpenDialog({
|
|
588
|
+
title: '选择工作区目录(git 仓库根)',
|
|
589
|
+
defaultPath: this.repoDir(),
|
|
590
|
+
properties: ['openDirectory', 'createDirectory'],
|
|
591
|
+
})
|
|
592
|
+
} catch (e) {
|
|
593
|
+
return { ok: false, message: '打开目录选择器失败:' + e.message }
|
|
594
|
+
}
|
|
595
|
+
if (!dir) return { ok: false, canceled: true }
|
|
596
|
+
if (Array.isArray(dir)) dir = dir[0]
|
|
597
|
+
try {
|
|
598
|
+
const probe = path.join(dir, '.cmark-write-test')
|
|
599
|
+
fs.writeFileSync(probe, 'ok')
|
|
600
|
+
fs.unlinkSync(probe)
|
|
601
|
+
} catch (e) {
|
|
602
|
+
return { ok: false, message: '这个目录不可写,请换一个' }
|
|
603
|
+
}
|
|
604
|
+
config = saveConfig({ repoDir: dir })
|
|
605
|
+
// 原来的笔记目录不在新工作区里(或没设置)→ 直接落到工作区根
|
|
606
|
+
const ws = config.workspace || workspace
|
|
607
|
+
let rel = ''
|
|
608
|
+
try { rel = path.relative(dir, ws) } catch (e) { rel = '..' }
|
|
609
|
+
if (!ws || rel.startsWith('..') || path.isAbsolute(rel)) {
|
|
610
|
+
workspace = dir
|
|
611
|
+
config = saveConfig({ workspace: dir, initialized: true })
|
|
612
|
+
}
|
|
613
|
+
return { ok: true, repoDir: dir, workspace: workspace, needReload: true }
|
|
614
|
+
},
|
|
615
|
+
|
|
616
|
+
/** 选择笔记目录:必须落在工作区(仓库根)之内,可以为根本身 */
|
|
617
|
+
pickNotesDir() {
|
|
618
|
+
const root = this.repoDir()
|
|
619
|
+
let dir
|
|
620
|
+
try {
|
|
621
|
+
dir = window.ztools.showOpenDialog({
|
|
622
|
+
title: '选择笔记目录(工作区内的子目录)',
|
|
623
|
+
defaultPath: root || workspace,
|
|
624
|
+
properties: ['openDirectory', 'createDirectory'],
|
|
625
|
+
})
|
|
626
|
+
} catch (e) {
|
|
627
|
+
return { ok: false, message: '打开目录选择器失败:' + e.message }
|
|
628
|
+
}
|
|
629
|
+
if (!dir) return { ok: false, canceled: true }
|
|
630
|
+
if (Array.isArray(dir)) dir = dir[0]
|
|
631
|
+
let rel = ''
|
|
632
|
+
try { rel = path.relative(root || dir, dir) } catch (e) { rel = '..' }
|
|
633
|
+
if (rel.startsWith('..') || path.isAbsolute(rel)) {
|
|
634
|
+
return { ok: false, message: '笔记目录必须在工作区(' + (root || '未设置') + ')之内' }
|
|
635
|
+
}
|
|
636
|
+
try {
|
|
637
|
+
const probe = path.join(dir, '.cmark-write-test')
|
|
638
|
+
fs.writeFileSync(probe, 'ok')
|
|
639
|
+
fs.unlinkSync(probe)
|
|
640
|
+
} catch (e) {
|
|
641
|
+
return { ok: false, message: '这个目录不可写,请换一个' }
|
|
642
|
+
}
|
|
643
|
+
workspace = dir
|
|
644
|
+
config = saveConfig({ workspace: dir, initialized: true })
|
|
645
|
+
return { ok: true, workspace: dir, noteRel: rel, needReload: true }
|
|
646
|
+
},
|
|
647
|
+
|
|
367
648
|
/** 更换工作区:只校验可写,不搬任何文件 */
|
|
368
649
|
pickWorkspace() {
|
|
369
650
|
let dir
|
|
@@ -1431,6 +1712,10 @@ try {
|
|
|
1431
1712
|
* ZTools 工具接口(对应 plugin.json 里的 tools 段)
|
|
1432
1713
|
* AI 侧通过这些工具读写笔记、把 Markdown 渲染成图片/PDF
|
|
1433
1714
|
* ================================================================== */
|
|
1715
|
+
// MCP 工具注册(ZTools 专有)。
|
|
1716
|
+
// plugin.json 里的 tools 声明已移除:插件本身不需要 MCP —— 其他 AI 直接读写磁盘上的 .md 即可。
|
|
1717
|
+
// 代码保留,若将来要恢复 MCP,把 tools 声明加回 plugin.json 就能生效;
|
|
1718
|
+
// uTools 没有 registerTool,这里的 return 会让它在 uTools 下自动跳过。
|
|
1434
1719
|
;(function registerTools() {
|
|
1435
1720
|
const z = window.ztools
|
|
1436
1721
|
if (!z || typeof z.registerTool !== 'function') return
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{g as p,r as u,d as a}from"./chunk-2E7WHVMD-F85Lca-i.js";import{p as f}from"./chunk-JWPE2WC7-BXnjDdh1.js";import{_ as n,l as o}from"./mermaid-C_q9pug0.js";import{M as c,b as d}from"./cynefin-EF2NZ3EQ-DypLIJxl.js";import"./markdown-DVehI1Sg.js";var v=d().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),l=t?parseInt(t,10):0,m=s?parseInt(s,10):1/0;return{min:l,max:m}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new c(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},B={parser:R,db:a,renderer:u,styles:p};export{B as diagram};
|