@elyracode/anna 0.5.4
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 +58 -0
- package/extensions/index.ts +249 -0
- package/package.json +27 -0
- package/skills/anna-js/SKILL.md +345 -0
package/README.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# @elyracode/anna
|
|
2
|
+
|
|
3
|
+
Elyra extension for **Anna.js** -- generate, preview, and build Markdown presentations with terminal animations, live code, Mermaid diagrams, and audience interaction.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
elyra install npm:@elyracode/anna
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Requires Anna.js CLI:
|
|
12
|
+
```
|
|
13
|
+
npm install -g @kwhorne/anna.js
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Tools
|
|
17
|
+
|
|
18
|
+
| Tool | Description |
|
|
19
|
+
|------|-------------|
|
|
20
|
+
| `generate_presentation` | Generate a complete Anna.js presentation from a topic or project context |
|
|
21
|
+
| `preview_presentation` | Start dev server with live reload and open in browser |
|
|
22
|
+
| `build_presentation` | Generate self-contained HTML (with optional offline/PWA support) |
|
|
23
|
+
|
|
24
|
+
## Commands
|
|
25
|
+
|
|
26
|
+
| Command | Description |
|
|
27
|
+
|---------|-------------|
|
|
28
|
+
| `/presentation [topic]` | Generate a new presentation |
|
|
29
|
+
| `/slides [file]` | Preview an existing presentation |
|
|
30
|
+
|
|
31
|
+
## Skills
|
|
32
|
+
|
|
33
|
+
The `anna-js` skill provides the complete Anna.js syntax reference so the agent generates correct Markdown including slides, fragments, terminal animations, live code playgrounds, Mermaid diagrams, component layouts, speaker notes, and themes.
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
> Create a presentation about our project architecture
|
|
39
|
+
> Generate slides for a Kubernetes intro with terminal demos and diagrams
|
|
40
|
+
> Add a slide with a Mermaid flowchart showing the auth flow
|
|
41
|
+
> Preview slides.md in the browser
|
|
42
|
+
> Build the presentation as offline HTML
|
|
43
|
+
/presentation API onboarding guide
|
|
44
|
+
/slides
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Features
|
|
48
|
+
|
|
49
|
+
The agent can generate presentations with:
|
|
50
|
+
- **Slides** with horizontal (`---`) and vertical (`--`) navigation
|
|
51
|
+
- **Fragments** for step-by-step reveals
|
|
52
|
+
- **Terminal animations** with realistic typing effects
|
|
53
|
+
- **Live code playgrounds** (JS, HTML, CSS) with console output
|
|
54
|
+
- **Mermaid diagrams** (flowcharts, sequence, gantt, etc.)
|
|
55
|
+
- **Component layouts** (columns, comparison, timeline, stats, cards, quotes)
|
|
56
|
+
- **Speaker notes** and keyboard shortcuts
|
|
57
|
+
- **11 themes** (dark and light)
|
|
58
|
+
- **Offline/PWA** mode for conferences without WiFi
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import type { ExtensionAPI } from "@elyracode/coding-agent";
|
|
5
|
+
import { Type } from "typebox";
|
|
6
|
+
|
|
7
|
+
export default function (elyra: ExtensionAPI): void {
|
|
8
|
+
|
|
9
|
+
// ── Tool: generate_presentation ──
|
|
10
|
+
elyra.registerTool({
|
|
11
|
+
name: "generate_presentation",
|
|
12
|
+
label: "Generate Presentation",
|
|
13
|
+
description:
|
|
14
|
+
"Generate an Anna.js Markdown presentation from a description or project context. " +
|
|
15
|
+
"Creates a complete .md file with slides, fragments, diagrams, terminal animations, " +
|
|
16
|
+
"and code playgrounds. Use the anna-js skill for correct syntax. " +
|
|
17
|
+
"The presentation can be previewed with `anna serve`.",
|
|
18
|
+
parameters: Type.Object({
|
|
19
|
+
topic: Type.String({
|
|
20
|
+
description: "Topic or description for the presentation (e.g., 'Project architecture overview', 'API onboarding guide')",
|
|
21
|
+
}),
|
|
22
|
+
output: Type.Optional(
|
|
23
|
+
Type.String({ description: "Output file path (default: slides.md)" }),
|
|
24
|
+
),
|
|
25
|
+
theme: Type.Optional(
|
|
26
|
+
Type.String({ description: "Theme: league, moon, night, black, blood, white, beige, sky, serif, simple, solarized (default: moon)" }),
|
|
27
|
+
),
|
|
28
|
+
slides: Type.Optional(
|
|
29
|
+
Type.Number({ description: "Approximate number of slides (default: 10)" }),
|
|
30
|
+
),
|
|
31
|
+
features: Type.Optional(
|
|
32
|
+
Type.Array(Type.String(), {
|
|
33
|
+
description: "Features to include: terminal, playground, mermaid, fragments, components (default: all)",
|
|
34
|
+
}),
|
|
35
|
+
),
|
|
36
|
+
}),
|
|
37
|
+
execute: async (_toolCallId, params) => {
|
|
38
|
+
const output = params.output ?? "slides.md";
|
|
39
|
+
const theme = params.theme ?? "moon";
|
|
40
|
+
const slideCount = params.slides ?? 10;
|
|
41
|
+
const features = params.features ?? ["terminal", "playground", "mermaid", "fragments", "components"];
|
|
42
|
+
|
|
43
|
+
const instructions: string[] = [
|
|
44
|
+
`# Generate Anna.js Presentation`,
|
|
45
|
+
"",
|
|
46
|
+
`**Topic**: ${params.topic}`,
|
|
47
|
+
`**Output file**: ${output}`,
|
|
48
|
+
`**Theme**: ${theme}`,
|
|
49
|
+
`**Target slides**: ~${slideCount}`,
|
|
50
|
+
`**Features**: ${features.join(", ")}`,
|
|
51
|
+
"",
|
|
52
|
+
"## Instructions",
|
|
53
|
+
"",
|
|
54
|
+
"Write a complete Anna.js Markdown presentation file. Requirements:",
|
|
55
|
+
"",
|
|
56
|
+
"1. Start with YAML frontmatter (title, theme, transition)",
|
|
57
|
+
"2. Use `---` for horizontal slide separators",
|
|
58
|
+
"3. Use `--` for vertical sub-slides where appropriate",
|
|
59
|
+
"4. Use `<!-- .fragments -->` for step-by-step reveals on lists",
|
|
60
|
+
"5. Add speaker notes with `Note:` where helpful",
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
if (features.includes("terminal")) {
|
|
64
|
+
instructions.push("6. Include ````terminal` blocks for CLI demos with realistic commands");
|
|
65
|
+
}
|
|
66
|
+
if (features.includes("playground")) {
|
|
67
|
+
instructions.push("7. Include ````playground` blocks for live code examples");
|
|
68
|
+
}
|
|
69
|
+
if (features.includes("mermaid")) {
|
|
70
|
+
instructions.push("8. Include ````mermaid` blocks for architecture/flow diagrams");
|
|
71
|
+
}
|
|
72
|
+
if (features.includes("components")) {
|
|
73
|
+
instructions.push("9. Use layout components (`<!-- @columns -->`, `<!-- @stats -->`, `<!-- @timeline -->`) for visual variety");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
instructions.push(
|
|
77
|
+
"",
|
|
78
|
+
`Write the presentation to \`${output}\` using the write tool.`,
|
|
79
|
+
"Make it visually engaging with a mix of text, code, and diagrams.",
|
|
80
|
+
"End with a clear summary/thank-you slide.",
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
content: [{ type: "text", text: instructions.join("\n") }],
|
|
85
|
+
details: { output, theme, slideCount },
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// ── Tool: preview_presentation ──
|
|
91
|
+
elyra.registerTool({
|
|
92
|
+
name: "preview_presentation",
|
|
93
|
+
label: "Preview Presentation",
|
|
94
|
+
description:
|
|
95
|
+
"Start the Anna.js dev server to preview a presentation in the browser. " +
|
|
96
|
+
"Opens the presentation with live reload -- edits to the .md file update instantly. " +
|
|
97
|
+
"Requires @kwhorne/anna.js to be installed globally.",
|
|
98
|
+
parameters: Type.Object({
|
|
99
|
+
file: Type.Optional(
|
|
100
|
+
Type.String({ description: "Markdown file to preview (default: slides.md)" }),
|
|
101
|
+
),
|
|
102
|
+
port: Type.Optional(
|
|
103
|
+
Type.Number({ description: "Server port (default: 3000)" }),
|
|
104
|
+
),
|
|
105
|
+
}),
|
|
106
|
+
execute: async (_toolCallId, params) => {
|
|
107
|
+
const file = params.file ?? "slides.md";
|
|
108
|
+
const port = params.port ?? 3000;
|
|
109
|
+
const cwd = process.cwd();
|
|
110
|
+
|
|
111
|
+
if (!existsSync(join(cwd, file))) {
|
|
112
|
+
return {
|
|
113
|
+
content: [{ type: "text", text: `File not found: ${file}. Generate a presentation first with generate_presentation.` }],
|
|
114
|
+
details: {},
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Check if anna is installed
|
|
119
|
+
if (!isAnnaInstalled()) {
|
|
120
|
+
return {
|
|
121
|
+
content: [{
|
|
122
|
+
type: "text",
|
|
123
|
+
text: "Anna.js CLI not found. Install it with:\n\nnpm install -g @kwhorne/anna.js\n\nThen try again.",
|
|
124
|
+
}],
|
|
125
|
+
details: {},
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Start anna serve in background
|
|
130
|
+
try {
|
|
131
|
+
execSync(`anna serve "${file}" --port ${port} --open &`, {
|
|
132
|
+
cwd,
|
|
133
|
+
timeout: 5000,
|
|
134
|
+
stdio: "pipe",
|
|
135
|
+
});
|
|
136
|
+
} catch {
|
|
137
|
+
// Expected -- the & backgrounds it
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
content: [{
|
|
142
|
+
type: "text",
|
|
143
|
+
text: `Presentation server started at http://localhost:${port}\nFile: ${file}\nLive reload enabled -- edit the .md file to see changes instantly.`,
|
|
144
|
+
}],
|
|
145
|
+
details: { file, port },
|
|
146
|
+
};
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// ── Tool: build_presentation ──
|
|
151
|
+
elyra.registerTool({
|
|
152
|
+
name: "build_presentation",
|
|
153
|
+
label: "Build Presentation HTML",
|
|
154
|
+
description:
|
|
155
|
+
"Generate the HTML file from an Anna.js Markdown presentation. " +
|
|
156
|
+
"Creates a self-contained HTML file that can be opened directly in a browser. " +
|
|
157
|
+
"Use --offline for bundled Mermaid, --pwa for installable offline app.",
|
|
158
|
+
parameters: Type.Object({
|
|
159
|
+
file: Type.Optional(
|
|
160
|
+
Type.String({ description: "Markdown file to build (default: slides.md)" }),
|
|
161
|
+
),
|
|
162
|
+
offline: Type.Optional(
|
|
163
|
+
Type.Boolean({ description: "Bundle Mermaid locally for offline use (default: false)" }),
|
|
164
|
+
),
|
|
165
|
+
pwa: Type.Optional(
|
|
166
|
+
Type.Boolean({ description: "Generate PWA manifest and service worker (default: false)" }),
|
|
167
|
+
),
|
|
168
|
+
}),
|
|
169
|
+
execute: async (_toolCallId, params) => {
|
|
170
|
+
const file = params.file ?? "slides.md";
|
|
171
|
+
const cwd = process.cwd();
|
|
172
|
+
|
|
173
|
+
if (!existsSync(join(cwd, file))) {
|
|
174
|
+
return {
|
|
175
|
+
content: [{ type: "text", text: `File not found: ${file}` }],
|
|
176
|
+
details: {},
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (!isAnnaInstalled()) {
|
|
181
|
+
return {
|
|
182
|
+
content: [{ type: "text", text: "Anna.js CLI not found. Install with: npm install -g @kwhorne/anna.js" }],
|
|
183
|
+
details: {},
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const flags: string[] = [];
|
|
188
|
+
if (params.offline) flags.push("--offline");
|
|
189
|
+
if (params.pwa) flags.push("--pwa");
|
|
190
|
+
|
|
191
|
+
try {
|
|
192
|
+
const result = execSync(`anna generate "${file}" ${flags.join(" ")}`, {
|
|
193
|
+
cwd,
|
|
194
|
+
timeout: 30000,
|
|
195
|
+
encoding: "utf-8",
|
|
196
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
const htmlFile = file.replace(/\.md$/, ".html");
|
|
200
|
+
return {
|
|
201
|
+
content: [{ type: "text", text: `Built: ${htmlFile}\n${result.trim()}` }],
|
|
202
|
+
details: { output: htmlFile },
|
|
203
|
+
};
|
|
204
|
+
} catch (error) {
|
|
205
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
206
|
+
return {
|
|
207
|
+
content: [{ type: "text", text: `Build failed: ${msg}` }],
|
|
208
|
+
details: {},
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
// ── Commands ──
|
|
215
|
+
elyra.registerCommand("presentation", {
|
|
216
|
+
description: "Generate an Anna.js presentation from a topic or project",
|
|
217
|
+
handler: async (args, _ctx) => {
|
|
218
|
+
if (!args.trim()) {
|
|
219
|
+
elyra.sendUserMessage(
|
|
220
|
+
"I want to create a presentation. Ask me what topic or project area to present, " +
|
|
221
|
+
"how many slides, and which features to include (terminal demos, live code, diagrams).",
|
|
222
|
+
);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
elyra.sendUserMessage(`Generate an Anna.js presentation about: ${args}`);
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
elyra.registerCommand("slides", {
|
|
230
|
+
description: "Preview or build an existing presentation",
|
|
231
|
+
handler: async (args, _ctx) => {
|
|
232
|
+
const file = args.trim() || "slides.md";
|
|
233
|
+
elyra.sendUserMessage(`Preview the presentation at ${file} using anna serve.`);
|
|
234
|
+
},
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function isAnnaInstalled(): boolean {
|
|
239
|
+
try {
|
|
240
|
+
execSync("which anna 2>/dev/null || where anna 2>/dev/null", {
|
|
241
|
+
timeout: 5000,
|
|
242
|
+
encoding: "utf-8",
|
|
243
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
244
|
+
});
|
|
245
|
+
return true;
|
|
246
|
+
} catch {
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@elyracode/anna",
|
|
3
|
+
"version": "0.5.4",
|
|
4
|
+
"description": "Elyra extension for Anna.js -- generate, preview, and edit Markdown presentations with terminal animations, live code, and Mermaid diagrams",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"keywords": ["elyra-package", "anna", "presentation", "slides", "markdown", "mermaid"],
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"author": "Knut W. Horne",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/kwhorne/elyra.git",
|
|
12
|
+
"directory": "packages/anna"
|
|
13
|
+
},
|
|
14
|
+
"elyra": {
|
|
15
|
+
"extensions": ["./extensions/index.ts"],
|
|
16
|
+
"skills": ["./skills"]
|
|
17
|
+
},
|
|
18
|
+
"peerDependencies": {
|
|
19
|
+
"@elyracode/coding-agent": "*",
|
|
20
|
+
"typebox": "*"
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"clean": "echo 'nothing to clean'",
|
|
24
|
+
"build": "echo 'nothing to build'",
|
|
25
|
+
"check": "echo 'nothing to check'"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: anna-js
|
|
3
|
+
description: Complete reference for Anna.js presentation framework. Use when generating, editing, or converting Markdown presentations with Anna.js syntax including slides, fragments, terminal animations, live code playgrounds, Mermaid diagrams, components, and layouts.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Anna.js Syntax Reference
|
|
7
|
+
|
|
8
|
+
## Slide Structure
|
|
9
|
+
|
|
10
|
+
```markdown
|
|
11
|
+
---
|
|
12
|
+
title: My Presentation
|
|
13
|
+
theme: moon
|
|
14
|
+
transition: slide
|
|
15
|
+
controls: true
|
|
16
|
+
progress: true
|
|
17
|
+
center: true
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# First Slide
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Second Slide
|
|
25
|
+
|
|
26
|
+
Content here.
|
|
27
|
+
|
|
28
|
+
--
|
|
29
|
+
|
|
30
|
+
### Vertical Sub-slide
|
|
31
|
+
|
|
32
|
+
Under the second slide.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Third Slide
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- `---` separates horizontal slides
|
|
40
|
+
- `--` separates vertical sub-slides (navigate with arrow down)
|
|
41
|
+
- YAML frontmatter configures the presentation
|
|
42
|
+
|
|
43
|
+
## Frontmatter Options
|
|
44
|
+
|
|
45
|
+
| Option | Values | Default |
|
|
46
|
+
|--------|--------|---------|
|
|
47
|
+
| `title` | string | untitled |
|
|
48
|
+
| `author` | string | - |
|
|
49
|
+
| `theme` | league, moon, night, black, blood, white, beige, sky, serif, simple, solarized | league |
|
|
50
|
+
| `transition` | slide, fade, convex, concave, zoom, none | slide |
|
|
51
|
+
| `controls` | true/false | true |
|
|
52
|
+
| `progress` | true/false | true |
|
|
53
|
+
| `center` | true/false | true |
|
|
54
|
+
| `hash` | true/false | true |
|
|
55
|
+
| `autoSlide` | milliseconds (0 = off) | 0 |
|
|
56
|
+
| `loop` | true/false | false |
|
|
57
|
+
|
|
58
|
+
## Fragments (Step-by-step Reveal)
|
|
59
|
+
|
|
60
|
+
```markdown
|
|
61
|
+
<!-- .fragments -->
|
|
62
|
+
- First point (revealed on click)
|
|
63
|
+
- Second point
|
|
64
|
+
- Third point
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Single paragraph fragment:
|
|
68
|
+
```markdown
|
|
69
|
+
<!-- .fragment -->
|
|
70
|
+
This paragraph appears on click.
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Speaker Notes
|
|
74
|
+
|
|
75
|
+
```markdown
|
|
76
|
+
## My Slide
|
|
77
|
+
|
|
78
|
+
Content visible to audience.
|
|
79
|
+
|
|
80
|
+
Note:
|
|
81
|
+
These are speaker notes.
|
|
82
|
+
Only visible in speaker view (press S).
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Backgrounds
|
|
86
|
+
|
|
87
|
+
```markdown
|
|
88
|
+
<!-- .slide: data-background="#4d7e65" -->
|
|
89
|
+
## Green Background
|
|
90
|
+
|
|
91
|
+
<!-- .slide: data-background-image="photo.jpg" -->
|
|
92
|
+
## Image Background
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Terminal Animations
|
|
96
|
+
|
|
97
|
+
Commands are typed out character by character with a realistic typing effect:
|
|
98
|
+
|
|
99
|
+
````markdown
|
|
100
|
+
```terminal
|
|
101
|
+
$ npm install anna.js
|
|
102
|
+
added 42 packages in 2.3s
|
|
103
|
+
|
|
104
|
+
$ anna generate slides.md
|
|
105
|
+
✓ slides.md → slides.html
|
|
106
|
+
```
|
|
107
|
+
````
|
|
108
|
+
|
|
109
|
+
Each command group separated by blank lines is a fragment step.
|
|
110
|
+
|
|
111
|
+
## Live Code Playground
|
|
112
|
+
|
|
113
|
+
### JavaScript
|
|
114
|
+
````markdown
|
|
115
|
+
```playground
|
|
116
|
+
const greeting = "Hello, Anna.js!";
|
|
117
|
+
console.log(greeting);
|
|
118
|
+
```
|
|
119
|
+
````
|
|
120
|
+
|
|
121
|
+
### HTML
|
|
122
|
+
````markdown
|
|
123
|
+
```playground html
|
|
124
|
+
<h1 style="color: coral">Hello!</h1>
|
|
125
|
+
<p>This renders live.</p>
|
|
126
|
+
```
|
|
127
|
+
````
|
|
128
|
+
|
|
129
|
+
### Multi-file (JS + HTML + CSS tabs)
|
|
130
|
+
````markdown
|
|
131
|
+
```playground multi
|
|
132
|
+
=== js
|
|
133
|
+
document.getElementById('msg').textContent = 'Hello!';
|
|
134
|
+
=== html
|
|
135
|
+
<div id="msg">Loading...</div>
|
|
136
|
+
=== css
|
|
137
|
+
#msg { color: coral; font-size: 2em; text-align: center; }
|
|
138
|
+
```
|
|
139
|
+
````
|
|
140
|
+
|
|
141
|
+
### Step-by-step Code (incremental with diffs)
|
|
142
|
+
````markdown
|
|
143
|
+
```playground step 1
|
|
144
|
+
const x = 1;
|
|
145
|
+
console.log(x);
|
|
146
|
+
```
|
|
147
|
+
````
|
|
148
|
+
|
|
149
|
+
Next slide:
|
|
150
|
+
````markdown
|
|
151
|
+
```playground step 2
|
|
152
|
+
const x = 1;
|
|
153
|
+
const y = 2;
|
|
154
|
+
console.log(x + y);
|
|
155
|
+
```
|
|
156
|
+
````
|
|
157
|
+
|
|
158
|
+
Added lines are highlighted in green.
|
|
159
|
+
|
|
160
|
+
### Console Support
|
|
161
|
+
Captures: `console.log()`, `console.error()`, `console.warn()`, `console.info()`, `console.table()`, `console.clear()`, `console.group()`, `console.groupEnd()`, plus the return value of the last expression.
|
|
162
|
+
|
|
163
|
+
## Mermaid Diagrams
|
|
164
|
+
|
|
165
|
+
````markdown
|
|
166
|
+
```mermaid
|
|
167
|
+
graph LR
|
|
168
|
+
A[Idea] --> B[Markdown] --> C[Presentation]
|
|
169
|
+
```
|
|
170
|
+
````
|
|
171
|
+
|
|
172
|
+
````markdown
|
|
173
|
+
```mermaid
|
|
174
|
+
sequenceDiagram
|
|
175
|
+
User->>CLI: slides.md
|
|
176
|
+
CLI->>HTML: Generate
|
|
177
|
+
HTML-->>User: slides.html
|
|
178
|
+
```
|
|
179
|
+
````
|
|
180
|
+
|
|
181
|
+
````markdown
|
|
182
|
+
```mermaid
|
|
183
|
+
gantt
|
|
184
|
+
title Project Timeline
|
|
185
|
+
section Phase 1
|
|
186
|
+
Research: 2024-01-01, 30d
|
|
187
|
+
section Phase 2
|
|
188
|
+
Development: 2024-02-01, 60d
|
|
189
|
+
```
|
|
190
|
+
````
|
|
191
|
+
|
|
192
|
+
All Mermaid diagram types are supported. Theme auto-matches the presentation theme.
|
|
193
|
+
|
|
194
|
+
## Component Layouts
|
|
195
|
+
|
|
196
|
+
### Columns
|
|
197
|
+
```markdown
|
|
198
|
+
<!-- @columns -->
|
|
199
|
+
### Left Column
|
|
200
|
+
Content here.
|
|
201
|
+
<!-- @col -->
|
|
202
|
+
### Right Column
|
|
203
|
+
More content.
|
|
204
|
+
<!-- @end -->
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Comparison (Pros/Cons)
|
|
208
|
+
```markdown
|
|
209
|
+
<!-- @comparison pros="Advantages" cons="Disadvantages" -->
|
|
210
|
+
- Fast performance
|
|
211
|
+
- Easy to learn
|
|
212
|
+
<!-- @vs -->
|
|
213
|
+
- Steep learning curve
|
|
214
|
+
- Complex setup
|
|
215
|
+
<!-- @end -->
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Timeline
|
|
219
|
+
```markdown
|
|
220
|
+
<!-- @timeline -->
|
|
221
|
+
- **2020** — Project started
|
|
222
|
+
- **2021** — First release
|
|
223
|
+
- **2023** — Version 2.0
|
|
224
|
+
<!-- @end -->
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Stats (Big Numbers)
|
|
228
|
+
```markdown
|
|
229
|
+
<!-- @stats -->
|
|
230
|
+
- 10K+ | Downloads
|
|
231
|
+
- 99.9% | Uptime
|
|
232
|
+
- 50ms | Response Time
|
|
233
|
+
<!-- @end -->
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Quote
|
|
237
|
+
```markdown
|
|
238
|
+
<!-- @quote author="Knut W. Horne" -->
|
|
239
|
+
The best presentations are written in Markdown.
|
|
240
|
+
<!-- @end -->
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Cards
|
|
244
|
+
```markdown
|
|
245
|
+
<!-- @cards -->
|
|
246
|
+
### Card 1
|
|
247
|
+
Description here.
|
|
248
|
+
### Card 2
|
|
249
|
+
Another description.
|
|
250
|
+
<!-- @end -->
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Image + Text
|
|
254
|
+
```markdown
|
|
255
|
+
<!-- @image-text src="photo.jpg" -->
|
|
256
|
+
### Title
|
|
257
|
+
Description next to the image.
|
|
258
|
+
<!-- @end -->
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Icon List
|
|
262
|
+
```markdown
|
|
263
|
+
<!-- @icon-list -->
|
|
264
|
+
- 🚀 | **Fast** | Built for speed
|
|
265
|
+
- 🔒 | **Secure** | Enterprise ready
|
|
266
|
+
- 🎨 | **Beautiful** | 11 themes
|
|
267
|
+
<!-- @end -->
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Custom Components (Reusable)
|
|
271
|
+
```markdown
|
|
272
|
+
<!-- @component: team-card -->
|
|
273
|
+
### {name}
|
|
274
|
+
*{role}*
|
|
275
|
+
<!-- @end -->
|
|
276
|
+
|
|
277
|
+
<!-- @use: team-card name="Knut" role="Creator" -->
|
|
278
|
+
<!-- @use: team-card name="Anna" role="Designer" -->
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## Live Audience Interaction
|
|
282
|
+
|
|
283
|
+
### Polls (requires `anna live`)
|
|
284
|
+
````markdown
|
|
285
|
+
```poll What is your favorite language?
|
|
286
|
+
- JavaScript
|
|
287
|
+
- Python
|
|
288
|
+
- Rust
|
|
289
|
+
- Go
|
|
290
|
+
```
|
|
291
|
+
````
|
|
292
|
+
|
|
293
|
+
### Q&A (requires `anna live`)
|
|
294
|
+
````markdown
|
|
295
|
+
```qa Ask me anything!
|
|
296
|
+
```
|
|
297
|
+
````
|
|
298
|
+
|
|
299
|
+
## CLI Commands
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
anna init my-presentation # scaffold new project
|
|
303
|
+
anna generate slides.md # generate HTML
|
|
304
|
+
anna generate slides.md --watch # watch mode
|
|
305
|
+
anna serve slides.md # dev server with live reload
|
|
306
|
+
anna live slides.md # live server with polls/Q&A
|
|
307
|
+
anna ai "Topic" # AI-generated presentation
|
|
308
|
+
anna ai refine slides.md # improve existing
|
|
309
|
+
anna ai translate slides.md --lang en # translate
|
|
310
|
+
anna export slides.md # export to PDF
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
## Themes
|
|
314
|
+
|
|
315
|
+
**Dark:** black, night, moon, blood, league (default)
|
|
316
|
+
**Light:** white, beige, sky, serif, simple, solarized
|
|
317
|
+
|
|
318
|
+
## Keyboard Shortcuts (in presentation)
|
|
319
|
+
|
|
320
|
+
| Key | Function |
|
|
321
|
+
|-----|----------|
|
|
322
|
+
| Arrow keys | Navigate |
|
|
323
|
+
| Space / N | Next slide |
|
|
324
|
+
| P | Previous |
|
|
325
|
+
| ESC / O | Overview |
|
|
326
|
+
| S | Speaker notes |
|
|
327
|
+
| F | Fullscreen |
|
|
328
|
+
| B / . | Pause (black screen) |
|
|
329
|
+
|
|
330
|
+
## Embed Mode (Web Components)
|
|
331
|
+
|
|
332
|
+
```html
|
|
333
|
+
<script src="https://unpkg.com/anna.js/js/anna-embed.js"></script>
|
|
334
|
+
|
|
335
|
+
<anna-slide theme="moon">
|
|
336
|
+
## Hello World
|
|
337
|
+
- Point 1
|
|
338
|
+
- Point 2
|
|
339
|
+
</anna-slide>
|
|
340
|
+
|
|
341
|
+
<anna-deck theme="night">
|
|
342
|
+
<anna-slide># Slide 1</anna-slide>
|
|
343
|
+
<anna-slide># Slide 2</anna-slide>
|
|
344
|
+
</anna-deck>
|
|
345
|
+
```
|