Skip to content

Commit f3b35fe

Browse files
committed
Add support for compiling unknown nodes
This updates ensures mdast-html is able to deal, “somewhat”, with future nodes and plugin-specific nodes. All unknown nodes are compiled as `div` elements, but the in e713382 introduced support for specifying how mdastnode(7)s are compiled enables plug-in authors to introduce other HTML elements. Closes GH-2.
1 parent 0ae12cf commit f3b35fe

File tree

6 files changed

+184
-12
lines changed

6 files changed

+184
-12
lines changed

index.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,11 @@ function plugin(mdast, options) {
4343
* Extensible constructor.
4444
*/
4545
function HTMLCompiler(file) {
46-
file.move({
47-
'extension': 'html'
48-
});
46+
if (file.extension) {
47+
file.move({
48+
'extension': 'html'
49+
});
50+
}
4951

5052
MarkdownCompiler.apply(this, [file, options]);
5153
}

lib/compilers.js

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,66 @@ function generateFootnotes() {
132132
}, null, true) + '\n';
133133
}
134134

135+
/**
136+
* Stringify an unknown node.
137+
*
138+
* @example
139+
* unknown({
140+
* data: {
141+
* htmlName: 'section'
142+
* },
143+
* children: [
144+
* {
145+
* type: 'text',
146+
* value: 'foo'
147+
* }
148+
* ]
149+
* }); // '<section>foo</section>'
150+
*
151+
* @param {Node} node - Node to compile.
152+
* @return {string} - Compiled node.
153+
* @this {HTMLCompiler}
154+
*/
155+
function unknown(node) {
156+
var content = 'children' in node ? this.all(node) : node.value;
157+
158+
return h(this, node, {
159+
'name': 'div',
160+
'content': content || ''
161+
}, node.data);
162+
}
163+
164+
/**
165+
* Visit a node.
166+
*
167+
* @example
168+
* var compiler = new Compiler();
169+
*
170+
* compiler.visit({
171+
* type: 'strong',
172+
* children: [{
173+
* type: 'text',
174+
* value: 'Foo'
175+
* }]
176+
* });
177+
* // '**Foo**'
178+
*
179+
* @param {Object} node - Node.
180+
* @param {Object?} [parent] - `node`s parent.
181+
* @return {string} - Compiled `node`.
182+
*/
183+
function one(node, parent) {
184+
var self = this;
185+
var type = node && node.type;
186+
var fn = typeof self[type] === 'function' ? type : 'unknown';
187+
188+
if (!type) {
189+
self.file.fail('Expected node `' + node + '`');
190+
}
191+
192+
return self[fn](node, parent);
193+
}
194+
135195
/**
136196
* Stringify the children of `node`.
137197
*
@@ -800,7 +860,7 @@ function image(node) {
800860
* value: 'foo'
801861
* }
802862
* ]
803-
* }); // '~~foo~~'
863+
* }); // '<del>foo</del>'
804864
*
805865
* @param {Node} node - Node to compile.
806866
* @return {string} - Compiled node.
@@ -862,7 +922,9 @@ function ignore() {
862922
* Helpers.
863923
*/
864924

925+
visitors.visit = one;
865926
visitors.all = all;
927+
visitors.unknown = unknown;
866928
visitors.generateFootnotes = generateFootnotes;
867929

868930
/*

mdast-html.js

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,11 @@ function plugin(mdast, options) {
4444
* Extensible constructor.
4545
*/
4646
function HTMLCompiler(file) {
47-
file.move({
48-
'extension': 'html'
49-
});
47+
if (file.extension) {
48+
file.move({
49+
'extension': 'html'
50+
});
51+
}
5052

5153
MarkdownCompiler.apply(this, [file, options]);
5254
}
@@ -205,6 +207,66 @@ function generateFootnotes() {
205207
}, null, true) + '\n';
206208
}
207209

210+
/**
211+
* Stringify an unknown node.
212+
*
213+
* @example
214+
* unknown({
215+
* data: {
216+
* htmlName: 'section'
217+
* },
218+
* children: [
219+
* {
220+
* type: 'text',
221+
* value: 'foo'
222+
* }
223+
* ]
224+
* }); // '<section>foo</section>'
225+
*
226+
* @param {Node} node - Node to compile.
227+
* @return {string} - Compiled node.
228+
* @this {HTMLCompiler}
229+
*/
230+
function unknown(node) {
231+
var content = 'children' in node ? this.all(node) : node.value;
232+
233+
return h(this, node, {
234+
'name': 'div',
235+
'content': content || ''
236+
}, node.data);
237+
}
238+
239+
/**
240+
* Visit a node.
241+
*
242+
* @example
243+
* var compiler = new Compiler();
244+
*
245+
* compiler.visit({
246+
* type: 'strong',
247+
* children: [{
248+
* type: 'text',
249+
* value: 'Foo'
250+
* }]
251+
* });
252+
* // '**Foo**'
253+
*
254+
* @param {Object} node - Node.
255+
* @param {Object?} [parent] - `node`s parent.
256+
* @return {string} - Compiled `node`.
257+
*/
258+
function one(node, parent) {
259+
var self = this;
260+
var type = node && node.type;
261+
var fn = typeof self[type] === 'function' ? type : 'unknown';
262+
263+
if (!type) {
264+
self.file.fail('Expected node `' + node + '`');
265+
}
266+
267+
return self[fn](node, parent);
268+
}
269+
208270
/**
209271
* Stringify the children of `node`.
210272
*
@@ -873,7 +935,7 @@ function image(node) {
873935
* value: 'foo'
874936
* }
875937
* ]
876-
* }); // '~~foo~~'
938+
* }); // '<del>foo</del>'
877939
*
878940
* @param {Node} node - Node to compile.
879941
* @return {string} - Compiled node.
@@ -935,7 +997,9 @@ function ignore() {
935997
* Helpers.
936998
*/
937999

1000+
visitors.visit = one;
9381001
visitors.all = all;
1002+
visitors.unknown = unknown;
9391003
visitors.generateFootnotes = generateFootnotes;
9401004

9411005
/*

0 commit comments

Comments
 (0)