@tycoworks/tycoslide 0.8.0 → 0.10.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/README.md +12 -9
- package/SKILL.md +6 -7
- package/dist/cli.js +39 -59
- package/dist/engine/fillers/filler.d.ts +21 -13
- package/dist/engine/fillers/filler.js +21 -24
- package/dist/engine/generate.d.ts +23 -17
- package/dist/engine/generate.js +157 -70
- package/dist/engine/index.d.ts +1 -1
- package/dist/engine/types.d.ts +39 -9
- package/dist/index.d.ts +15 -21
- package/dist/index.js +63 -88
- package/dist/manifest.js +17 -25
- package/dist/markdown/blocks/code.d.ts +17 -0
- package/dist/markdown/blocks/code.js +65 -0
- package/dist/markdown/blocks/image.d.ts +2 -0
- package/dist/markdown/blocks/image.js +9 -0
- package/dist/markdown/blocks/mermaid.d.ts +15 -0
- package/dist/markdown/blocks/mermaid.js +227 -0
- package/dist/markdown/{resolvers → blocks}/mermaidTheme.d.ts +1 -1
- package/dist/markdown/{resolvers → blocks}/mermaidTheme.js +1 -1
- package/dist/markdown/blocks/registry.d.ts +16 -0
- package/dist/markdown/blocks/registry.js +44 -0
- package/dist/markdown/blocks/table.d.ts +2 -0
- package/dist/markdown/blocks/table.js +23 -0
- package/dist/markdown/blocks/text.d.ts +12 -0
- package/dist/markdown/blocks/text.js +90 -0
- package/dist/markdown/deckCompiler.d.ts +17 -20
- package/dist/markdown/deckCompiler.js +143 -113
- package/dist/markdown/index.d.ts +11 -11
- package/dist/markdown/index.js +9 -8
- package/dist/markdown/inline.d.ts +26 -0
- package/dist/markdown/inline.js +136 -0
- package/dist/markdown/mdast.d.ts +25 -0
- package/dist/markdown/mdast.js +49 -0
- package/dist/markdown/schema/deckSchema.d.ts +30 -0
- package/dist/markdown/schema/deckSchema.js +51 -0
- package/dist/markdown/schema/strict.d.ts +9 -0
- package/dist/markdown/schema/strict.js +18 -0
- package/dist/markdown/schema/themeConfigSchema.d.ts +106 -0
- package/dist/markdown/schema/themeConfigSchema.js +147 -0
- package/dist/markdown/types.d.ts +194 -134
- package/dist/markdown/types.js +34 -23
- package/dist/skillZip.d.ts +17 -0
- package/dist/skillZip.js +35 -0
- package/package.json +7 -3
- package/syntax.md +1 -1
- package/dist/markdown/parsers.d.ts +0 -32
- package/dist/markdown/parsers.js +0 -233
- package/dist/markdown/resolvers/code.d.ts +0 -17
- package/dist/markdown/resolvers/code.js +0 -44
- package/dist/markdown/resolvers/mermaid.d.ts +0 -14
- package/dist/markdown/resolvers/mermaid.js +0 -81
- package/dist/markdown/resolvers/resolver.d.ts +0 -42
- package/dist/markdown/resolvers/resolver.js +0 -52
package/dist/markdown/types.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type
|
|
1
|
+
import type { RootContent } from "mdast";
|
|
2
|
+
import { type Frame, type ImageFill, type TableFill, type TemplateFill, type TextFill } from "../engine/index.js";
|
|
3
|
+
import type { MermaidConfig } from "./blocks/mermaidTheme.js";
|
|
3
4
|
/**
|
|
4
5
|
* An asset's scaling/cropping tolerance, declared in the theme catalog. The
|
|
5
6
|
* compiler maps it to the engine's object-fit `fit`. `icon`: never enlarge,
|
|
@@ -26,18 +27,6 @@ export type AssetEntry = {
|
|
|
26
27
|
};
|
|
27
28
|
/** Two-level catalog: `{ category: { name: AssetEntry } }`. */
|
|
28
29
|
export type AssetCatalog = Record<string, Record<string, AssetEntry>>;
|
|
29
|
-
/**
|
|
30
|
-
* Discriminator strings for the compiler-internal fence shapes produced by
|
|
31
|
-
* deckCompiler.ts. `Code` and `Mermaid` are resolved away entirely (syntax
|
|
32
|
-
* highlighting → TextFill, PNG rendering → ImageFill), so neither reaches the
|
|
33
|
-
* engine. Prose has no FenceType: it becomes a `TextFill` (`{ paragraphs }`),
|
|
34
|
-
* one of the engine's own fill shapes.
|
|
35
|
-
*/
|
|
36
|
-
export declare const FenceType: {
|
|
37
|
-
readonly Code: "code";
|
|
38
|
-
readonly Mermaid: "mermaid";
|
|
39
|
-
};
|
|
40
|
-
export type FenceType = (typeof FenceType)[keyof typeof FenceType];
|
|
41
30
|
/**
|
|
42
31
|
* Discriminator for a layout's frontmatter *parameters* — inputs the author
|
|
43
32
|
* writes as a single `key: value` line. Two kinds: `Template` (fills a styled
|
|
@@ -51,113 +40,117 @@ export declare const ParameterType: {
|
|
|
51
40
|
};
|
|
52
41
|
export type ParameterType = (typeof ParameterType)[keyof typeof ParameterType];
|
|
53
42
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* `
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
43
|
+
* The engine content types a slot may `accept`. A subset of the engine's
|
|
44
|
+
* `SlotType`: `Template` is parameter-only, never a body block. There is no
|
|
45
|
+
* `code` / `mermaid` accept type — a code fence folds into a `Text`-accepting
|
|
46
|
+
* slot (syntax highlighting → TextFill) and a mermaid fence into an
|
|
47
|
+
* `Image`-accepting slot (PNG render → ImageFill), the same fold the engine
|
|
48
|
+
* already performs. The author's markdown shape selects which accepted type a
|
|
49
|
+
* region routes to.
|
|
60
50
|
*/
|
|
61
|
-
export declare const
|
|
51
|
+
export declare const AcceptType: {
|
|
62
52
|
readonly Text: "text";
|
|
63
53
|
readonly Table: "table";
|
|
64
|
-
readonly
|
|
65
|
-
readonly Mermaid: "mermaid";
|
|
54
|
+
readonly Image: "image";
|
|
66
55
|
};
|
|
67
|
-
export type
|
|
56
|
+
export type AcceptType = (typeof AcceptType)[keyof typeof AcceptType];
|
|
68
57
|
/**
|
|
69
|
-
*
|
|
70
|
-
*
|
|
58
|
+
* The tonal surface a layout sits on. A code layout on a light panel needs a
|
|
59
|
+
* light Shiki theme (dark syntax would wash out); one on a dark panel needs a
|
|
60
|
+
* dark theme. A layout declares its `variant`; the code compile resolves a
|
|
61
|
+
* `{ light, dark }` `codeTheme` pair against it (a pair with no `variant` throws).
|
|
71
62
|
*/
|
|
72
|
-
export
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
source: string;
|
|
63
|
+
export declare const Variant: {
|
|
64
|
+
readonly Light: "light";
|
|
65
|
+
readonly Dark: "dark";
|
|
76
66
|
};
|
|
67
|
+
export type Variant = (typeof Variant)[keyof typeof Variant];
|
|
77
68
|
/**
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
69
|
+
* The four engine content shapes a slot's compiled content can be — the value
|
|
70
|
+
* `compile` produces and the engine fills. ImageFill carries a `.type`
|
|
71
|
+
* discriminator; the other three — TextFill, TableFill, TemplateFill — are
|
|
72
|
+
* identified structurally by their signature field.
|
|
81
73
|
*/
|
|
82
|
-
export type
|
|
83
|
-
type: typeof FenceType.Mermaid;
|
|
84
|
-
definition: string;
|
|
85
|
-
};
|
|
74
|
+
export type EngineFill = TextFill | TableFill | ImageFill | TemplateFill;
|
|
86
75
|
/**
|
|
87
|
-
* The
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* discriminator; the three engine fills without one — TextFill, TableFill,
|
|
91
|
-
* TemplateFill — are identified structurally by their signature field.
|
|
76
|
+
* The three engine content shapes a block handler can produce. A subset of
|
|
77
|
+
* `EngineFill` — `TemplateFill` is parameter-only (`AcceptType` excludes
|
|
78
|
+
* `Template`), so no block handler ever compiles one.
|
|
92
79
|
*/
|
|
93
|
-
export type
|
|
80
|
+
export type BlockFill = TextFill | TableFill | ImageFill;
|
|
94
81
|
/**
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
82
|
+
* Everything a block handler needs to compile a node into its engine fill: the
|
|
83
|
+
* asset resolver, the diagnostic context to name the offending layout/slide/slot
|
|
84
|
+
* when a region's markdown shape is illegal (a stray standalone block mixed into
|
|
85
|
+
* prose), and the theme-level `config` — from which code/mermaid compile read
|
|
86
|
+
* their one-per-theme style (`codeTheme`, `mermaid`, `mermaidVariant`,
|
|
87
|
+
* `outputDir`), not the slot.
|
|
88
|
+
*
|
|
89
|
+
* Lives in types.ts (not in `blocks/registry.ts`, which re-exports it) so a
|
|
90
|
+
* per-kind block file can import it without importing the registry — the registry
|
|
91
|
+
* imports the per-kind handlers, so the reverse would cycle.
|
|
98
92
|
*/
|
|
99
|
-
export type
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
93
|
+
export type BlockContext = {
|
|
94
|
+
resolveAssetRef: (ref: string) => ImageFill;
|
|
95
|
+
layoutName: string;
|
|
96
|
+
slideIdx: number;
|
|
97
|
+
source: string;
|
|
98
|
+
config: CompilerConfig;
|
|
99
|
+
/**
|
|
100
|
+
* The current layout's tonal surface, threaded from its `variant`. The code
|
|
101
|
+
* compile reads it to pick the arm of a `{ light, dark }` `codeTheme` pair;
|
|
102
|
+
* a pair with no `variant` throws (no default).
|
|
103
|
+
*/
|
|
104
|
+
layoutVariant?: Variant;
|
|
104
105
|
};
|
|
105
106
|
/**
|
|
106
|
-
*
|
|
107
|
-
*
|
|
107
|
+
* A block handler recognizes one content kind at the region's top level, folds
|
|
108
|
+
* it to the engine `AcceptType` it fills, and compiles the node straight into the
|
|
109
|
+
* matching engine fill — highlighting a code fence to a TextFill, rendering a
|
|
110
|
+
* mermaid fence to an ImageFill. Recognition (`match`), type (`acceptType`), and
|
|
111
|
+
* build (`compile`) live together — a new content kind is one file, one registry
|
|
112
|
+
* row. Non-generic like the engine's `Filler`: the array can't correlate a
|
|
113
|
+
* per-element type guard with `compile`'s param, so each handler narrows the node
|
|
114
|
+
* internally with a single-hop cast. Mirrors the old sdk's `SyntaxHandler`.
|
|
108
115
|
*/
|
|
109
|
-
export type
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
116
|
+
export type BlockHandler = {
|
|
117
|
+
match(node: RootContent): boolean;
|
|
118
|
+
acceptType: AcceptType;
|
|
119
|
+
compile(node: RootContent, ctx: BlockContext): Promise<BlockFill>;
|
|
113
120
|
};
|
|
114
121
|
/**
|
|
115
|
-
* A DeckStep
|
|
116
|
-
*
|
|
117
|
-
*
|
|
122
|
+
* A DeckStep as the compiler produces it. Content is already engine-shaped —
|
|
123
|
+
* code fences highlighted to TextFill and mermaid fences rendered to ImageFill
|
|
124
|
+
* during `compile` — so this is structurally equivalent to the engine's DeckStep
|
|
125
|
+
* and needs no further resolution.
|
|
118
126
|
*/
|
|
119
|
-
export type
|
|
127
|
+
export type CompilerDeckStep = {
|
|
120
128
|
layout: string;
|
|
121
|
-
content?: Record<string,
|
|
122
|
-
/** Slide-level speaker notes,
|
|
129
|
+
content?: Record<string, EngineFill>;
|
|
130
|
+
/** Slide-level speaker notes, stripped from frontmatter. Plain text. */
|
|
123
131
|
notes?: string;
|
|
124
132
|
};
|
|
125
133
|
/**
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
134
|
+
* The deck shape the compiler produces. `output` may be unset until a caller
|
|
135
|
+
* (the CLI, or a programmatic caller) assigns one; `buildDeck` fails fast if it
|
|
136
|
+
* is still missing. Once `output` is present this is structurally equivalent to
|
|
137
|
+
* the engine's Deck, so `generate` consumes it without any cast.
|
|
129
138
|
*/
|
|
130
|
-
export type
|
|
139
|
+
export type CompilerDeck = {
|
|
131
140
|
theme: string;
|
|
132
|
-
output
|
|
133
|
-
steps:
|
|
134
|
-
};
|
|
135
|
-
/**
|
|
136
|
-
* Fields common to every text shape, image parameter, and slot. A text shape is
|
|
137
|
-
* addressed by `shapeName` and owns a `template` (its placeholders are the
|
|
138
|
-
* fillable keys); image parameters and slots additionally carry a single `key`.
|
|
139
|
-
*/
|
|
140
|
-
type CompilerShapeBase = {
|
|
141
|
-
shapeName: string;
|
|
142
|
-
limit?: {
|
|
143
|
-
maxChars?: number;
|
|
144
|
-
maxLines?: number;
|
|
145
|
-
maxItems?: number;
|
|
146
|
-
};
|
|
147
|
-
/**
|
|
148
|
-
* Whether the parameter/slot may be omitted from a slide. Optional (defaults
|
|
149
|
-
* to false): a required one with no value causes the compiler to throw with
|
|
150
|
-
* layout + key names.
|
|
151
|
-
*/
|
|
152
|
-
required?: boolean;
|
|
141
|
+
output?: string;
|
|
142
|
+
steps: CompilerDeckStep[];
|
|
153
143
|
};
|
|
154
144
|
/**
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
145
|
+
* Markdown-flavored measurement hints on a slot or template parameter: caps on
|
|
146
|
+
* expanded run text, line count, or list items. All optional — a missing cap is
|
|
147
|
+
* "no limit." Advisory metadata surfaced in the manifest; the fill never enforces
|
|
148
|
+
* it.
|
|
158
149
|
*/
|
|
159
|
-
type
|
|
160
|
-
|
|
150
|
+
export type Limit = {
|
|
151
|
+
maxChars?: number;
|
|
152
|
+
maxLines?: number;
|
|
153
|
+
maxItems?: number;
|
|
161
154
|
};
|
|
162
155
|
/**
|
|
163
156
|
* Template parameter: a styled text shape filled by expanding a `template` into the
|
|
@@ -167,14 +160,31 @@ type CompilerSlotBase = CompilerShapeBase & {
|
|
|
167
160
|
* placeholders in its template. The shape carries no top-level `key`; its
|
|
168
161
|
* placeholders are the keys the author fills in frontmatter.
|
|
169
162
|
*/
|
|
170
|
-
export type CompilerTemplateParameter =
|
|
163
|
+
export type CompilerTemplateParameter = {
|
|
164
|
+
shapeName: string;
|
|
165
|
+
limit?: Limit;
|
|
166
|
+
/**
|
|
167
|
+
* Whether the parameter may be omitted from a slide. Optional (defaults to
|
|
168
|
+
* false): a required one with no value causes the compiler to throw with
|
|
169
|
+
* layout + key names.
|
|
170
|
+
*/
|
|
171
|
+
required?: boolean;
|
|
171
172
|
type: typeof ParameterType.Template;
|
|
172
173
|
/** The shape's text as one template with `{key}` placeholders; newlines are line breaks. */
|
|
173
174
|
template: string;
|
|
174
175
|
};
|
|
175
176
|
/** Image parameter: one frontmatter path filled by fillImage. Sizing/crop
|
|
176
|
-
* behaviour comes from the resolved asset's `type`, not the slot.
|
|
177
|
-
|
|
177
|
+
* behaviour comes from the resolved asset's `type`, not the slot. Carries no
|
|
178
|
+
* `limit` — measuring an image path against char/line caps is meaningless. */
|
|
179
|
+
export type CompilerImageParameter = {
|
|
180
|
+
shapeName: string;
|
|
181
|
+
/**
|
|
182
|
+
* Whether the parameter may be omitted from a slide. Optional (defaults to
|
|
183
|
+
* false): a required one with no value causes the compiler to throw with
|
|
184
|
+
* layout + key names.
|
|
185
|
+
*/
|
|
186
|
+
required?: boolean;
|
|
187
|
+
key: string;
|
|
178
188
|
type: typeof ParameterType.Image;
|
|
179
189
|
};
|
|
180
190
|
/**
|
|
@@ -182,58 +192,90 @@ export type CompilerImageParameter = CompilerSlotBase & {
|
|
|
182
192
|
* single `key: value` line, resolved against the layout's `parameters` list.
|
|
183
193
|
*/
|
|
184
194
|
export type CompilerParameter = CompilerTemplateParameter | CompilerImageParameter;
|
|
185
|
-
/** Multi-paragraph body filled by fillText (specimen-style rebuild). */
|
|
186
|
-
export type CompilerTextSlot = CompilerSlotBase & {
|
|
187
|
-
type: typeof CompilerSlotType.Text;
|
|
188
|
-
/** Leave the first N specimen paragraphs untouched. */
|
|
189
|
-
startAt?: number;
|
|
190
|
-
};
|
|
191
|
-
/** Table shape backed by an `<a:tbl>` with header + data specimen rows. */
|
|
192
|
-
export type CompilerTableSlot = CompilerSlotBase & {
|
|
193
|
-
type: typeof CompilerSlotType.Table;
|
|
194
|
-
};
|
|
195
195
|
/**
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
196
|
+
* Reserved keys in a deck's frontmatter — global (theme, output) and per-slide
|
|
197
|
+
* (layout, body). Exported so callers (e.g. cli.ts) reference the constants
|
|
198
|
+
* instead of literal strings.
|
|
199
199
|
*/
|
|
200
|
-
export
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
200
|
+
export declare const RESERVED_KEY: {
|
|
201
|
+
readonly LAYOUT: "layout";
|
|
202
|
+
readonly BODY: "body";
|
|
203
|
+
readonly OUTPUT: "output";
|
|
204
|
+
readonly THEME: "theme";
|
|
205
|
+
readonly NOTES: "notes";
|
|
204
206
|
};
|
|
205
207
|
/**
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
*
|
|
208
|
+
* A kind of content a slot accepts, and the real template shape that realizes
|
|
209
|
+
* it — the compiler mirror of the engine's `Block`. `type` is an engine content
|
|
210
|
+
* type (`text` | `table` | `image`); `shapeName` names the shape on
|
|
211
|
+
* `sourceSlide` carrying the specimen styling. When `sourceSlide` equals the
|
|
212
|
+
* layout's `slideNumber` the shape is already on the cloned slide (fill in
|
|
213
|
+
* place); otherwise it is transplanted into the slot's `frame`. `startAt` is a
|
|
214
|
+
* text-specimen concern (leave the first N specimen paragraphs untouched), only
|
|
215
|
+
* meaningful on a text block. Named `CompilerBlock` to stay distinct from the
|
|
216
|
+
* engine's `Block` and the compiler's `BlockHandler`.
|
|
210
217
|
*/
|
|
211
|
-
export type
|
|
212
|
-
type:
|
|
213
|
-
|
|
214
|
-
|
|
218
|
+
export type CompilerBlock = {
|
|
219
|
+
type: AcceptType;
|
|
220
|
+
sourceSlide: number;
|
|
221
|
+
shapeName: string;
|
|
222
|
+
startAt?: number;
|
|
215
223
|
};
|
|
216
224
|
/**
|
|
217
|
-
* Compiler-facing slot.
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
*
|
|
225
|
+
* Compiler-facing slot. A layout's body region (the default region, or a
|
|
226
|
+
* `::name::` region), no longer welded to one shape+type: it `accepts` a set of
|
|
227
|
+
* `CompilerBlock`s and owns a `frame` (real observed EMU coordinates, never
|
|
228
|
+
* computed). The author's markdown shape selects which accepted block a region
|
|
229
|
+
* routes to; a type the slot does not accept fails fast. `frame` is required
|
|
230
|
+
* only when a slot has a transplant block (a block whose `sourceSlide` differs
|
|
231
|
+
* from the layout's `slideNumber`); a base-only slot fills in place and needs
|
|
232
|
+
* none. Adds markdown-flavored `limit` hints on top of the engine's minimal
|
|
233
|
+
* Slot; per-slot `codeTheme` / `mermaidVariant` moved to the theme level.
|
|
224
234
|
*/
|
|
225
|
-
export type CompilerSlot =
|
|
235
|
+
export type CompilerSlot = {
|
|
236
|
+
key: string;
|
|
237
|
+
accepts: CompilerBlock[];
|
|
238
|
+
frame?: Frame;
|
|
239
|
+
limit?: Limit;
|
|
240
|
+
/**
|
|
241
|
+
* Whether the slot may be omitted from a slide. Optional (defaults to false):
|
|
242
|
+
* a required slot with no content throws with layout + key names.
|
|
243
|
+
*/
|
|
244
|
+
required?: boolean;
|
|
245
|
+
};
|
|
226
246
|
export type CompilerLayout = {
|
|
227
247
|
name: string;
|
|
228
248
|
slideNumber: number;
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
249
|
+
/** Optional prose — a layout is a shape, not a purpose (agent-guidance descoped). */
|
|
250
|
+
description?: string;
|
|
251
|
+
whenToUse?: string;
|
|
252
|
+
whenNotToUse?: string;
|
|
253
|
+
/**
|
|
254
|
+
* The layout's tonal surface. Selects the arm of a `{ light, dark }` `codeTheme`
|
|
255
|
+
* pair for code fences on this layout. Required when `codeTheme` is a pair.
|
|
256
|
+
*/
|
|
257
|
+
variant?: Variant;
|
|
232
258
|
/** Frontmatter inputs (template, image) — one value per `key: value` line. */
|
|
233
259
|
parameters: CompilerParameter[];
|
|
234
|
-
/** Body regions
|
|
260
|
+
/** Body regions — the default body or `::name::` regions; each `accepts` blocks. */
|
|
235
261
|
slots: CompilerSlot[];
|
|
236
262
|
};
|
|
263
|
+
/**
|
|
264
|
+
* A brand font the theme hands the compiler for HTML-based rendering (currently
|
|
265
|
+
* mermaid). Purely compiler-facing — the engine fills PPTX shapes, whose fonts
|
|
266
|
+
* live in the template, and never sees this. `path` is a module specifier
|
|
267
|
+
* (`@fontsource/inter/files/inter-latin-400-normal.woff2`) resolved from the
|
|
268
|
+
* theme's directory, or a `./`- / `/`-prefixed filesystem path resolved against
|
|
269
|
+
* `rootDir`; `family` is the CSS `font-family` name the mermaid variant's
|
|
270
|
+
* `fontFamily` must match. Register weight 400 + 700 to avoid synthetic bold on
|
|
271
|
+
* node labels. The mechanism is generic — the theme names its own fonts.
|
|
272
|
+
*/
|
|
273
|
+
export type ThemeFont = {
|
|
274
|
+
family: string;
|
|
275
|
+
path: string;
|
|
276
|
+
/** OpenType weight (default 400). */
|
|
277
|
+
weight?: number;
|
|
278
|
+
};
|
|
237
279
|
/**
|
|
238
280
|
* Compiler-facing theme configuration. Mirrors the engine's ThemeConfig but
|
|
239
281
|
* carries markdown-flavored fields (mermaid variants) that live outside the
|
|
@@ -246,8 +288,26 @@ export type CompilerThemeConfig = {
|
|
|
246
288
|
template: string;
|
|
247
289
|
outputDir?: string;
|
|
248
290
|
mermaid?: MermaidConfig;
|
|
291
|
+
/**
|
|
292
|
+
* Brand fonts injected as `@font-face` when rendering mermaid, so diagram text
|
|
293
|
+
* uses the theme font instead of a Chromium fallback. Optional — with none
|
|
294
|
+
* declared, mermaid renders in whatever the OS substitutes.
|
|
295
|
+
*/
|
|
296
|
+
fonts?: ThemeFont[];
|
|
297
|
+
/**
|
|
298
|
+
* Theme-level defaults for the two content types the compiler resolves before
|
|
299
|
+
* the engine sees them. One code style and one mermaid style per theme (the
|
|
300
|
+
* design-system framing) — they can't sit on a multi-type slot. `codeTheme` is
|
|
301
|
+
* a Shiki theme id, or a `{ light, dark }` pair when the theme has both light
|
|
302
|
+
* and dark code layouts (each layout's `variant` picks the arm);
|
|
303
|
+
* `mermaidVariant` names an entry in `mermaid`.
|
|
304
|
+
*/
|
|
305
|
+
codeTheme?: string | {
|
|
306
|
+
light: string;
|
|
307
|
+
dark: string;
|
|
308
|
+
};
|
|
309
|
+
mermaidVariant?: string;
|
|
249
310
|
};
|
|
250
311
|
export type CompilerConfig = CompilerThemeConfig & {
|
|
251
312
|
rootDir: string;
|
|
252
313
|
};
|
|
253
|
-
export {};
|
package/dist/markdown/types.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SlotType } from "../engine/index.js";
|
|
1
|
+
import { SlotType, } from "../engine/index.js";
|
|
2
2
|
// ── Asset catalog (compiler / theme-metadata only) ───────────────────────────
|
|
3
3
|
/**
|
|
4
4
|
* An asset's scaling/cropping tolerance, declared in the theme catalog. The
|
|
@@ -10,18 +10,6 @@ export const AssetType = {
|
|
|
10
10
|
Image: "image",
|
|
11
11
|
Background: "background",
|
|
12
12
|
};
|
|
13
|
-
// ── FenceType discriminator ───────────────────────────────────────────────────
|
|
14
|
-
/**
|
|
15
|
-
* Discriminator strings for the compiler-internal fence shapes produced by
|
|
16
|
-
* deckCompiler.ts. `Code` and `Mermaid` are resolved away entirely (syntax
|
|
17
|
-
* highlighting → TextFill, PNG rendering → ImageFill), so neither reaches the
|
|
18
|
-
* engine. Prose has no FenceType: it becomes a `TextFill` (`{ paragraphs }`),
|
|
19
|
-
* one of the engine's own fill shapes.
|
|
20
|
-
*/
|
|
21
|
-
export const FenceType = {
|
|
22
|
-
Code: "code",
|
|
23
|
-
Mermaid: "mermaid",
|
|
24
|
-
};
|
|
25
13
|
// ── ParameterType discriminator (frontmatter, one value) ──────────────────────
|
|
26
14
|
/**
|
|
27
15
|
* Discriminator for a layout's frontmatter *parameters* — inputs the author
|
|
@@ -34,18 +22,41 @@ export const ParameterType = {
|
|
|
34
22
|
Template: SlotType.Template,
|
|
35
23
|
Image: SlotType.Image,
|
|
36
24
|
};
|
|
37
|
-
// ──
|
|
25
|
+
// ── AcceptType discriminator (what a slot accepts) ────────────────────────────
|
|
38
26
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* `
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
27
|
+
* The engine content types a slot may `accept`. A subset of the engine's
|
|
28
|
+
* `SlotType`: `Template` is parameter-only, never a body block. There is no
|
|
29
|
+
* `code` / `mermaid` accept type — a code fence folds into a `Text`-accepting
|
|
30
|
+
* slot (syntax highlighting → TextFill) and a mermaid fence into an
|
|
31
|
+
* `Image`-accepting slot (PNG render → ImageFill), the same fold the engine
|
|
32
|
+
* already performs. The author's markdown shape selects which accepted type a
|
|
33
|
+
* region routes to.
|
|
45
34
|
*/
|
|
46
|
-
export const
|
|
35
|
+
export const AcceptType = {
|
|
47
36
|
Text: SlotType.Text,
|
|
48
37
|
Table: SlotType.Table,
|
|
49
|
-
|
|
50
|
-
|
|
38
|
+
Image: SlotType.Image,
|
|
39
|
+
};
|
|
40
|
+
// ── Variant discriminator (a layout's light/dark surface) ─────────────────────
|
|
41
|
+
/**
|
|
42
|
+
* The tonal surface a layout sits on. A code layout on a light panel needs a
|
|
43
|
+
* light Shiki theme (dark syntax would wash out); one on a dark panel needs a
|
|
44
|
+
* dark theme. A layout declares its `variant`; the code compile resolves a
|
|
45
|
+
* `{ light, dark }` `codeTheme` pair against it (a pair with no `variant` throws).
|
|
46
|
+
*/
|
|
47
|
+
export const Variant = {
|
|
48
|
+
Light: "light",
|
|
49
|
+
Dark: "dark",
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Reserved keys in a deck's frontmatter — global (theme, output) and per-slide
|
|
53
|
+
* (layout, body). Exported so callers (e.g. cli.ts) reference the constants
|
|
54
|
+
* instead of literal strings.
|
|
55
|
+
*/
|
|
56
|
+
export const RESERVED_KEY = {
|
|
57
|
+
LAYOUT: "layout",
|
|
58
|
+
BODY: "body",
|
|
59
|
+
OUTPUT: "output",
|
|
60
|
+
THEME: "theme",
|
|
61
|
+
NOTES: "notes",
|
|
51
62
|
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rewrite the `name:` value in a skill.md's leading YAML frontmatter so the
|
|
3
|
+
* packaged skill is named after the consuming theme, not the source template.
|
|
4
|
+
* Only the leading `---`…`---` block is touched; the body is left byte-for-byte.
|
|
5
|
+
* Throws if there is no frontmatter or no `name:` line — the caller names the file.
|
|
6
|
+
*/
|
|
7
|
+
export declare function renameSkill(md: string, name: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Build an uploadable Agent Skill zip whose entries live under a single root
|
|
10
|
+
* folder (e.g. `mz-slides/skill.md`), matching Anthropic's custom-skill format.
|
|
11
|
+
* Each entry is written from an explicit in-memory list rather than a directory
|
|
12
|
+
* scan, so the zip contains exactly the files the caller passes — nothing else.
|
|
13
|
+
*/
|
|
14
|
+
export declare function zipSkill(folderName: string, files: {
|
|
15
|
+
name: string;
|
|
16
|
+
content: string | Buffer;
|
|
17
|
+
}[]): Promise<Buffer>;
|
package/dist/skillZip.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import JSZip from "jszip";
|
|
2
|
+
const FRONTMATTER = /^---\n([\s\S]*?)\n---/;
|
|
3
|
+
const NAME_LINE = /^name:[ \t]*.*$/m;
|
|
4
|
+
/**
|
|
5
|
+
* Rewrite the `name:` value in a skill.md's leading YAML frontmatter so the
|
|
6
|
+
* packaged skill is named after the consuming theme, not the source template.
|
|
7
|
+
* Only the leading `---`…`---` block is touched; the body is left byte-for-byte.
|
|
8
|
+
* Throws if there is no frontmatter or no `name:` line — the caller names the file.
|
|
9
|
+
*/
|
|
10
|
+
export function renameSkill(md, name) {
|
|
11
|
+
const block = md.match(FRONTMATTER);
|
|
12
|
+
if (!block)
|
|
13
|
+
throw new Error("skill.md has no YAML frontmatter block");
|
|
14
|
+
if (!NAME_LINE.test(block[1]))
|
|
15
|
+
throw new Error('skill.md frontmatter has no "name:" line');
|
|
16
|
+
return md.replace(block[0], block[0].replace(NAME_LINE, `name: ${name}`));
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Build an uploadable Agent Skill zip whose entries live under a single root
|
|
20
|
+
* folder (e.g. `mz-slides/skill.md`), matching Anthropic's custom-skill format.
|
|
21
|
+
* Each entry is written from an explicit in-memory list rather than a directory
|
|
22
|
+
* scan, so the zip contains exactly the files the caller passes — nothing else.
|
|
23
|
+
*/
|
|
24
|
+
export async function zipSkill(folderName, files) {
|
|
25
|
+
if (files.length === 0)
|
|
26
|
+
throw new Error(`No files to zip for skill folder: ${folderName}`);
|
|
27
|
+
const zip = new JSZip();
|
|
28
|
+
const folder = zip.folder(folderName);
|
|
29
|
+
if (!folder)
|
|
30
|
+
throw new Error(`Failed to create zip folder: ${folderName}`);
|
|
31
|
+
for (const file of files) {
|
|
32
|
+
folder.file(file.name, file.content);
|
|
33
|
+
}
|
|
34
|
+
return zip.generateAsync({ type: "nodebuffer" });
|
|
35
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tycoworks/tycoslide",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
|
+
"description": "Create editable, on-brand PowerPoint slides from markdown.",
|
|
4
5
|
"type": "module",
|
|
5
6
|
"main": "dist/index.js",
|
|
6
7
|
"types": "dist/index.d.ts",
|
|
@@ -22,17 +23,20 @@
|
|
|
22
23
|
"format": "biome format --write ."
|
|
23
24
|
},
|
|
24
25
|
"dependencies": {
|
|
25
|
-
"@mermaid-js/mermaid-cli": "^11.15.0",
|
|
26
26
|
"@xmldom/xmldom": "^0.9.10",
|
|
27
27
|
"commander": "^15.0.0",
|
|
28
28
|
"image-size": "^2.0.2",
|
|
29
|
+
"jszip": "^3.10.1",
|
|
30
|
+
"mermaid": "^11.16.1",
|
|
31
|
+
"playwright": "^1.58.2",
|
|
29
32
|
"pptx-automizer": "^0.8.2",
|
|
30
33
|
"remark-gfm": "^4.0.1",
|
|
31
34
|
"remark-ins": "^1.2.5",
|
|
32
35
|
"remark-parse": "^11.0.0",
|
|
33
36
|
"shiki": "^4.3.0",
|
|
34
37
|
"unified": "^11.0.0",
|
|
35
|
-
"yaml": "^2.0.0"
|
|
38
|
+
"yaml": "^2.0.0",
|
|
39
|
+
"zod": "^4.4.3"
|
|
36
40
|
},
|
|
37
41
|
"devDependencies": {
|
|
38
42
|
"@biomejs/biome": "^2.5.1",
|
package/syntax.md
CHANGED
|
@@ -238,7 +238,7 @@ notes: |
|
|
|
238
238
|
---
|
|
239
239
|
```
|
|
240
240
|
|
|
241
|
-
To build with all speaker notes omitted, pass `--no-notes` to `tycoslide build` (see [README](README.md#cli)).
|
|
241
|
+
To build with all speaker notes omitted, pass `--no-notes` to `npx tycoslide build` (see [README](README.md#cli)).
|
|
242
242
|
|
|
243
243
|
---
|
|
244
244
|
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import type { StyledParagraph, TableFill, TextRun } from "../engine/index.js";
|
|
2
|
-
/**
|
|
3
|
-
* Parse inline markdown formatting in a single line of text into TextRun arrays.
|
|
4
|
-
* Handles **bold**, *italic*, ***bold italic***, ~~strikethrough~~, ++underline++,
|
|
5
|
-
* [link](url), and `inline code`.
|
|
6
|
-
*/
|
|
7
|
-
export declare function parseInlineRuns(text: string): TextRun[];
|
|
8
|
-
/**
|
|
9
|
-
* Parse a raw prose line into a StyledParagraph with bullet detection and inline
|
|
10
|
-
* formatting. The caller provides the raw line including leading whitespace and
|
|
11
|
-
* bullet markers.
|
|
12
|
-
*/
|
|
13
|
-
export declare function parseStyledParagraph(raw: string): StyledParagraph;
|
|
14
|
-
/**
|
|
15
|
-
* Parse a single line of prose into its structural components.
|
|
16
|
-
*
|
|
17
|
-
* Lines beginning with `- ` or `* ` (optionally preceded by spaces) are
|
|
18
|
-
* recognized as bullet items. Every 2 spaces of leading indent on a bullet
|
|
19
|
-
* line increase its level by 1. A leading dash without a trailing space is
|
|
20
|
-
* NOT a bullet (e.g. `-foo`).
|
|
21
|
-
*/
|
|
22
|
-
export declare function parseProseLine(raw: string): {
|
|
23
|
-
text: string;
|
|
24
|
-
bullet: boolean;
|
|
25
|
-
level: number;
|
|
26
|
-
};
|
|
27
|
-
/**
|
|
28
|
-
* Parse a GFM table into TableFill (StyledParagraph[] cells). Returns null
|
|
29
|
-
* for non-table text. Cells carry rich runs so inline formatting works
|
|
30
|
-
* inside tables for free.
|
|
31
|
-
*/
|
|
32
|
-
export declare function parseGfmTable(text: string): TableFill | null;
|