@codename/deck 0.3.0 → 0.4.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 +4 -4
- package/dist/deck.bundle.mjs +100 -94
- package/dist/deck.bundle.mjs.map +4 -4
- package/dist/deck.css +111 -0
- package/dist/deck.js +208 -91
- package/dist/deck.js.map +4 -4
- package/dist/deck.mjs +42 -36
- package/dist/deck.mjs.map +4 -4
- package/dist/template.mjs +3 -3
- package/dist/template.mjs.map +3 -3
- package/dist/types/blocks.d.ts +6 -4
- package/dist/types/figures.d.ts +68 -0
- package/dist/types/kit.d.ts +16 -0
- package/dist/types/mindmap.d.ts +69 -0
- package/dist/types/pptx.d.ts +3 -1
- package/dist/types/render.d.ts +21 -3
- package/dist/types/version.d.ts +1 -1
- package/docs/format.md +85 -4
- package/docs/host.md +3 -3
- package/docs/kits.md +10 -2
- package/package.json +1 -1
- package/src/blocks.js +26 -9
- package/src/deck.css +111 -0
- package/src/deck.js +11 -1
- package/src/figures.js +255 -0
- package/src/kit.js +35 -6
- package/src/mindmap.js +208 -0
- package/src/pptx.js +132 -17
- package/src/render.js +122 -19
- package/src/version.js +1 -1
package/dist/types/blocks.d.ts
CHANGED
|
@@ -14,12 +14,14 @@ export type Where = {
|
|
|
14
14
|
export declare const libraryAt: (base: string, name: string, version: string, file: string) => string;
|
|
15
15
|
/** @param {Where} where */
|
|
16
16
|
export declare function defaultBlocks({ base, root, versions }: Where): {
|
|
17
|
-
/** @param {HTMLElement} box @param {string} source */
|
|
17
|
+
/** @param {HTMLElement} box @param {string} source the chart's option, as JSON */
|
|
18
18
|
echarts(box: HTMLElement, source: string): Promise<void>;
|
|
19
19
|
/**
|
|
20
20
|
* A diagram written in Mermaid's language, drawn by Pele (Obsidian's, MIT): every kind Mermaid
|
|
21
|
-
* 12.1 has, no DOM needed, an SVG with no script or HTML in it
|
|
22
|
-
*
|
|
21
|
+
* 12.1 has, no DOM needed, an SVG with no script or HTML in it; its own settings (a `---` config
|
|
22
|
+
* block, `%%{init: …}%%`) read by Pele, the fence's options too, `scale` the share of its box it
|
|
23
|
+
* takes. Shown as a picture, its colours the deck's. @param {HTMLElement} box @param {string} source
|
|
24
|
+
* @param {Record<string, any>} [options]
|
|
23
25
|
*/
|
|
24
|
-
mermaid(box: HTMLElement, source: string): Promise<void>;
|
|
26
|
+
mermaid(box: HTMLElement, source: string, options?: Record<string, any>): Promise<void>;
|
|
25
27
|
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export type Context = import('./render.js').Context;
|
|
2
|
+
export type Entry = {
|
|
3
|
+
tokens: any[];
|
|
4
|
+
start: number;
|
|
5
|
+
end: number;
|
|
6
|
+
blocks: {
|
|
7
|
+
token: any;
|
|
8
|
+
start: number;
|
|
9
|
+
}[];
|
|
10
|
+
step: number;
|
|
11
|
+
};
|
|
12
|
+
export type Split = {
|
|
13
|
+
lead: any[] | null;
|
|
14
|
+
leadAt: [number, number] | null;
|
|
15
|
+
rest: any[];
|
|
16
|
+
restAt: [number, number] | null;
|
|
17
|
+
};
|
|
18
|
+
/** A paragraph whose every line starts in bold, as key figures are written without a list. @param {any} token */
|
|
19
|
+
export declare const boldLines: (token: any) => any;
|
|
20
|
+
/**
|
|
21
|
+
* A list's items, or a paragraph's lines that start in bold, as a figure's entries: each one's words (its first line's
|
|
22
|
+
* inline tokens) and where they are in the source, `end` -1 when they run over lines; what is under an item (a list, a
|
|
23
|
+
* chart) its blocks. @param {any} token @param {number} start where its raw starts @param {(markdown: string) => any[]} lex
|
|
24
|
+
* @returns {Entry[]}
|
|
25
|
+
*/
|
|
26
|
+
export declare function entriesOf(token: any, start: number, lex: (markdown: string) => any[]): Entry[];
|
|
27
|
+
/**
|
|
28
|
+
* An entry's lead and the rest of its words, each with where it is in the source: the bold it starts with, else for a
|
|
29
|
+
* programme a time and for key figures a number; what comes between them (a colon, a dash) left out.
|
|
30
|
+
* @param {Entry} entry @param {string} kind @returns {Split}
|
|
31
|
+
*/
|
|
32
|
+
export declare function leadOf(entry: Entry, kind: string): Split;
|
|
33
|
+
/**
|
|
34
|
+
* Where a slot's parts start: at each heading of the level its last heading has, but the heading the slot opens with when
|
|
35
|
+
* there are more of them than the parts asked for (the slide's title, written at their level).
|
|
36
|
+
* @param {any[]} tokens @param {number} count how many parts the layout has @returns {Set<number>}
|
|
37
|
+
*/
|
|
38
|
+
export declare function partHeads(tokens: any[], count: number): Set<number>;
|
|
39
|
+
/**
|
|
40
|
+
* The deck's contents, as Slidev's <Toc> reads them: each slide's title and level, but a slide with `hideInToc: true`,
|
|
41
|
+
* the contents themselves, a cover, an introduction, the end and slides with no title. Where the deck has parts (slides
|
|
42
|
+
* on `section` or `subsection`, or with a `level`), the parts alone, a section at level 1 and a subsection at 2; else
|
|
43
|
+
* every slide, at its heading's level. `hideInToc: false` brings a slide back. Levels start at 1, `maxDepth` at most.
|
|
44
|
+
* @param {import('./parse.js').Slide[]} slides @param {import('./kit.js').Kit} kit @param {number} at the contents' own slide
|
|
45
|
+
* @param {number} [maxDepth] @returns {{ index: number, title: string, level: number }[]}
|
|
46
|
+
*/
|
|
47
|
+
export declare function contentsOf(slides: import('./parse.js').Slide[], kit: import('./kit.js').Kit, at: number, maxDepth?: number): {
|
|
48
|
+
index: number;
|
|
49
|
+
title: string;
|
|
50
|
+
level: number;
|
|
51
|
+
}[];
|
|
52
|
+
/**
|
|
53
|
+
* A slot's lists as the figure its layout draws. Entries a click each (<v-clicks>) show their card, milestone, chevron,
|
|
54
|
+
* row, level or tile at their step. @param {string} kind @param {Entry[]} entries @param {Context} context @returns {HTMLElement}
|
|
55
|
+
*/
|
|
56
|
+
export declare function listFigure(kind: string, entries: Entry[], context: Context): HTMLElement;
|
|
57
|
+
/**
|
|
58
|
+
* A slot's parts as its layout sets them: face to face, the last on the fill, a medallion between each two (versus), or
|
|
59
|
+
* in a grid of two columns, the second, top at the end, on the fill (matrix). Their words stay as they were drawn.
|
|
60
|
+
* @param {string} kind @param {Node[][]} parts @returns {HTMLElement}
|
|
61
|
+
*/
|
|
62
|
+
export declare function partsFigure(kind: string, parts: Node[][]): HTMLElement;
|
|
63
|
+
/**
|
|
64
|
+
* The deck's contents as rows, a part's number and its title, each going to its slide when chosen; a subsection under
|
|
65
|
+
* its section, without a number; in two columns from seven rows. @param {Context} context @param {number} at its own slide
|
|
66
|
+
* @param {number} [maxDepth] @returns {HTMLElement | null}
|
|
67
|
+
*/
|
|
68
|
+
export declare function contentsFigure(context: Context, at: number, maxDepth?: number): HTMLElement | null;
|
package/dist/types/kit.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export type Budget = {
|
|
|
7
7
|
heading_max_words?: number;
|
|
8
8
|
kind?: string;
|
|
9
9
|
};
|
|
10
|
+
export type List = 'bullets' | 'mindmap' | 'steps' | 'metrics' | 'timeline' | 'process' | 'agenda' | 'pyramid' | 'bento';
|
|
10
11
|
export type Layout = {
|
|
11
12
|
label?: Record<string, string> | string;
|
|
12
13
|
intent?: string;
|
|
@@ -22,6 +23,9 @@ export type Layout = {
|
|
|
22
23
|
paper: 'paper' | 'fill' | 'ink' | 'soft';
|
|
23
24
|
title: 'normal' | 'large' | 'huge';
|
|
24
25
|
logo: 'big' | 'small' | 'none';
|
|
26
|
+
lists: List;
|
|
27
|
+
parts: 'none' | 'versus' | 'matrix';
|
|
28
|
+
contents: boolean;
|
|
25
29
|
pptx: string;
|
|
26
30
|
numbered: boolean;
|
|
27
31
|
art?: string[];
|
|
@@ -74,6 +78,18 @@ export declare function mergeKits(...kits: any[]): {
|
|
|
74
78
|
};
|
|
75
79
|
/** A layout's name in a language, else its own name. @param {Layout} layout @param {string} name @param {string} lang */
|
|
76
80
|
export declare function labelOf(layout: Layout, name: string, lang: string): string;
|
|
81
|
+
/**
|
|
82
|
+
* The layout a slide is drawn with: the one it names, by its name or a name brains give it, else the one its content
|
|
83
|
+
* suits. @param {{ index: number, settings: Record<string, any>, slots: { name: string, text: string }[] }} slide @param {Kit} kit
|
|
84
|
+
*/
|
|
85
|
+
export declare function layoutNameOf(slide: {
|
|
86
|
+
index: number;
|
|
87
|
+
settings: Record<string, any>;
|
|
88
|
+
slots: {
|
|
89
|
+
name: string;
|
|
90
|
+
text: string;
|
|
91
|
+
}[];
|
|
92
|
+
}, kit: Kit): string;
|
|
77
93
|
/**
|
|
78
94
|
* The layout a slide that names none is given, from what it holds, as Pandoc's PowerPoint writer
|
|
79
95
|
* chooses: the first slide is the cover; a heading alone, a section; slots beyond the first, the
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export type Item = {
|
|
2
|
+
text: string;
|
|
3
|
+
start: number;
|
|
4
|
+
end: number;
|
|
5
|
+
children: Item[];
|
|
6
|
+
blocks?: {
|
|
7
|
+
lang: string;
|
|
8
|
+
text: string;
|
|
9
|
+
}[];
|
|
10
|
+
step?: boolean;
|
|
11
|
+
element?: HTMLElement;
|
|
12
|
+
};
|
|
13
|
+
export type Box = {
|
|
14
|
+
w: number;
|
|
15
|
+
h: number;
|
|
16
|
+
children: Box[];
|
|
17
|
+
x?: number;
|
|
18
|
+
y?: number;
|
|
19
|
+
side?: number;
|
|
20
|
+
span?: number;
|
|
21
|
+
inner?: number;
|
|
22
|
+
};
|
|
23
|
+
export type Line = {
|
|
24
|
+
branch: number;
|
|
25
|
+
depth: number;
|
|
26
|
+
x1: number;
|
|
27
|
+
y1: number;
|
|
28
|
+
x2: number;
|
|
29
|
+
y2: number;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* A list's items as a tree, by their indentation, as written: each item's words where they are in the source, from
|
|
33
|
+
* `start` (where the list's own text starts), a line that is no item going on with the item above it, a fenced block
|
|
34
|
+
* under an item (a chart, a diagram) that item's to draw.
|
|
35
|
+
* @param {string} raw @param {number} start @returns {Item[]}
|
|
36
|
+
*/
|
|
37
|
+
export declare function itemsOf(raw: string, start: number): Item[];
|
|
38
|
+
/** An item's words as they are compared: no emphasis, no case, one space. @param {string} text */
|
|
39
|
+
export declare const keyOf: (text: string) => string;
|
|
40
|
+
/**
|
|
41
|
+
* Items merged: of siblings with the same words, the first keeps the others' children, at every level; a step if any
|
|
42
|
+
* was one. Items without words stay apart. @param {Item[]} items @returns {Item[]}
|
|
43
|
+
*/
|
|
44
|
+
export declare function mergeItems(items: Item[]): Item[];
|
|
45
|
+
/**
|
|
46
|
+
* A map laid out, its boxes' sizes given (in em): the root's centre at the middle, its branches shared out to the end
|
|
47
|
+
* side (top to bottom) and the start side (bottom to top) so the two are as tall as they can be alike, each child a gap
|
|
48
|
+
* beyond its parent, siblings stacked and centred on it, spaced out further (up to four times) where the map would be
|
|
49
|
+
* flatter than its box (`aspect`, its width over its height). Each box gets its `x` and `y` (its top start corner, from the
|
|
50
|
+
* map's top start corner, mirrored if `rtl`) and its `side` (1 right of the root, -1 left); gives the map's size and its
|
|
51
|
+
* lines, each from a parent's side to its child's.
|
|
52
|
+
* @param {Box} root @param {{ rtl?: boolean, aspect?: number }} [how] @returns {{ width: number, height: number, lines: Line[] }}
|
|
53
|
+
*/
|
|
54
|
+
export declare function layoutMap(root: Box, { rtl, aspect }?: {
|
|
55
|
+
rtl?: boolean;
|
|
56
|
+
aspect?: number;
|
|
57
|
+
}): {
|
|
58
|
+
width: number;
|
|
59
|
+
height: number;
|
|
60
|
+
lines: Line[];
|
|
61
|
+
};
|
|
62
|
+
/** A line as a curve leaving its parent and reaching its child level. @param {Line} line */
|
|
63
|
+
export declare const curveOf: ({ x1, y1, x2, y2 }: Line) => string;
|
|
64
|
+
/**
|
|
65
|
+
* A map drawn by render.js (`.deck-mindmap`, its plane, its lines' SVG with a group a branch, its tree as lists, each
|
|
66
|
+
* item's words a `.deck-map-node`) placed once it is on a page, and again as its words or its box change size: its
|
|
67
|
+
* words where the layout puts them, its lines, the whole shrunk to its box. @param {HTMLElement} map
|
|
68
|
+
*/
|
|
69
|
+
export declare function watchMap(map: HTMLElement): void;
|
package/dist/types/pptx.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @param {import('./deck.js').DeckView} view
|
|
3
3
|
* @param {{ PptxGenJS: any, JSZip: any }} libraries
|
|
4
|
-
* @returns {Promise<{ blob: Blob, report: { slides: number, charts: number, pictures: number, tables: number, placeholders: number } }>}
|
|
4
|
+
* @returns {Promise<{ blob: Blob, report: { slides: number, charts: number, pictures: number, tables: number, placeholders: number, maps: number, figures: number } }>}
|
|
5
5
|
*/
|
|
6
6
|
export declare function toPptx(view: import('./deck.js').DeckView, { PptxGenJS, JSZip }: {
|
|
7
7
|
PptxGenJS: any;
|
|
@@ -14,5 +14,7 @@ export declare function toPptx(view: import('./deck.js').DeckView, { PptxGenJS,
|
|
|
14
14
|
pictures: number;
|
|
15
15
|
tables: number;
|
|
16
16
|
placeholders: number;
|
|
17
|
+
maps: number;
|
|
18
|
+
figures: number;
|
|
17
19
|
};
|
|
18
20
|
}>;
|
package/dist/types/render.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type Slide = import('./parse.js').Slide;
|
|
2
2
|
export type Slot = import('./parse.js').Slot;
|
|
3
|
-
export type Drawer = (element: HTMLElement, source: string) => void | Promise<void>;
|
|
3
|
+
export type Drawer = (element: HTMLElement, source: string, options?: Record<string, any>) => void | Promise<void>;
|
|
4
4
|
export type Context = {
|
|
5
5
|
blocks: Record<string, Drawer>;
|
|
6
6
|
resolve: (src: string) => string | null;
|
|
@@ -10,11 +10,12 @@ export type Context = {
|
|
|
10
10
|
kit: import('./kit.js').Kit;
|
|
11
11
|
lex: (markdown: string) => any[];
|
|
12
12
|
slide: string;
|
|
13
|
+
deck?: import('./parse.js').Deck;
|
|
13
14
|
};
|
|
14
15
|
/** @typedef {import('./parse.js').Slide} Slide */
|
|
15
16
|
/** @typedef {import('./parse.js').Slot} Slot */
|
|
16
|
-
/** @typedef {(element: HTMLElement, source: string) => void | Promise<void>} Drawer */
|
|
17
|
-
/** @typedef {{ blocks: Record<string, Drawer>, resolve: (src: string) => string | null, headings: 'real' | 'aria', number: (n: number) => string, total: number, kit: import('./kit.js').Kit, lex: (markdown: string) => any[], slide: string }} Context */
|
|
17
|
+
/** @typedef {(element: HTMLElement, source: string, options?: Record<string, any>) => void | Promise<void>} Drawer */
|
|
18
|
+
/** @typedef {{ blocks: Record<string, Drawer>, resolve: (src: string) => string | null, headings: 'real' | 'aria', number: (n: number) => string, total: number, kit: import('./kit.js').Kit, lex: (markdown: string) => any[], slide: string, deck?: import('./parse.js').Deck }} Context */
|
|
18
19
|
/**
|
|
19
20
|
* @param {string} tag @param {Record<string, string | number | boolean | undefined>} [attributes]
|
|
20
21
|
* @param {(Node | string | null | undefined | false)[]} [children]
|
|
@@ -30,5 +31,22 @@ export declare function renderSlide(slide: Slide, context: Context): {
|
|
|
30
31
|
element: HTMLElement;
|
|
31
32
|
steps: number;
|
|
32
33
|
};
|
|
34
|
+
/** @param {Element} element @param {number} n */
|
|
35
|
+
export declare const step: (element: Element, n: number) => void;
|
|
36
|
+
/**
|
|
37
|
+
* @param {any} token @param {number} start where its raw starts in the source
|
|
38
|
+
* @param {Context} context @param {{ step: number } | null} stepped list items each a step
|
|
39
|
+
* @returns {HTMLElement | null}
|
|
40
|
+
*/
|
|
41
|
+
export declare function block(token: any, start: number, context: Context, stepped: {
|
|
42
|
+
step: number;
|
|
43
|
+
} | null): HTMLElement | null;
|
|
44
|
+
/**
|
|
45
|
+
* The options after a fence's language, as Slidev writes them (`mermaid {theme: 'neutral', scale: 0.8}`), read as YAML's
|
|
46
|
+
* flow, which JSON is too; none if they don't read. @param {string} info @returns {Record<string, any>}
|
|
47
|
+
*/
|
|
48
|
+
export declare function optionsOf(info: string): Record<string, any>;
|
|
49
|
+
/** @param {number} from @param {number} to */
|
|
50
|
+
export declare const range: (from: number, to: number) => string | undefined;
|
|
33
51
|
/** @param {any[]} tokens @param {Context} context @returns {Node[]} */
|
|
34
52
|
export declare function inline(tokens: any[] | undefined, context: Context): Node[];
|
package/dist/types/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "0.
|
|
1
|
+
export declare const VERSION = "0.4.0";
|
package/docs/format.md
CHANGED
|
@@ -36,13 +36,16 @@ Slidev's form, as `@slidev/parser` splits it, and the parts a deck for knowledge
|
|
|
36
36
|
|
|
37
37
|
- **Slides** between lines holding only `---`. A `---` followed by a `key:` line opens that slide's settings, YAML up to the next `---` line; a ` ```yaml ` block at a slide's top does the same.
|
|
38
38
|
- **The first slide's settings** are the deck's too (its headmatter): `title`, `lang`, `dir`, `colorSchema` (`auto`, `light`, `dark`), `transition`, `theme`, `themeConfig`, `kit`.
|
|
39
|
-
- **A slide's settings:** `layout`, `transition` (`slide-left`, `slide-right`, `slide-up`, `fade`, `view-transition`; `a | b` for forward and back), `class` (`invert`, `text-center`), `image`, `background`, `alt`, `title`, `paginate
|
|
39
|
+
- **A slide's settings:** `layout`, `transition` (`slide-left`, `slide-right`, `slide-up`, `fade`, `view-transition`; `a | b` for forward and back), `class` (`invert`, `text-center`), `image`, `background`, `alt`, `title`, `paginate`, and for the deck's contents `hideInToc`, `level` and, on the contents' own slide, `maxDepth`, as Slidev names them.
|
|
40
40
|
- **Slots:** `::name::` alone on a line starts the slot of that name; what comes before is `default`.
|
|
41
41
|
- **Notes:** the last HTML comment at a slide's end.
|
|
42
42
|
- **Steps:** `<v-clicks>` and `</v-clicks>` around a list, each on its own line with empty lines around; `<v-click>` around a block.
|
|
43
43
|
- **Code** in fences, with lines marked as Slidev marks them: ` ```ts {2,4-5} `.
|
|
44
|
-
- **Charts:** ` ```echarts ` holding an ECharts option as JSON, data only.
|
|
45
|
-
- **Diagrams:** ` ```mermaid ` holding Mermaid's language.
|
|
44
|
+
- **Charts:** ` ```echarts ` holding an ECharts option as JSON, data only, drawn by ECharts in the deck's colours and type.
|
|
45
|
+
- **Diagrams:** ` ```mermaid ` holding Mermaid's language, drawn by Pele, with its own settings (a `---` block with `config:`, `%%{init: {…}}%%`); its colours, a pie's and a chart's too, are the deck's, light or dark.
|
|
46
|
+
- **A fence's options,** after its language as Slidev writes them, YAML's flow or JSON: ` ```mermaid {scale: 0.8} ` takes at most that share of its box; the others go to Pele as its settings (`theme` aside: the colours are the deck's). They reach a host's drawer as its third argument.
|
|
47
|
+
- **Mind maps:** `layout: mindmap`, its lists drawn as one map (below).
|
|
48
|
+
- **Figures:** a layout that draws a slide's lists as cards, key figures, a timeline, chevrons, a programme, a pyramid or a bento, sets its `##` parts face to face or in a matrix, or shows the deck's contents (below).
|
|
46
49
|
- **Markdown** as CommonMark and GFM have it: headings, lists, task lists, tables, quotes, emphasis, links, pictures. A picture alone on its line fills what its slot leaves, whole, whatever its own size.
|
|
47
50
|
|
|
48
51
|
### Added by deck
|
|
@@ -51,6 +54,84 @@ Slidev's form, as `@slidev/parser` splits it, and the parts a deck for knowledge
|
|
|
51
54
|
- `kit`: tokens and layouts as data ([kits.md](kits.md)).
|
|
52
55
|
- A layout chosen from what a slide holds when it names none.
|
|
53
56
|
- A Morph between two slides that share a heading, a picture or a list item, with `transition: view-transition`.
|
|
57
|
+
- A mind map: a slide on `layout: mindmap` (or a kit's layout with `lists: mindmap`) draws its lists as one map.
|
|
58
|
+
- Figures drawn from a slide's lists or parts, and the deck's contents, by the layouts below.
|
|
59
|
+
|
|
60
|
+
### A mind map
|
|
61
|
+
|
|
62
|
+
````md
|
|
63
|
+
---
|
|
64
|
+
layout: mindmap
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## What a second oven changes
|
|
68
|
+
|
|
69
|
+
### Mornings
|
|
70
|
+
|
|
71
|
+
- Croissants until noon
|
|
72
|
+
- No queue at 7
|
|
73
|
+
|
|
74
|
+
### Bread
|
|
75
|
+
|
|
76
|
+
- A batch at noon
|
|
77
|
+
- For the lunch crowd
|
|
78
|
+
- Rye on Fridays
|
|
79
|
+
|
|
80
|
+
### Mornings
|
|
81
|
+
|
|
82
|
+
- Coffee with the first batch
|
|
83
|
+
````
|
|
84
|
+
|
|
85
|
+
- **Each item a node,** its indentation its branching, at any depth, with any marker; a line that is no item goes on with the item above it.
|
|
86
|
+
- **Every list on the slide is merged into one map.** A heading just before a list, other than the one the slide opens with, is that list's node. Items with the same words at the same place (emphasis and case aside) are one node, their children together: the slide above has one `Mornings`, with three children.
|
|
87
|
+
- **One root.** When the lists come down to one item, it is the root, and the heading the slide opens with stays its title, unless it says the same. Else the heading the slide opens with is the root, drawn in the middle of the map and not above it; with none, a dot.
|
|
88
|
+
- **Laid out** as maps are drawn by hand: the root in the middle, its branches shared out to either side, clockwise from the side a line ends (the right, the left right to left), each branch in a colour of the charts', the whole shrunk to what the slide leaves it and spread out to its height. Paragraphs before or after the lists stay above or under the map.
|
|
89
|
+
- **Steps:** lists inside `<v-clicks>` show one branch a click.
|
|
90
|
+
- **A chart or a diagram in a node:** a ` ```echarts ` or ` ```mermaid ` block fenced under an item, indented with it, is drawn in that item's node, under its words, at a size of its own.
|
|
91
|
+
- **Changed in place,** each node's words as a list item's are, and in PowerPoint as its own shapes: a box with words for each node, a curve for each line.
|
|
92
|
+
|
|
93
|
+
### Figures
|
|
94
|
+
|
|
95
|
+
A slide on one of these layouts says what it shows in plain Markdown; the layout draws it. An item's **lead** is the bold it starts with, its label; the rest of its line is its words; a colon or a dash between them is left out. Everything else on the slide (its heading, a line above or under) stays where it is.
|
|
96
|
+
|
|
97
|
+
| Layout | Written as | Drawn as |
|
|
98
|
+
|---|---|---|
|
|
99
|
+
| `summary` | a heading | the deck's contents under it (below) |
|
|
100
|
+
| `section`, `subsection` | a heading alone | a part's title, on ink; a subsection's, smaller, on the soft fill |
|
|
101
|
+
| `statement` | one sentence | the sentence, large, in the middle |
|
|
102
|
+
| `quote` | `> words`, who said them under it; `image:` | the quote, over the picture filling the slide behind a veil when it has one |
|
|
103
|
+
| `steps` | `- **Find** bakers through the school` | a row of cards, one an item, each numbered |
|
|
104
|
+
| `metrics` | `- **56%** of people`, or lines `**56%** of people` | a row of 2 to 4 key figures, big, each over what it counts; a number starting a line is its lead too |
|
|
105
|
+
| `timeline` | `- **Q1** The shop fitted` | milestones along a line, each lead over its dot, its words under it |
|
|
106
|
+
| `process` | `1. **Sign** the lease` | chevrons, each holding a step's lead, its words under it, pointing the way the language reads |
|
|
107
|
+
| `agenda` | `- **6:00 PM** Doors open` | a programme, a time and its words a row, in two columns from seven rows; a time starting a line is its lead too |
|
|
108
|
+
| `pyramid` | `- **Love** They tell their friends` | levels stacked, the first the narrowest, on top, the last the widest; each level's words beside it |
|
|
109
|
+
| `bento` | `- **A terrace** for forty` | a mosaic: the first item a big tile on the fill, the next 2 to 4 tiles around it |
|
|
110
|
+
| `versus` | two `##` parts, each with its words | face to face, a "VS" medallion between them, the second on the fill |
|
|
111
|
+
| `matrix` | four `##` parts | a grid of two by two, the top one at the end (the second) on the fill |
|
|
112
|
+
|
|
113
|
+
- **Items** are every list's on the slide, in order, at their first list's place; an item's own list, chart or diagram, indented under it, is drawn in its card, tile or row. Lines that all start in bold are items too, as key figures are often written without a list.
|
|
114
|
+
- **Parts** start at each heading of the level the slide's last heading has. The heading the slide opens with is its title when it is of a higher level (`#` over `##` parts), or when there is one more heading of their level than the parts (`## Where to open`, then two `##`). Parts take everything under their heading: paragraphs, lists, a chart.
|
|
115
|
+
- **Steps:** items in `<v-clicks>` show one a click; a `<v-click>` around a list shows the whole figure at once; a `<v-click>` in a part, that block.
|
|
116
|
+
- **Right to left,** the figures are mirrored: chevrons point left, the timeline and cards run from the right, the second part sits on the left.
|
|
117
|
+
- **Changed in place,** a lead and its words each, as a list item's words are, when the item is one line.
|
|
118
|
+
- **In PowerPoint,** each figure is PowerPoint's own shapes (cards, chevrons and levels as their outlines, dots, rules) and boxes of words, where the slide has them.
|
|
119
|
+
|
|
120
|
+
### The deck's contents
|
|
121
|
+
|
|
122
|
+
````md
|
|
123
|
+
---
|
|
124
|
+
layout: summary
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## What we will cover
|
|
128
|
+
````
|
|
129
|
+
|
|
130
|
+
`summary` lists the deck's parts under the slide's own words, as Slidev's `<Toc>` reads them: each slide's `title`, else its first heading. A slide with `hideInToc: true` is left out, as are the contents' own slide, a cover, an introduction, the end and slides with no title; `hideInToc: false` brings one back.
|
|
131
|
+
|
|
132
|
+
- **Where the deck has parts** (slides on `section` or `subsection`, or with a `level`), the contents are the parts: a section at level 1, numbered, its subsections under it. Else they are every slide with a title, at its heading's level.
|
|
133
|
+
- **`maxDepth`** on the contents' slide keeps the levels above it (2 by default, 1 for sections alone).
|
|
134
|
+
- **In two columns** from seven rows. Each row goes to its slide when chosen (a click, or Enter).
|
|
54
135
|
|
|
55
136
|
### Also read, as brains write it
|
|
56
137
|
|
|
@@ -61,7 +142,7 @@ Brains blend dialects. These are read, never rewritten:
|
|
|
61
142
|
- Slides at headings of the first two levels when a deck has no `---` at all, as Pandoc splits a document.
|
|
62
143
|
- Steps written as `<li v-click>`.
|
|
63
144
|
- A `---` followed by words, which Slidev would take for settings, as a new slide.
|
|
64
|
-
- Names brains give layouts: `title`, `two-columns`, `comparison`, `divider`, `thanks`…
|
|
145
|
+
- Names brains give layouts: `title`, `two-columns`, `comparison`, `divider`, `thanks`, `toc`, `kpis`, `roadmap`, `schedule`, `vs`, `quadrant`…
|
|
65
146
|
|
|
66
147
|
`deckIn(answer)` finds a deck in a brain's answer and mends what brains get wrong most: a deck fenced as ` ```markdown ` or with nothing, a chart's fence inside three backticks, settings after an empty line, steps without their empty lines, a chart fenced as ` ```json `, words after a slot's marker.
|
|
67
148
|
|
package/docs/host.md
CHANGED
|
@@ -12,7 +12,7 @@ const view = createDeck(document.querySelector('#deck'), {
|
|
|
12
12
|
lang: 'fr', dir: 'ltr', // else the deck's own, else the page's
|
|
13
13
|
kit, // the host's kit: an organisation's, a person's, a project's, merged
|
|
14
14
|
scheme: 'auto', // 'light', 'dark' or 'auto', over the deck's colorSchema
|
|
15
|
-
blocks: { echarts, mermaid }, // drawers for fenced blocks: (box, source) => void | Promise<void
|
|
15
|
+
blocks: { echarts, mermaid }, // drawers for fenced blocks: (box, source, options) => void | Promise<void>, options those after the fence's language
|
|
16
16
|
resolve: (src) => url, // a picture's address as the page can load it, or null
|
|
17
17
|
strings, // the bar's words, and `slide` and `carousel` for screen readers, else deck's own (en, fr, ar, ja)
|
|
18
18
|
lex: (markdown) => tokens, // how a slide's Markdown is read: the host's own marked, its extensions too; else marked's GFM
|
|
@@ -32,7 +32,7 @@ Every block that can be changed by hand carries `data-edit="from-to"`, the offse
|
|
|
32
32
|
|
|
33
33
|
## Drawers
|
|
34
34
|
|
|
35
|
-
`defaultBlocks({ base, root, versions })` gives the drawers a file uses alone: ECharts as SVG in the deck's colours and type, its category axis mirrored right to left; Pele for Mermaid's language, its SVG shown as a picture coloured by Pele's variables, its words the picture's text
|
|
35
|
+
`defaultBlocks({ base, root, versions })` gives the drawers a file uses alone: ECharts as SVG in the deck's colours and type, its category axis mirrored right to left; Pele for Mermaid's language, its SVG shown as a picture coloured by Pele's variables (its charts' series too), again when the scheme changes, its words the picture's text, the fence's options its settings and `scale`. Each library loads the first time a slide needs it, from `base` (jsDelivr's npm mirror, or a `node_modules/` folder, `libraryAt()`). A host with a strict policy gives its own: Pele's SVG holds style attributes, so it belongs in an image or a worker's output, not in the page's DOM.
|
|
36
36
|
|
|
37
37
|
## PowerPoint
|
|
38
38
|
|
|
@@ -42,7 +42,7 @@ const { blob, report } = await toPptx(view, { PptxGenJS, JSZip })
|
|
|
42
42
|
|
|
43
43
|
A kit from a PowerPoint template, and a kit's tokens out, are `@codename/deck/template`'s (`kitFromTemplate`, `tokensToDtcg`, [kits.md](kits.md)), which a host imports only when it reads or writes one; `logoOf` and `CORNERS` check a kit's logo and its corner before it is kept, and `rgbOf` a colour as deck reads it.
|
|
44
44
|
|
|
45
|
-
PptxGenJS 4 (its bundle carries JSZip) is the host's to load, on demand. The file is made from the deck as drawn: a slide layout per deck layout, named by its label in the deck's language, with a placeholder for its title and each slot; lists as lists with their levels; tables; bars, lines, areas, pies, rings, points and radars as native charts with their numbers, other charts and diagrams as pictures, and pictures, alone on their line or beside the words, as pictures; a layout's art as one picture on its slide layout; notes; transitions; the kit's colours as the theme. `report` counts slides, charts, tables, pictures and
|
|
45
|
+
PptxGenJS 4 (its bundle carries JSZip) is the host's to load, on demand. The file is made from the deck as drawn: a slide layout per deck layout, named by its label in the deck's language, with a placeholder for its title and each slot; lists as lists with their levels; tables; mind maps as PowerPoint's own shapes, a box with words for each node and a curve for each line; figures (cards, key figures, timelines, chevrons, programmes, pyramids, bentos, parts face to face or in a matrix, the deck's contents) as PowerPoint's own shapes and boxes of words, a quote's veil over its picture as a see-through rectangle; bars, lines, areas, pies, rings, points and radars as native charts with their numbers, other charts and diagrams as pictures, and pictures, alone on their line or beside the words, as pictures; a layout's art as one picture on its slide layout; notes; transitions; the kit's colours as the theme. `report` counts slides, charts, tables, pictures, placeholders, mind maps and figures.
|
|
46
46
|
|
|
47
47
|
## Files
|
|
48
48
|
|
package/docs/kits.md
CHANGED
|
@@ -55,6 +55,9 @@ A logo shows in its corner, small, or big where a layout says (`logo`: a cover,
|
|
|
55
55
|
| `paper` | `paper`, `fill` (the primary), `ink`, `soft` | `paper` |
|
|
56
56
|
| `title` | `normal`, `large`, `huge` | `normal` |
|
|
57
57
|
| `logo` | `small`, `big`, `none`: how the kit's logo shows | `small`; `big` on `cover`, `intro`, `end`; `none` on `image`, `full`, `none` |
|
|
58
|
+
| `lists` | `bullets`, `mindmap`, `steps`, `metrics`, `timeline`, `process`, `agenda`, `pyramid`, `bento`: each slot's lists as lists, merged into one mind map ([format.md](format.md#a-mind-map)), or drawn as that figure ([format.md](format.md#figures)) | `bullets`; the layout's name on deck's own |
|
|
59
|
+
| `parts` | `none`, `versus`, `matrix`: each slot's `##` parts as they come, face to face, or in a grid of two by two; over `lists` | `none`; `versus` and `matrix` on deck's own |
|
|
60
|
+
| `contents` | `true` for the deck's contents under the slot's words ([format.md](format.md#the-decks-contents)) | `false`; `true` on `summary` |
|
|
58
61
|
| `pptx` | Title Slide, Title and Content, Section Header, Two Content, Comparison, Title Only, Blank, Content with Caption, Picture with Caption | by its slots |
|
|
59
62
|
| `numbered` | `false` for no slide number | `true` |
|
|
60
63
|
| `art` | Up to 8 names of the kit's `pictures`, drawn over the whole slide, layer over layer, behind the words, as a template draws them | none |
|
|
@@ -84,13 +87,18 @@ Each layout's art is what a slide on it shows besides its placeholders, as SVG l
|
|
|
84
87
|
|---|---|---|
|
|
85
88
|
| `cover`, `intro`, `end` | one | Title Slide |
|
|
86
89
|
| `default` | one | Title and Content |
|
|
87
|
-
| `section` | one | Section Header |
|
|
90
|
+
| `section`, `subsection` | one | Section Header |
|
|
91
|
+
| `summary` | one, the deck's contents under it | Title and Content |
|
|
88
92
|
| `two-cols` | `default`, `right` | Two Content |
|
|
89
93
|
| `two-cols-header` | `default` across, `left`, `right`, `bottom` | Comparison |
|
|
90
94
|
| `three-cols` | `default` across, `left`, `middle`, `right` | Comparison |
|
|
91
|
-
| `center`, `statement`, `fact
|
|
95
|
+
| `center`, `statement`, `fact` | one | Title Only |
|
|
96
|
+
| `quote` | one, over the slide's `image` when it has one | Title Only |
|
|
92
97
|
| `image-left`, `image-right` | one, beside the slide's `image` | Picture with Caption |
|
|
93
98
|
| `image`, `full`, `none` | one | Blank |
|
|
99
|
+
| `mindmap` | one, its lists as one mind map | Title Only |
|
|
100
|
+
| `steps`, `metrics`, `timeline`, `process`, `agenda`, `pyramid`, `bento` | one, its lists as that figure | Title Only |
|
|
101
|
+
| `versus`, `matrix` | one, its parts face to face or in a matrix | Title Only |
|
|
94
102
|
|
|
95
103
|
## A slide that names none
|
|
96
104
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codename/deck",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Slide decks as one web page: Markdown in Slidev's form inside a .deck.html file any browser presents, a renderer that runs anywhere, kits of layouts and looks, and an editable PowerPoint out",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
package/src/blocks.js
CHANGED
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
// from `base` (a CDN by default) the first time a slide needs it, never before. A chart is data,
|
|
3
3
|
// read with JSON.parse; it takes the deck's colours and type, light or dark, and is drawn as SVG.
|
|
4
4
|
// A diagram is drawn by Pele from Mermaid's language as SVG, then shown as a picture, so nothing it
|
|
5
|
-
// makes runs or joins the page; its words are its picture's text for whoever can't see it
|
|
6
|
-
//
|
|
5
|
+
// makes runs or joins the page; its words are its picture's text for whoever can't see it; its colours
|
|
6
|
+
// (a pie's, a chart's too) are the deck's, again when the scheme changes. Options after a fence's
|
|
7
|
+
// language, as Slidev writes them (```mermaid {scale: 0.8}), reach the drawer. A host gives its own
|
|
8
|
+
// drawers instead.
|
|
7
9
|
|
|
8
10
|
/** @typedef {{ base: string, root: HTMLElement, versions?: { echarts?: string, pele?: string } }} Where */
|
|
9
11
|
|
|
@@ -34,12 +36,22 @@ export function defaultBlocks({ base, root, versions = {} }) {
|
|
|
34
36
|
const { echarts: chartsAt = '6.1.0', pele: diagramsAt = '1.10.0' } = versions
|
|
35
37
|
/** @type {Set<{ chart: any, option: any, box: HTMLElement }>} */
|
|
36
38
|
const charts = new Set()
|
|
39
|
+
/** @type {Set<{ picture: HTMLImageElement, svg: string }>} */
|
|
40
|
+
const diagrams = new Set()
|
|
37
41
|
/** @type {any} */
|
|
38
42
|
let colours = null
|
|
39
43
|
root.addEventListener('deck-scheme', (event) => {
|
|
40
44
|
colours = /** @type {CustomEvent} */ (event).detail.colours
|
|
41
45
|
for (const one of charts) one.chart.setOption(themed(one.option, one.box), true)
|
|
46
|
+
for (const one of diagrams) one.picture.src = pictured(one.svg)
|
|
42
47
|
})
|
|
48
|
+
// A diagram's SVG as a picture in the deck's colours, set as Pele's variables inside it.
|
|
49
|
+
const pictured = (/** @type {string} */ svg) => {
|
|
50
|
+
const font = getComputedStyle(root).getPropertyValue('--deck-body') || 'system-ui, sans-serif'
|
|
51
|
+
const series = Array.from({ length: 8 }, (_, n) => `--pele-series-${n + 1}:${colours?.series?.[n % (colours?.series?.length || 1)]}`).join(';')
|
|
52
|
+
const look = `--pele-bg:transparent;--pele-fg:${colours?.ink};--pele-muted:${colours?.muted};--pele-line:${colours?.muted};--pele-surface:${colours?.soft};--pele-surface-alt:${colours?.line};--pele-border:${colours?.primary};--pele-accent:${colours?.primary};${series};--pele-font:${font.replace(/[<>"]/g, '')}`
|
|
53
|
+
return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg.replace(/^(<svg\b[^>]*>)/, `$1<style>svg{${look}}</style>`))}`
|
|
54
|
+
}
|
|
43
55
|
// Its type sized with the slide's, its category axis read from the right in a language written so.
|
|
44
56
|
const themed = (/** @type {any} */ option, /** @type {HTMLElement} */ box) => {
|
|
45
57
|
const size = parseFloat(getComputedStyle(box).fontSize) || 16
|
|
@@ -61,7 +73,7 @@ export function defaultBlocks({ base, root, versions = {} }) {
|
|
|
61
73
|
}
|
|
62
74
|
}
|
|
63
75
|
return {
|
|
64
|
-
/** @param {HTMLElement} box @param {string} source */
|
|
76
|
+
/** @param {HTMLElement} box @param {string} source the chart's option, as JSON */
|
|
65
77
|
async echarts(box, source) {
|
|
66
78
|
const option = JSON.parse(source)
|
|
67
79
|
const echarts = await script(libraryAt(base, 'echarts', chartsAt, 'dist/echarts.min.js'), 'echarts')
|
|
@@ -79,17 +91,22 @@ export function defaultBlocks({ base, root, versions = {} }) {
|
|
|
79
91
|
},
|
|
80
92
|
/**
|
|
81
93
|
* A diagram written in Mermaid's language, drawn by Pele (Obsidian's, MIT): every kind Mermaid
|
|
82
|
-
* 12.1 has, no DOM needed, an SVG with no script or HTML in it
|
|
83
|
-
*
|
|
94
|
+
* 12.1 has, no DOM needed, an SVG with no script or HTML in it; its own settings (a `---` config
|
|
95
|
+
* block, `%%{init: …}%%`) read by Pele, the fence's options too, `scale` the share of its box it
|
|
96
|
+
* takes. Shown as a picture, its colours the deck's. @param {HTMLElement} box @param {string} source
|
|
97
|
+
* @param {Record<string, any>} [options]
|
|
84
98
|
*/
|
|
85
|
-
async mermaid(box, source) {
|
|
99
|
+
async mermaid(box, source, options = {}) {
|
|
86
100
|
const pele = await script(libraryAt(base, 'pele', diagramsAt, 'dist/pele.global.js'), 'pele')
|
|
87
101
|
const font = getComputedStyle(root).getPropertyValue('--deck-body') || 'system-ui, sans-serif'
|
|
88
|
-
const {
|
|
89
|
-
const
|
|
102
|
+
const { scale, theme, ...config } = options
|
|
103
|
+
const { svg } = pele.render(source, { fontFamily: font, links: false, images: false, autoDirection: true, maxWidth: Math.max(320, box.clientWidth * 1.4), ...(Object.keys(config).length && { config }) })
|
|
90
104
|
const picture = document.createElement('img')
|
|
91
105
|
picture.alt = source
|
|
92
|
-
picture.src =
|
|
106
|
+
picture.src = pictured(svg)
|
|
107
|
+
const share = Number(scale)
|
|
108
|
+
if (share > 0 && share < 1) for (const side of ['max-inline-size', 'max-block-size']) picture.style.setProperty(side, `${share * 100}%`)
|
|
109
|
+
diagrams.add({ picture, svg })
|
|
93
110
|
const place = document.createElement('div')
|
|
94
111
|
place.className = 'deck-diagram'
|
|
95
112
|
place.append(picture)
|