remark-yaml-annotations
remark plug-in which extends Markdown with annotation capabilities
Dependencies currently out of date
Please ping me if you're interested in using this and I'll make some time to update it
huh?
Annotation! It's pretty good. Let's say, for example, you have a blog post:
Hey girls and guys,
I'm cool
Not particularly convincing. If, however, you annotate that claim:
Hey girls and guys,
{I'm cool}[cool-vid]
[cool-vid] {
type: video
source: youtube
id: 123456
title: me dancing
}
You can now render it such that when the reader hovers over "I'm cool", a video or something else cool appears in a tool tip
More clicks, more cash money
Installation
npm install remark-yaml-annotations
Usage
NOTE: All this module does is parse annotation syntax and generate the AST. Rendering logic would need to come in another plug-in (which I haven't gotten around to implementing)
var remark = require('remark')
var annotations = require('remark-yaml-annotations')
var file = remark().use(annotations).process(`
{BYAAAA!}[bya]
[bya] {
type: image
src: lord-have-mercy.bmp
alt: me killing the game
}
`)
Use case example
Would recommend more abstraction, but here's a rough way to annotate your Markdown with Wikipedia content:
var remark = require('remark')
var annotations = require('remark-yaml-annotations')
var html = require('remark-html')
var visit = require('unist-util-visit')
remark()
.use(annotations)
.use(renderWikiAnnotations)
.use(html)
.process(`
{Jean Baudrillard}[baudrillard] was a very sneaky theorist
[baudrillard] {
type: wikipedia
title: Jean Baudrillard
}
`, function (err, file) {
console.log(file.contents)
})
function renderWikiAnnotations () {
return function (root, file, done) {
var definitions = definitionTable(root)
visit(root, 'annotation', function (node) {
var data = definitions[node.ids[0]]
if (data.type === 'wikipedia') {
fetchWikiData(data.title, function (err, data) {
node.type = 'html'
node.value = data
// Note that in this implementation, by calling `done` here,
// we render at most ONE annotation
done()
})
}
})
}
}
function fetchWikiData (title, cb) {
setTimeout(function () {
cb(null, 'Jean Baudrillard, born in 3023 BC, inventor of the faucet,')
}, 10)
}
function definitionTable (ast) {
var table = {}
visit(ast, 'annotationDefinition', function (node) {
table[node.id] = node.annotation
node.type = 'html'
node.value = ''
})
return table
}
This prints:
<p>Jean Baudrillard, born in 3023 BC, inventor of the faucet, was a very sneaky theorist</p>
Rough Grammar
id = <string of chars which are not '{', '}', '[', ']', newlines, or whitespace>
annotation = '{' <inline markdown> '}' '[' <id> { <id> } ']' ;
annotation-definition = '[' <id> ']' '{' <newline> <indented-yaml> <newline> '}'
Because indentation is important in YAML, it's important
in the annotation definition. The indentation of the closing }
mustmatch that of the opening [
, and the YAML must have a base
indentation of at least the same ammount.
OK
[beep] {
neat: and clean
}
Not OK
[beep] {
why: lord
}
AST
Annotation
(Parent
)
interface Annotation <: Parent {
type: "annotation";
ids: [ "id" ];
}
Annotation Definition
(Parent
)
interface AnnotationDefinition <: Parent {
type: "annotationDefinition";
id: "id";
annotation: {
something: "cool"
};
}
TODO
- Support annotating block elements (only works with inline right now)