Skip to content

Commit 06aa0aa

Browse files
committed
Add template literal tag
1 parent c79a430 commit 06aa0aa

File tree

4 files changed

+88
-3
lines changed

4 files changed

+88
-3
lines changed

dev/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@
99
* @typedef {import('./lib/index.js').CompileContext} CompileContext
1010
*/
1111

12-
export {fromMarkdown} from './lib/index.js'
12+
export {fromMarkdown, md} from './lib/index.js'

dev/lib/index.js

+34
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,12 @@
8080
*/
8181

8282
import assert from 'assert'
83+
import {directiveFromMarkdown} from 'mdast-util-directive'
8384
import {toString} from 'mdast-util-to-string'
8485
import {parse} from 'micromark/lib/parse.js'
8586
import {preprocess} from 'micromark/lib/preprocess.js'
8687
import {postprocess} from 'micromark/lib/postprocess.js'
88+
import {directive} from 'micromark-extension-directive'
8789
import {decodeNumericCharacterReference} from 'micromark-util-decode-numeric-character-reference'
8890
import {decodeString} from 'micromark-util-decode-string'
8991
import {normalizeIdentifier} from 'micromark-util-normalize-identifier'
@@ -1142,3 +1144,35 @@ function extension(combined, extension) {
11421144
}
11431145
}
11441146
}
1147+
1148+
/**
1149+
* @param {TemplateStringsArray} strings
1150+
* @param {...Node} values
1151+
* @returns {Root}
1152+
*/
1153+
export function md(strings, ...values) {
1154+
// Interleave strings with `:expression`.
1155+
const tree = fromMarkdown(strings.join(':expression'), {
1156+
extensions: [directive()],
1157+
mdastExtensions: [directiveFromMarkdown]
1158+
})
1159+
// Swap `:expression` nodes for values.
1160+
visit(tree)
1161+
return tree
1162+
1163+
/**
1164+
* @param {Node} node
1165+
* @returns {void}
1166+
*/
1167+
function visit(node) {
1168+
if ('children' in node) {
1169+
for (const [i, child] of node.children.entries()) {
1170+
if (child.type === 'textDirective' && child.name === 'expression') {
1171+
node.children[i] = /** @type {Content} */ (values.shift())
1172+
} else {
1173+
visit(child)
1174+
}
1175+
}
1176+
}
1177+
}
1178+
}

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@
4343
"dependencies": {
4444
"@types/mdast": "^3.0.0",
4545
"@types/unist": "^2.0.0",
46+
"mdast-util-directive": "^2.1.1",
4647
"mdast-util-to-string": "^3.1.0",
4748
"micromark": "^3.0.0",
49+
"micromark-extension-directive": "^2.0.1",
4850
"micromark-util-decode-numeric-character-reference": "^1.0.0",
4951
"micromark-util-decode-string": "^1.0.0",
5052
"micromark-util-normalize-identifier": "^1.0.0",

test/index.js

+51-2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
*/
44

55
import assert from 'assert'
6-
import {Buffer} from 'node:buffer'
76
import fs from 'fs'
87
import path from 'path'
8+
import {Buffer} from 'node:buffer'
99
import test from 'tape'
1010
import {unified} from 'unified'
1111
import rehypeParse from 'rehype-parse'
@@ -14,7 +14,7 @@ import {toHast} from 'mdast-util-to-hast'
1414
import {toString} from 'mdast-util-to-string'
1515
import {toHtml} from 'hast-util-to-html'
1616
import {commonmark} from 'commonmark.json'
17-
import {fromMarkdown} from '../dev/index.js'
17+
import {fromMarkdown, md} from '../dev/index.js'
1818

1919
const join = path.join
2020

@@ -1012,6 +1012,55 @@ test('mdast-util-from-markdown', (t) => {
10121012
'should parse a thematic break'
10131013
)
10141014

1015+
t.deepEqual(
1016+
md`*${fromMarkdown('a*b')}*`.children[0],
1017+
{
1018+
type: 'paragraph',
1019+
children: [
1020+
{
1021+
type: 'emphasis',
1022+
children: [
1023+
{
1024+
type: 'root',
1025+
children: [
1026+
{
1027+
type: 'paragraph',
1028+
children: [
1029+
{
1030+
type: 'text',
1031+
value: 'a*b',
1032+
position: {
1033+
start: {line: 1, column: 1, offset: 0},
1034+
end: {line: 1, column: 4, offset: 3}
1035+
}
1036+
}
1037+
],
1038+
position: {
1039+
start: {line: 1, column: 1, offset: 0},
1040+
end: {line: 1, column: 4, offset: 3}
1041+
}
1042+
}
1043+
],
1044+
position: {
1045+
start: {line: 1, column: 1, offset: 0},
1046+
end: {line: 1, column: 4, offset: 3}
1047+
}
1048+
}
1049+
],
1050+
position: {
1051+
start: {line: 1, column: 1, offset: 0},
1052+
end: {line: 1, column: 14, offset: 13}
1053+
}
1054+
}
1055+
],
1056+
position: {
1057+
start: {line: 1, column: 1, offset: 0},
1058+
end: {line: 1, column: 14, offset: 13}
1059+
}
1060+
},
1061+
'should substitute an expression'
1062+
)
1063+
10151064
t.end()
10161065
})
10171066

0 commit comments

Comments
 (0)