@slidev/cli 52.19.2 → 52.20.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/dist/{build-D2W5VZjC.mjs → build-BrwsAFCa.mjs} +3 -3
- package/dist/cli.mjs +16 -12
- package/dist/{export-DbxUfS31.mjs → export-LauAJGMx.mjs} +17 -1
- package/dist/index.mjs +1 -1
- package/dist/pptx-D2UE590V.mjs +1907 -0
- package/dist/{serve-CLfxiJWo.mjs → serve-BRH-KJ3L.mjs} +24 -17
- package/dist/{stdio-SMQ1-gi9.mjs → stdio-B5Rvh_az.mjs} +1 -1
- package/package.json +10 -9
- package/skills/slidev/references/core-cli.md +1 -1
- package/skills/slidev/references/core-exporting.md +4 -1
|
@@ -262,6 +262,16 @@ function loadModule(absolutePath) {
|
|
|
262
262
|
function stringifyMarkdownTokens(tokens) {
|
|
263
263
|
return tokens.map((token) => token.children?.filter((t) => ["text", "code_inline"].includes(t.type) && !t.content.match(RE_WHITESPACE_ONLY)).map((t) => t.content.trim()).join(" ")).filter(Boolean).join(" ");
|
|
264
264
|
}
|
|
265
|
+
const RE_WORD_CHARS_ONLY = /^[\w-]+$/;
|
|
266
|
+
const RE_REGEXP_CHARS = /[.*+?^${}()|[\]\\]/g;
|
|
267
|
+
function applyNotesAutoRuby(md, notesAutoRuby) {
|
|
268
|
+
const keys = Object.keys(notesAutoRuby).sort((a, b) => b.length - a.length).map((i) => RE_WORD_CHARS_ONLY.test(i) ? `\\b${i}\\b` : i.replace(RE_REGEXP_CHARS, "\\$&"));
|
|
269
|
+
if (!keys.length) return md;
|
|
270
|
+
return md.replace(new RegExp(`(${keys.join("|")})`, "g"), (match) => {
|
|
271
|
+
if (notesAutoRuby[match]) return `<ruby>${match}<rt>${notesAutoRuby[match]}</rt></ruby>`;
|
|
272
|
+
return match;
|
|
273
|
+
});
|
|
274
|
+
}
|
|
265
275
|
function generateFontParams(options) {
|
|
266
276
|
const weights = options.weights.flatMap((i) => options.italic ? [`0,${i}`, `1,${i}`] : [`${i}`]).sort().join(";");
|
|
267
277
|
return options.webfonts.map((i) => `family=${i.replace(RE_QUOTED_STRING, "$1").replace(RE_WHITESPACE, "+")}:${options.italic ? "ital," : ""}wght@${weights}`).join("&");
|
|
@@ -712,7 +722,7 @@ function createLayoutWrapperPlugin({ data, utils }) {
|
|
|
712
722
|
}
|
|
713
723
|
//#endregion
|
|
714
724
|
//#region package.json
|
|
715
|
-
var version = "52.
|
|
725
|
+
var version = "52.20.0";
|
|
716
726
|
//#endregion
|
|
717
727
|
//#region node/integrations/addons.ts
|
|
718
728
|
async function resolveAddons(addonsInConfig) {
|
|
@@ -1507,7 +1517,6 @@ const templates = [
|
|
|
1507
1517
|
];
|
|
1508
1518
|
//#endregion
|
|
1509
1519
|
//#region node/vite/loaders.ts
|
|
1510
|
-
const RE_WORD_CHARS_ONLY = /^[\w-]+$/;
|
|
1511
1520
|
function createSlidesLoader(options, serverOptions) {
|
|
1512
1521
|
const { data, mode, utils, withoutNotes } = options;
|
|
1513
1522
|
const notesMd = MarkdownExit({ html: true });
|
|
@@ -1547,12 +1556,17 @@ function createSlidesLoader(options, serverOptions) {
|
|
|
1547
1556
|
if (!match) return next();
|
|
1548
1557
|
const [, no] = match;
|
|
1549
1558
|
const idx = Number.parseInt(no) - 1;
|
|
1559
|
+
const targetSlide = data.slides[idx];
|
|
1560
|
+
if (!targetSlide) {
|
|
1561
|
+
res.statusCode = 404;
|
|
1562
|
+
return res.end();
|
|
1563
|
+
}
|
|
1550
1564
|
if (req.method === "GET") {
|
|
1551
|
-
res.write(JSON.stringify(withRenderedNote(
|
|
1565
|
+
res.write(JSON.stringify(withRenderedNote(targetSlide)));
|
|
1552
1566
|
return res.end();
|
|
1553
1567
|
} else if (req.method === "POST") {
|
|
1554
1568
|
const body = await getBodyJson(req);
|
|
1555
|
-
const slide =
|
|
1569
|
+
const slide = targetSlide;
|
|
1556
1570
|
if (body.content && body.content !== slide.source.content) hmrSlidesIndexes.add(idx);
|
|
1557
1571
|
if (body.content) slide.content = slide.source.content = body.content;
|
|
1558
1572
|
if (body.frontmatterRaw != null) {
|
|
@@ -1754,19 +1768,11 @@ function createSlidesLoader(options, serverOptions) {
|
|
|
1754
1768
|
if (withoutNotes) return "";
|
|
1755
1769
|
let clickCount = 0;
|
|
1756
1770
|
const notesAutoRuby = data.headmatter.notesAutoRuby || {};
|
|
1757
|
-
|
|
1771
|
+
const md = text.replace(/\[click(?::(\d+))?\]/gi, (_, count = 1) => {
|
|
1758
1772
|
clickCount += Number(count);
|
|
1759
1773
|
return `<span class="slidev-note-click-mark" data-clicks="${clickCount}"></span>`;
|
|
1760
1774
|
});
|
|
1761
|
-
|
|
1762
|
-
if (keys.length) {
|
|
1763
|
-
const regex = new RegExp(`(${keys.join("|")})`, "g");
|
|
1764
|
-
md = md.replace(regex, (match) => {
|
|
1765
|
-
if (notesAutoRuby[match]) return `<ruby>${match}<rt>${notesAutoRuby[match]}</rt></ruby>`;
|
|
1766
|
-
return match;
|
|
1767
|
-
});
|
|
1768
|
-
}
|
|
1769
|
-
return notesMd.render(md);
|
|
1775
|
+
return notesMd.render(applyNotesAutoRuby(md, notesAutoRuby));
|
|
1770
1776
|
}
|
|
1771
1777
|
function withRenderedNote(data) {
|
|
1772
1778
|
return {
|
|
@@ -2210,13 +2216,14 @@ function MarkdownItSnippet(md, { userRoot, userWorkspaceRoot, roots, data: { wat
|
|
|
2210
2216
|
}
|
|
2211
2217
|
const snippet = resolveSnippetImport(lineText, userRoot, slide, allowedRoots);
|
|
2212
2218
|
if (!snippet) return false;
|
|
2213
|
-
const { content,
|
|
2219
|
+
const { content, src } = snippet;
|
|
2214
2220
|
let { lang, meta } = snippet;
|
|
2215
2221
|
if (meta.includes("{monaco-write}")) {
|
|
2216
|
-
|
|
2222
|
+
const writePath = slash(path.relative(userRoot, src));
|
|
2223
|
+
monacoWriterWhitelist.add(writePath);
|
|
2217
2224
|
lang = lang.trim();
|
|
2218
2225
|
meta = meta.replace("{monaco-write}", "").trim() || "{}";
|
|
2219
|
-
const safeFilepath = JSON.stringify(
|
|
2226
|
+
const safeFilepath = JSON.stringify(writePath).slice(1, -1);
|
|
2220
2227
|
const encoded = lz.compressToBase64(content);
|
|
2221
2228
|
const token = state.push("html_block", "", 0);
|
|
2222
2229
|
token.content = `<Monaco writable="${safeFilepath}" code-lz="${encoded}" lang="${lang}" v-bind="${meta}" />\n`;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as getRoots } from "./resolver-BIhhHpe7.mjs";
|
|
2
|
-
import { i as createSlidevMcpServer, s as parser, u as version } from "./serve-
|
|
2
|
+
import { i as createSlidevMcpServer, s as parser, u as version } from "./serve-BRH-KJ3L.mjs";
|
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
|
|
4
4
|
//#region node/mcp/stdio.ts
|
|
5
5
|
/**
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slidev/cli",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "52.
|
|
4
|
+
"version": "52.20.0",
|
|
5
5
|
"description": "Presentation slides for developers",
|
|
6
6
|
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -60,11 +60,11 @@
|
|
|
60
60
|
"@shikijs/markdown-it": "^4.4.3",
|
|
61
61
|
"@shikijs/twoslash": "^4.4.3",
|
|
62
62
|
"@shikijs/vitepress-twoslash": "^4.4.3",
|
|
63
|
-
"@slidev/client": "52.
|
|
64
|
-
"@slidev/parser": "52.
|
|
65
|
-
"@slidev/types": "52.
|
|
66
|
-
"@unocss/extractor-mdc": "^66.10.
|
|
67
|
-
"@unocss/reset": "^66.10.
|
|
63
|
+
"@slidev/client": "52.20.0",
|
|
64
|
+
"@slidev/parser": "52.20.0",
|
|
65
|
+
"@slidev/types": "52.20.0",
|
|
66
|
+
"@unocss/extractor-mdc": "^66.10.4",
|
|
67
|
+
"@unocss/reset": "^66.10.4",
|
|
68
68
|
"@vitejs/plugin-vue": "^6.0.9",
|
|
69
69
|
"@vitejs/plugin-vue-jsx": "^5.1.6",
|
|
70
70
|
"ansis": "^4.4.0",
|
|
@@ -105,14 +105,14 @@
|
|
|
105
105
|
"source-map-js": "^1.2.1",
|
|
106
106
|
"typescript": "^6.0.3",
|
|
107
107
|
"unhead": "^3.4.1",
|
|
108
|
-
"unocss": "^66.10.
|
|
108
|
+
"unocss": "^66.10.4",
|
|
109
109
|
"unplugin-icons": "^24.0.0",
|
|
110
110
|
"unplugin-vue-components": "^32.1.0",
|
|
111
111
|
"unplugin-vue-markdown": "^32.1.1",
|
|
112
112
|
"untun": "^0.2.2",
|
|
113
113
|
"uqr": "^0.1.3",
|
|
114
114
|
"verkit": "^0.4.0",
|
|
115
|
-
"vite": "
|
|
115
|
+
"vite": "^8.3.0",
|
|
116
116
|
"vite-plugin-inspect": "^12.0.2",
|
|
117
117
|
"vite-plugin-remote-assets": "^2.1.0",
|
|
118
118
|
"vite-plugin-static-copy": "^4.1.1",
|
|
@@ -126,7 +126,8 @@
|
|
|
126
126
|
"devDependencies": {
|
|
127
127
|
"@hedgedoc/markdown-it-plugins": "^2.1.4",
|
|
128
128
|
"@types/picomatch": "^4.0.3",
|
|
129
|
-
"@types/plantuml-encoder": "^1.4.2"
|
|
129
|
+
"@types/plantuml-encoder": "^1.4.2",
|
|
130
|
+
"jszip": "^3.10.1"
|
|
130
131
|
},
|
|
131
132
|
"scripts": {
|
|
132
133
|
"build": "tsdown node/index.ts node/cli.ts",
|
|
@@ -65,7 +65,7 @@ Options:
|
|
|
65
65
|
| Option | Default | Description |
|
|
66
66
|
|--------|---------|-------------|
|
|
67
67
|
| `--output` | - | Output filename |
|
|
68
|
-
| `--format` | pdf | pdf / png / pptx / md |
|
|
68
|
+
| `--format` | pdf | pdf / png / pptx / pptx-editable / md |
|
|
69
69
|
| `--timeout` | 30000 | Timeout per slide (ms) |
|
|
70
70
|
| `--range` | - | Slide range (e.g., 1,4-7) |
|
|
71
71
|
| `--dark` | false | Export dark mode |
|
|
@@ -30,9 +30,12 @@ slidev export --output my-slides.pdf
|
|
|
30
30
|
### PowerPoint Export
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
|
-
slidev export --format pptx
|
|
33
|
+
slidev export --format pptx # each slide as an image
|
|
34
|
+
slidev export --format pptx-editable # native shapes, selectable text
|
|
34
35
|
```
|
|
35
36
|
|
|
37
|
+
`pptx-editable` measures the rendered slides and rebuilds them as PowerPoint shapes. SVG (including Mermaid), canvas, iframes, KaTeX formulas, gradients and CSS filters stay pictures, and any slide that cannot be rebuilt falls back to the image export on its own. Fonts are named, not embedded. `--per-slide` is not supported with it.
|
|
38
|
+
|
|
36
39
|
### PNG Export
|
|
37
40
|
|
|
38
41
|
```bash
|