The Code.Movie plugin for Marked (marked.js.org) extends markdown with syntax to author animated code right inside markdown! You can install the plugin (along with Marked itself) from NPM:
npm install @codemovie/code-movie-marked-plugin marked
1npm install @codemovie/code-movie-marked-plugin marked
To use the plugin's features in markdown, wrap regular fenced code blocks...
!!!json
```
[]
```
```
["World"]
```
```
["Hello", "World"]
```
```
[
"Hello",
"World"
]
```
!!!
12345678910111213141516171819202122!!!json
```
[]
```
```
["World"]
```
```
["Hello", "World"]
```
```
[
"Hello",
"World"
]
```
!!!
... and get back animated, syntax highlighted code:
[]
["World"]
["Hello", "World"]
[ "Hello", "World" ]
Apart from the !!!
wrapper blocks, the plugin also extends fenced code blocks inside wrapper blocks with a syntax to add decorations and metadata as JSON5-encoded objects:
!!!json
```
[]
```
```(|decorations=[{ kind: "TEXT", from: 1, to: 8 }])
["World"]
```
```(|decorations=[
{ kind: "TEXT", from: 1, to: 8 },
{ kind: "TEXT", from: 10, to: 17, data: { class: "error" } }
])
["Hello", "World"]
```
```(|decorations=[
{ kind: "GUTTER", text: "âś…", line: 2 },
{ kind: "GUTTER", text: "đźš«", line: 3 }
])
[
"Hello",
"World"
]
```
!!!
12345678910111213141516171819202122232425262728!!!json
```
[]
```
```(|decorations=[{ kind: "TEXT", from: 1, to: 8 }])
["World"]
```
```(|decorations=[
{ kind: "TEXT", from: 1, to: 8 },
{ kind: "TEXT", from: 10, to: 17, data: { class: "error" } }
])
["Hello", "World"]
```
```(|decorations=[
{ kind: "GUTTER", text: "âś…", line: 2 },
{ kind: "GUTTER", text: "đźš«", line: 3 }
])
[
"Hello",
"World"
]
```
!!!
Result:
["World"]
["Hello", "World"]
[ "Hello", "World" ]
While this syntax looks a little gross compared to what markdown is supposed to be, it is actually not too bad when it comes to authoring animations that are meant as part of larger documents. It definitely beats pasting HTML into markdown! The entire documentation on this site as well as this blog post have been (re)written with the help of this plugin.
Similar to @codemovie/code-movie-html, this plugin does not bundle the core library and therefore requires a bit of setup to wire everything up. You'll need too install @codemovie/code-movie, pick the languages you intend to support, and write/paste a little adapter function:
import { marked } from "marked";
import { markedCodeMoviePlugin } from "@codemovie/code-movie-marked-plugin";
import { animateHTML, monokaiDark } from "@codemovie/code-movie";
import ecmascript from "@codemovie/code-movie/languages/ecmascript";
import "@codemovie/code-movie-runtime";
// Connect the plugin to the core library
const codeMoviePlugin = markedCodeMoviePlugin({
adapter(frames, language, token) {
return animateHTML(frames, {
tabSize: 2,
language,
theme: monokaiDark,
});
},
languages: {
javascript: ecmascript({ ts: false }),
typescript: ecmascript({ ts: true }),
},
// Automatically add <code-movie-runtime> markup
addRuntime: {
controls: true, // controls attribute
},
});
// Pass the plugin to Marked
marked.use(codeMoviePlugin);
// Time to parse some markdown!
const markdown = await fetch("./content.md").then((res) => res.text());
document.body.innerHTML += marked.parse(markdown);
1234567891011121314151617181920212223242526272829303132import { marked } from "marked";
import { markedCodeMoviePlugin } from "@codemovie/code-movie-marked-plugin";
import { animateHTML, monokaiDark } from "@codemovie/code-movie";
import ecmascript from "@codemovie/code-movie/languages/ecmascript";
import "@codemovie/code-movie-runtime";
// Connect the plugin to the core library
const codeMoviePlugin = markedCodeMoviePlugin({
adapter(frames, language, token) {
return animateHTML(frames, {
tabSize: 2,
language,
theme: monokaiDark,
});
},
languages: {
javascript: ecmascript({ ts: false }),
typescript: ecmascript({ ts: true }),
},
// Automatically add <code-movie-runtime> markup
addRuntime: {
controls: true, // controls attribute
},
});
// Pass the plugin to Marked
marked.use(codeMoviePlugin);
// Time to parse some markdown!
const markdown = await fetch("./content.md").then((res) => res.text());
document.body.innerHTML += marked.parse(markdown);
For more information on syntax and features check out the package's readme on NPM or GitHub.