@sugarat/theme 0.5.10 → 0.5.12-beta.0

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/node.mjs CHANGED
@@ -9,168 +9,178 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
9
9
  // src/utils/node/mdPlugins.ts
10
10
  import { createRequire } from "module";
11
11
 
12
- // ../../node_modules/.pnpm/vitepress-plugin-tabs@0.2.0_vitepress@2.0.0-alpha.15_@types+node@24.5.2_async-validator_99dc32d207803fc3e59dad002dbf4f6a/node_modules/vitepress-plugin-tabs/dist/index.js
13
- var tabsMarker = "=tabs";
14
- var tabsMarkerLen = tabsMarker.length;
15
- var ruleBlockTabs = (state, startLine, endLine, silent) => {
16
- if (state.sCount[startLine] - state.blkIndent >= 4) {
17
- return false;
12
+ // ../../node_modules/.pnpm/vitepress-plugin-tabs@0.7.3_vitepress@2.0.0-alpha.15_@types+node@24.5.2_async-validator_99255ebfe5ccbf71b0568b407a8fdeff/node_modules/vitepress-plugin-tabs/dist/node/index.js
13
+ function container_plugin(md, name, options) {
14
+ function validateDefault(params) {
15
+ return params.trim().split(" ", 2)[0] === name;
16
+ }
17
+ function renderDefault(tokens, idx, _options, env, slf) {
18
+ if (tokens[idx].nesting === 1)
19
+ tokens[idx].attrJoin("class", name);
20
+ return slf.renderToken(tokens, idx, _options, env, slf);
21
+ }
22
+ options = options || {};
23
+ const min_markers = 3;
24
+ const marker_str = options.marker || ":";
25
+ const marker_char = marker_str.charCodeAt(0);
26
+ const marker_len = marker_str.length;
27
+ const validate = options.validate || validateDefault;
28
+ const render = options.render || renderDefault;
29
+ function container(state, startLine, endLine, silent) {
30
+ let pos;
31
+ let auto_closed = false;
32
+ let start = state.bMarks[startLine] + state.tShift[startLine];
33
+ let max = state.eMarks[startLine];
34
+ if (marker_char !== state.src.charCodeAt(start))
35
+ return false;
36
+ for (pos = start + 1; pos <= max; pos++)
37
+ if (marker_str[(pos - start) % marker_len] !== state.src[pos])
38
+ break;
39
+ const marker_count = Math.floor((pos - start) / marker_len);
40
+ if (marker_count < min_markers)
41
+ return false;
42
+ pos -= (pos - start) % marker_len;
43
+ const markup = state.src.slice(start, pos);
44
+ const params = state.src.slice(pos, max);
45
+ if (!validate(params, markup))
46
+ return false;
47
+ if (silent)
48
+ return true;
49
+ let nextLine = startLine;
50
+ for (; ; ) {
51
+ nextLine++;
52
+ if (nextLine >= endLine)
53
+ break;
54
+ start = state.bMarks[nextLine] + state.tShift[nextLine];
55
+ max = state.eMarks[nextLine];
56
+ if (start < max && state.sCount[nextLine] < state.blkIndent)
57
+ break;
58
+ if (marker_char !== state.src.charCodeAt(start))
59
+ continue;
60
+ if (state.sCount[nextLine] - state.blkIndent >= 4)
61
+ continue;
62
+ for (pos = start + 1; pos <= max; pos++)
63
+ if (marker_str[(pos - start) % marker_len] !== state.src[pos])
64
+ break;
65
+ if (Math.floor((pos - start) / marker_len) < marker_count)
66
+ continue;
67
+ pos -= (pos - start) % marker_len;
68
+ pos = state.skipSpaces(pos);
69
+ if (pos < max)
70
+ continue;
71
+ auto_closed = true;
72
+ break;
73
+ }
74
+ const old_parent = state.parentType;
75
+ const old_line_max = state.lineMax;
76
+ state.parentType = "container";
77
+ state.lineMax = nextLine;
78
+ const token_o = state.push("container_" + name + "_open", "div", 1);
79
+ token_o.markup = markup;
80
+ token_o.block = true;
81
+ token_o.info = params;
82
+ token_o.map = [startLine, nextLine];
83
+ state.md.block.tokenize(state, startLine + 1, nextLine);
84
+ const token_c = state.push("container_" + name + "_close", "div", -1);
85
+ token_c.markup = state.src.slice(start, pos);
86
+ token_c.block = true;
87
+ state.parentType = old_parent;
88
+ state.lineMax = old_line_max;
89
+ state.line = nextLine + (auto_closed ? 1 : 0);
90
+ return true;
18
91
  }
92
+ md.block.ruler.before("fence", "container_" + name, container, { alt: [
93
+ "paragraph",
94
+ "reference",
95
+ "blockquote",
96
+ "list"
97
+ ] });
98
+ md.renderer.rules["container_" + name + "_open"] = render;
99
+ md.renderer.rules["container_" + name + "_close"] = render;
100
+ }
101
+ var tabMarkerCode = "=".charCodeAt(0);
102
+ var minTabMarkerLen = 2;
103
+ var ruleBlockTab = (state, startLine, endLine, silent) => {
19
104
  let pos = state.bMarks[startLine] + state.tShift[startLine];
20
- let max = state.eMarks[startLine];
21
- if (pos + 3 > max) {
105
+ const max = state.eMarks[startLine];
106
+ if (state.parentType !== "container")
107
+ return false;
108
+ if (pos + minTabMarkerLen > max)
22
109
  return false;
23
- }
24
110
  const marker = state.src.charCodeAt(pos);
25
- if (marker !== 58) {
111
+ if (marker !== tabMarkerCode)
26
112
  return false;
27
- }
28
113
  const mem = pos;
29
- pos = state.skipChars(pos, marker);
30
- let len = pos - mem;
31
- if (len < 3) {
32
- return false;
33
- }
34
- if (state.src.slice(pos, pos + tabsMarkerLen) !== tabsMarker) {
114
+ pos = state.skipChars(pos + 1, marker);
115
+ const tabMarkerLen = pos - mem;
116
+ if (tabMarkerLen < minTabMarkerLen - 1)
35
117
  return false;
36
- }
37
- pos += tabsMarkerLen;
38
- if (silent) {
118
+ if (silent)
39
119
  return true;
40
- }
41
- const markup = state.src.slice(mem, pos);
42
- const params = state.src.slice(pos, max);
43
120
  let nextLine = startLine;
44
- let haveEndMarker = false;
121
+ let endStart = mem;
122
+ let endPos = pos;
45
123
  for (; ; ) {
46
124
  nextLine++;
47
- if (nextLine >= endLine) {
125
+ if (nextLine >= endLine)
48
126
  break;
49
- }
50
- pos = state.bMarks[nextLine] + state.tShift[nextLine];
51
- const mem2 = pos;
52
- max = state.eMarks[nextLine];
53
- if (pos < max && state.sCount[nextLine] < state.blkIndent) {
127
+ endStart = state.bMarks[nextLine] + state.tShift[nextLine];
128
+ const max$1 = state.eMarks[nextLine];
129
+ if (endStart < max$1 && state.sCount[nextLine] < state.blkIndent)
54
130
  break;
55
- }
56
- if (state.src.charCodeAt(pos) !== marker) {
57
- continue;
58
- }
59
- if (state.sCount[nextLine] - state.blkIndent >= 4) {
131
+ if (state.src.charCodeAt(endStart) !== tabMarkerCode)
60
132
  continue;
61
- }
62
- pos = state.skipChars(pos, marker);
63
- if (pos - mem2 < len) {
133
+ const p = state.skipChars(endStart + 1, marker);
134
+ if (p - endStart !== tabMarkerLen)
64
135
  continue;
65
- }
66
- pos = state.skipSpaces(pos);
67
- if (pos < max) {
68
- continue;
69
- }
70
- haveEndMarker = true;
136
+ endPos = p;
71
137
  break;
72
138
  }
73
- len = state.sCount[startLine];
74
- state.line = nextLine + (haveEndMarker ? 1 : 0);
75
- const token = state.push("tabs", "div", 0);
76
- token.info = params;
77
- token.content = state.getLines(startLine + 1, nextLine, len, true);
78
- token.markup = markup;
79
- token.map = [startLine, state.line];
139
+ const oldParent = state.parentType;
140
+ const oldLineMax = state.lineMax;
141
+ state.parentType = "tab";
142
+ state.lineMax = nextLine;
143
+ const startToken = state.push("tab_open", "div", 1);
144
+ startToken.markup = state.src.slice(mem, pos);
145
+ startToken.block = true;
146
+ startToken.info = state.src.slice(pos, max).trimStart();
147
+ startToken.map = [startLine, nextLine - 1];
148
+ state.md.block.tokenize(state, startLine + 1, nextLine);
149
+ const endToken = state.push("tab_close", "div", -1);
150
+ endToken.markup = state.src.slice(endStart, endPos);
151
+ endToken.block = true;
152
+ state.parentType = oldParent;
153
+ state.lineMax = oldLineMax;
154
+ state.line = nextLine;
80
155
  return true;
81
156
  };
82
- var tabBreakRE = /^\s*::(.+)$/;
83
- var forbiddenCharsInSlotNames = /[ '"]/;
84
- var parseTabBreakLine = (line) => {
85
- const m = line.match(tabBreakRE);
86
- if (!m)
87
- return null;
88
- const trimmed = m[1].trim();
89
- if (forbiddenCharsInSlotNames.test(trimmed)) {
90
- throw new Error(
91
- `contains forbidden chars in slot names (space and quotes) (${JSON.stringify(
92
- line
93
- )})`
94
- );
95
- }
96
- return trimmed;
97
- };
98
- var lastLineBreakRE = /\n$/;
99
- var parseTabsContent = (content) => {
100
- const lines = content.replace(lastLineBreakRE, "").split("\n");
101
- const tabInfos = [];
102
- const tabLabels = /* @__PURE__ */ new Set();
103
- let currentTab = null;
104
- const createTabInfo = (label) => {
105
- if (tabLabels.has(label)) {
106
- throw new Error(`a tab labelled ${JSON.stringify(label)} already exists`);
107
- }
108
- const newTab = { label, content: [] };
109
- tabInfos.push(newTab);
110
- tabLabels.add(label);
111
- return newTab;
112
- };
113
- for (const line of lines) {
114
- const tabLabel = parseTabBreakLine(line);
115
- if (currentTab === null) {
116
- if (tabLabel === null) {
117
- throw new Error(
118
- `tabs should start with \`::\${tabLabel}\` (e.g. "::foo"). (received: ${JSON.stringify(
119
- line
120
- )})`
121
- );
122
- }
123
- currentTab = createTabInfo(tabLabel);
124
- continue;
125
- }
126
- if (tabLabel === null) {
127
- currentTab.content.push(line);
128
- } else {
129
- currentTab = createTabInfo(tabLabel);
130
- }
131
- }
132
- if (tabInfos.length < 0) {
133
- throw new Error("tabs should include at least one tab");
134
- }
135
- return tabInfos.map((info) => ({
136
- label: info.label,
137
- content: info.content.join("\n").replace(lastLineBreakRE, "")
138
- }));
139
- };
140
- var parseParams = (input) => {
141
- if (!input.startsWith("=")) {
142
- return {
143
- shareStateKey: void 0
144
- };
145
- }
146
- const splitted = input.split("=");
147
- return {
148
- shareStateKey: splitted[1]
149
- };
157
+ var parseTabsParams = (input) => {
158
+ return { shareStateKey: input.match(/key:(\S+)/)?.[1] };
150
159
  };
151
160
  var tabsPlugin = (md) => {
152
- md.block.ruler.before("fence", "=tabs", ruleBlockTabs, {
153
- alt: ["paragraph", "reference", "blockquote", "list"]
154
- });
155
- md.renderer.rules.tabs = (tokens, index, _options, env) => {
161
+ md.use(container_plugin, "tabs", { render(tokens, index) {
156
162
  const token = tokens[index];
157
- const tabs = parseTabsContent(token.content);
158
- const renderedTabs = tabs.map((tab) => ({
159
- label: tab.label,
160
- content: md.render(tab.content, env)
161
- }));
162
- const params = parseParams(token.info);
163
- const tabLabelsProp = `:tabLabels="${md.utils.escapeHtml(
164
- JSON.stringify(tabs.map((tab) => tab.label))
165
- )}"`;
166
- const shareStateKeyProp = params.shareStateKey ? `sharedStateKey="${md.utils.escapeHtml(params.shareStateKey)}"` : "";
167
- const slots = renderedTabs.map(
168
- (tab) => `<template #${tab.label}>${tab.content}</template>`
169
- );
170
- return `<PluginTabs ${tabLabelsProp} ${shareStateKeyProp}>${slots.join(
171
- ""
172
- )}</PluginTabs>`;
163
+ if (token.nesting === 1) {
164
+ const params = parseTabsParams(token.info);
165
+ return `<PluginTabs ${params.shareStateKey ? `sharedStateKey="${md.utils.escapeHtml(params.shareStateKey)}"` : ""}>
166
+ `;
167
+ } else
168
+ return `</PluginTabs>
169
+ `;
170
+ } });
171
+ md.block.ruler.after("container_tabs", "tab", ruleBlockTab);
172
+ const renderTab = (tokens, index) => {
173
+ const token = tokens[index];
174
+ if (token.nesting === 1) {
175
+ const label = token.info;
176
+ return `<PluginTabsTab ${`label="${md.utils.escapeHtml(label)}"`}>
177
+ `;
178
+ } else
179
+ return `</PluginTabsTab>
180
+ `;
173
181
  };
182
+ md.renderer.rules["tab_open"] = renderTab;
183
+ md.renderer.rules["tab_close"] = renderTab;
174
184
  };
175
185
 
176
186
  // src/utils/node/mdPlugins.ts
@@ -296,7 +306,6 @@ function patchOptimizeDeps(config) {
296
306
  config.vite.optimizeDeps = {};
297
307
  }
298
308
  config.vite.optimizeDeps.exclude = ["vitepress-plugin-tabs", "@sugarat/theme"];
299
- config.vite.optimizeDeps.include = ["element-plus"];
300
309
  }
301
310
 
302
311
  // src/utils/node/theme.ts
@@ -304,6 +313,14 @@ import fs from "node:fs";
304
313
  import { getDefaultTitle, getFileLastModifyTime, getTextSummary, getVitePressPages, grayMatter, normalizePath as normalizePath2, renderDynamicMarkdown } from "@sugarat/theme-shared";
305
314
 
306
315
  // src/utils/client/index.ts
316
+ function shuffleArray(arr) {
317
+ const array = [...arr];
318
+ for (let i = array.length - 1; i > 0; i--) {
319
+ const j = Math.floor(Math.random() * (i + 1));
320
+ [array[i], array[j]] = [array[j], array[i]];
321
+ }
322
+ return array;
323
+ }
307
324
  function formatDate(d, fmt = "yyyy-MM-dd hh:mm:ss") {
308
325
  if (!(d instanceof Date)) {
309
326
  d = new Date(d);
@@ -425,6 +442,10 @@ function patchVPThemeConfig(cfg, vpThemeConfig = {}) {
425
442
  return vpThemeConfig;
426
443
  }
427
444
  function checkConfig(cfg) {
445
+ const friendConfig = cfg?.friend;
446
+ if (!Array.isArray(friendConfig) && friendConfig?.random) {
447
+ friendConfig.list = shuffleArray(friendConfig.list);
448
+ }
428
449
  }
429
450
 
430
451
  // src/utils/node/vitePlugins.ts
@@ -547,20 +568,30 @@ function getVitePlugins(cfg = {}) {
547
568
  plugins.push(patchGroupIconPlugin());
548
569
  plugins.push(groupIconVitePlugin(cfg?.groupIcon));
549
570
  }
571
+ if (cfg?.tabs !== false) {
572
+ plugins.push(patchTabsPlugin());
573
+ }
574
+ if (cfg?.timeline !== false) {
575
+ plugins.push(patchTimelinePlugin());
576
+ }
550
577
  return plugins;
551
578
  }
552
579
  function patchGroupIconPlugin() {
553
- return {
580
+ return createPatchPlugin({
554
581
  name: "@sugarat/theme-plugin-patch-group-icon",
555
- enforce: "pre",
556
- transform(code, id) {
557
- if (id.match(/[\/\\]theme[\/\\]index\.(ts|js)$/)) {
558
- return `import 'virtual:group-icons.css'
559
- ${code}`;
560
- }
561
- return code;
582
+ replacements: {
583
+ "// replace-group-icon-import-code": "import 'virtual:group-icons.css'"
562
584
  }
563
- };
585
+ });
586
+ }
587
+ function patchTabsPlugin() {
588
+ return createPatchPlugin({
589
+ name: "@sugarat/theme-plugin-patch-tabs",
590
+ replacements: {
591
+ "// replace-tabs-import-code": "import { enhanceAppWithTabs } from 'vitepress-plugin-tabs/client'",
592
+ "// replace-tabs-enhance-app-code": "enhanceAppWithTabs(ctx.app)"
593
+ }
594
+ });
564
595
  }
565
596
  function registerVitePlugins(vpCfg, plugins) {
566
597
  vpCfg.vite = {
@@ -569,12 +600,25 @@ function registerVitePlugins(vpCfg, plugins) {
569
600
  };
570
601
  }
571
602
  function inlineInjectMermaidClient() {
572
- return {
603
+ return createPatchPlugin({
573
604
  name: "@sugarat/theme-plugin-inline-inject-mermaid-client",
605
+ replacements: {
606
+ "// replace-mermaid-import-code": "import Mermaid from 'vitepress-plugin-mermaid/Mermaid.vue'",
607
+ "// replace-mermaid-mounted-code": "if (!ctx.app.component('Mermaid')) { ctx.app.component('Mermaid', Mermaid as any) }"
608
+ }
609
+ });
610
+ }
611
+ function createPatchPlugin({ name, replacements }) {
612
+ return {
613
+ name,
574
614
  enforce: "pre",
575
615
  transform(code, id) {
576
- if (id.endsWith("src/index.ts") && code.startsWith("// @sugarat/theme index")) {
577
- return code.replace("// replace-mermaid-import-code", "import Mermaid from 'vitepress-plugin-mermaid/Mermaid.vue'").replace("// replace-mermaid-mounted-code", "if (!ctx.app.component('Mermaid')) { ctx.app.component('Mermaid', Mermaid as any) }");
616
+ if (id.endsWith("theme/src/index.ts") && code.startsWith("// @sugarat/theme index")) {
617
+ let newCode = code;
618
+ for (const [key, value] of Object.entries(replacements)) {
619
+ newCode = newCode.replace(key, value);
620
+ }
621
+ return newCode;
578
622
  }
579
623
  return code;
580
624
  }
@@ -737,6 +781,14 @@ function setThemeScript(themeColor) {
737
781
  };
738
782
  return pluginOps;
739
783
  }
784
+ function patchTimelinePlugin() {
785
+ return createPatchPlugin({
786
+ name: "@sugarat/theme-plugin-patch-timeline",
787
+ replacements: {
788
+ "// replace-timeline-import-code": "import 'vitepress-markdown-timeline/dist/theme/index.css'"
789
+ }
790
+ });
791
+ }
740
792
 
741
793
  // src/node.ts
742
794
  function getThemeConfig(cfg = {}) {
@@ -801,6 +853,5 @@ export {
801
853
  defineConfig,
802
854
  defineLocaleConfig,
803
855
  footerHTML,
804
- getThemeConfig,
805
- tabsPlugin as tabsMarkdownPlugin
856
+ getThemeConfig
806
857
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sugarat/theme",
3
- "version": "0.5.10",
3
+ "version": "0.5.12-beta.0",
4
4
  "description": "简约风的 Vitepress 博客主题,sugarat vitepress blog theme",
5
5
  "author": "sugar",
6
6
  "license": "MIT",
@@ -40,35 +40,31 @@
40
40
  "element-plus": "^2.7"
41
41
  },
42
42
  "dependencies": {
43
- "@giscus/vue": "^2.4.0",
44
- "@mdit-vue/shared": "^0.12.1",
43
+ "@giscus/vue": "^3.1.1",
45
44
  "@mermaid-js/mermaid-mindmap": "^9.3.0",
46
- "@vue/shared": "^3.4.26",
47
- "@vueuse/core": "^9.13.0",
45
+ "@vue/shared": "^3.5.25",
46
+ "@vueuse/core": "^14.1.0",
48
47
  "markdown-it-task-checkbox": "^1.0.6",
49
48
  "mermaid": "^10.9.0",
50
49
  "oh-my-live2d": "^0.19.3",
51
- "swiper": "^11.1.1",
52
50
  "vitepress-markdown-timeline": "^1.2.1",
53
- "vitepress-plugin-group-icons": "1.2.4",
51
+ "vitepress-plugin-group-icons": "1.6.5",
54
52
  "vitepress-plugin-mermaid": "2.0.13",
55
- "vitepress-plugin-tabs": "0.2.0",
53
+ "vitepress-plugin-tabs": "0.7.3",
56
54
  "@sugarat/theme-shared": "0.0.7",
57
- "vitepress-plugin-announcement": "0.1.6",
58
- "vitepress-plugin-rss": "0.4.0",
59
- "vitepress-plugin-pagefind": "0.4.17"
55
+ "vitepress-plugin-announcement": "0.1.7-beta.0",
56
+ "vitepress-plugin-pagefind": "0.4.18-beta.0",
57
+ "vitepress-plugin-rss": "0.4.1"
60
58
  },
61
59
  "devDependencies": {
62
- "@element-plus/icons-vue": "^2.3.1",
63
60
  "artalk": "^2.8.5",
64
- "element-plus": "^2.7.2",
65
61
  "markdown-it-mathjax3": "^4.3.2",
66
62
  "pagefind": "^1.3.0",
67
63
  "sass": "^1.80.6",
68
64
  "typescript": "^5.4.5",
69
65
  "vite": "^5.4.9",
70
66
  "vitepress": "2.0.0-alpha.15",
71
- "vue": "^3.5.12",
67
+ "vue": "^3.5.24",
72
68
  "vitepress-plugin-51la": "0.1.1"
73
69
  },
74
70
  "scripts": {