Skip to content

Commit f2d1a29

Browse files
committed
Fix default class names by moving to transformer
As pointed out by @eush77, it was not possible to preserve default class names added by mdast-html. This fixes that by moving them from the compiling phase (which cannot easily be hooked into) to the transformation phase (which can be hooked into by later attached plugins). Note that plug-ins still need to check for the existance of `node.data.htmlAttributes.class`, and join it with a space if it exists. Closes GH-3.
1 parent 97360a4 commit f2d1a29

File tree

6 files changed

+198
-35
lines changed

6 files changed

+198
-35
lines changed

index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
* Dependencies.
1313
*/
1414

15-
var compilers = require('./lib/compilers.js');
15+
var compilers = require('./lib/compilers');
16+
var transformer = require('./lib/transformer');
1617

1718
/**
1819
* Attach an HTML compiler.
@@ -63,6 +64,8 @@ function plugin(mdast, options) {
6364
}
6465

6566
mdast.Compiler = HTMLCompiler;
67+
68+
return transformer;
6669
}
6770

6871
/*

lib/compilers.js

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,6 @@ var trimLines = require('trim-lines');
2020
var visit = require('unist-util-visit');
2121
var h = require('./h.js');
2222

23-
/*
24-
* Constants.
25-
*/
26-
27-
var FIRST_WORD = /^[^\ \t]+(?=[\ \t]|$)/;
28-
2923
/*
3024
* Compilers.
3125
*/
@@ -515,15 +509,11 @@ function paragraph(node) {
515509
function code(node) {
516510
var self = this;
517511
var value = node.value ? detab(node.value + '\n') : '';
518-
var language = node.lang && node.lang.match(FIRST_WORD);
519512

520513
return h(self, node, {
521514
'name': 'pre',
522515
'content': h(self, node, {
523516
'name': 'code',
524-
'attributes': {
525-
'class': language ? 'language-' + language[0] : null
526-
},
527517
'content': self.encode(value)
528518
}, node.data)
529519
});
@@ -747,7 +737,10 @@ function link(node) {
747737
* // If a definition was added previously:
748738
* footnoteReference({
749739
* identifier: 'foo'
750-
* }); // '<sup id="fnref-foo"><a href="#fn-foo">foo</a></sup>'
740+
* });
741+
* // <sup id="fnref-foo">
742+
* // <a class="footnote-ref" href="#fn-foo">foo</a>
743+
* // </sup>
751744
*
752745
* @param {Node} node - Node to compile.
753746
* @return {string} - Compiled node.

lib/transformer.js

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/**
2+
* @author Titus Wormer
3+
* @copyright 2015 Titus Wormer
4+
* @license MIT
5+
* @module mdast:html:compilers
6+
* @fileoverview Compilers to transform mdast nodes to HTML.
7+
*/
8+
9+
'use strict';
10+
11+
/*
12+
* Dependencies.
13+
*/
14+
15+
var visit = require('unist-util-visit');
16+
17+
/*
18+
* Constants.
19+
*/
20+
21+
var FIRST_WORD = /^[^\ \t]+(?=[\ \t]|$)/;
22+
23+
/**
24+
* Helper to get/set `htmlAttributes`.
25+
*
26+
* @param {Node} node - Node to get data from.
27+
* @return {Object} - Attributes.
28+
*/
29+
function getAttributes(node) {
30+
var data = node.data || (node.data = {});
31+
return data.htmlAttributes || (data.htmlAttributes = {});
32+
}
33+
34+
/**
35+
* Augment a code node.
36+
*
37+
* @param {Node} node - Code node.
38+
*/
39+
function code(node) {
40+
var lang = node.lang && node.lang.match(FIRST_WORD);
41+
var attrs;
42+
43+
if (!lang) {
44+
return;
45+
}
46+
47+
attrs = getAttributes(node);
48+
attrs.class = (attrs.class ? attrs.class + ' ' : '') + 'language-' + lang;
49+
}
50+
51+
/*
52+
* Map of node-type handlers.
53+
*/
54+
55+
var handlers = {};
56+
57+
handlers.code = code;
58+
59+
/**
60+
* Transform `ast`.
61+
*
62+
* @param {Node} ast - Tree.
63+
*/
64+
function transformer(ast) {
65+
visit(ast, function (node) {
66+
if (node.type in handlers) {
67+
handlers[node.type](node);
68+
}
69+
});
70+
}
71+
72+
/*
73+
* Expose.
74+
*/
75+
76+
module.exports = transformer;

mdast-html.js

Lines changed: 96 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
* Dependencies.
1414
*/
1515

16-
var compilers = require('./lib/compilers.js');
16+
var compilers = require('./lib/compilers');
17+
var transformer = require('./lib/transformer');
1718

1819
/**
1920
* Attach an HTML compiler.
@@ -64,6 +65,8 @@ function plugin(mdast, options) {
6465
}
6566

6667
mdast.Compiler = HTMLCompiler;
68+
69+
return transformer;
6770
}
6871

6972
/*
@@ -72,7 +75,7 @@ function plugin(mdast, options) {
7275

7376
module.exports = plugin;
7477

75-
},{"./lib/compilers.js":2}],2:[function(require,module,exports){
78+
},{"./lib/compilers":2,"./lib/transformer":4}],2:[function(require,module,exports){
7679
/**
7780
* @author Titus Wormer
7881
* @copyright 2015 Titus Wormer
@@ -95,12 +98,6 @@ var trimLines = require('trim-lines');
9598
var visit = require('unist-util-visit');
9699
var h = require('./h.js');
97100

98-
/*
99-
* Constants.
100-
*/
101-
102-
var FIRST_WORD = /^[^\ \t]+(?=[\ \t]|$)/;
103-
104101
/*
105102
* Compilers.
106103
*/
@@ -590,15 +587,11 @@ function paragraph(node) {
590587
function code(node) {
591588
var self = this;
592589
var value = node.value ? detab(node.value + '\n') : '';
593-
var language = node.lang && node.lang.match(FIRST_WORD);
594590

595591
return h(self, node, {
596592
'name': 'pre',
597593
'content': h(self, node, {
598594
'name': 'code',
599-
'attributes': {
600-
'class': language ? 'language-' + language[0] : null
601-
},
602595
'content': self.encode(value)
603596
}, node.data)
604597
});
@@ -822,7 +815,10 @@ function link(node) {
822815
* // If a definition was added previously:
823816
* footnoteReference({
824817
* identifier: 'foo'
825-
* }); // '<sup id="fnref-foo"><a href="#fn-foo">foo</a></sup>'
818+
* });
819+
* // <sup id="fnref-foo">
820+
* // <a class="footnote-ref" href="#fn-foo">foo</a>
821+
* // </sup>
826822
*
827823
* @param {Node} node - Node to compile.
828824
* @return {string} - Compiled node.
@@ -1044,7 +1040,7 @@ visitors.escape = escape;
10441040

10451041
module.exports = visitors;
10461042

1047-
},{"./h.js":3,"collapse-white-space":4,"detab":5,"normalize-uri":7,"trim":10,"trim-lines":9,"unist-util-visit":11}],3:[function(require,module,exports){
1043+
},{"./h.js":3,"collapse-white-space":5,"detab":6,"normalize-uri":8,"trim":11,"trim-lines":10,"unist-util-visit":12}],3:[function(require,module,exports){
10481044
/**
10491045
* @author Titus Wormer
10501046
* @copyright 2015 Titus Wormer
@@ -1185,7 +1181,85 @@ function h(context, node, defaults, data, loose) {
11851181

11861182
module.exports = h;
11871183

1188-
},{"object-assign":8}],4:[function(require,module,exports){
1184+
},{"object-assign":9}],4:[function(require,module,exports){
1185+
/**
1186+
* @author Titus Wormer
1187+
* @copyright 2015 Titus Wormer
1188+
* @license MIT
1189+
* @module mdast:html:compilers
1190+
* @fileoverview Compilers to transform mdast nodes to HTML.
1191+
*/
1192+
1193+
'use strict';
1194+
1195+
/*
1196+
* Dependencies.
1197+
*/
1198+
1199+
var visit = require('unist-util-visit');
1200+
1201+
/*
1202+
* Constants.
1203+
*/
1204+
1205+
var FIRST_WORD = /^[^\ \t]+(?=[\ \t]|$)/;
1206+
1207+
/**
1208+
* Helper to get/set `htmlAttributes`.
1209+
*
1210+
* @param {Node} node - Node to get data from.
1211+
* @return {Object} - Attributes.
1212+
*/
1213+
function getAttributes(node) {
1214+
var data = node.data || (node.data = {});
1215+
return data.htmlAttributes || (data.htmlAttributes = {});
1216+
}
1217+
1218+
/**
1219+
* Augment a code node.
1220+
*
1221+
* @param {Node} node - Code node.
1222+
*/
1223+
function code(node) {
1224+
var lang = node.lang && node.lang.match(FIRST_WORD);
1225+
var attrs;
1226+
1227+
if (!lang) {
1228+
return;
1229+
}
1230+
1231+
attrs = getAttributes(node);
1232+
attrs.class = (attrs.class ? attrs.class + ' ' : '') + 'language-' + lang;
1233+
}
1234+
1235+
/*
1236+
* Map of node-type handlers.
1237+
*/
1238+
1239+
var handlers = {};
1240+
1241+
handlers.code = code;
1242+
1243+
/**
1244+
* Transform `ast`.
1245+
*
1246+
* @param {Node} ast - Tree.
1247+
*/
1248+
function transformer(ast) {
1249+
visit(ast, function (node) {
1250+
if (node.type in handlers) {
1251+
handlers[node.type](node);
1252+
}
1253+
});
1254+
}
1255+
1256+
/*
1257+
* Expose.
1258+
*/
1259+
1260+
module.exports = transformer;
1261+
1262+
},{"unist-util-visit":12}],5:[function(require,module,exports){
11891263
'use strict';
11901264

11911265
/*
@@ -1215,7 +1289,7 @@ function collapse(value) {
12151289

12161290
module.exports = collapse;
12171291

1218-
},{}],5:[function(require,module,exports){
1292+
},{}],6:[function(require,module,exports){
12191293
'use strict';
12201294

12211295
/*
@@ -1287,7 +1361,7 @@ function detab(value, size) {
12871361

12881362
module.exports = detab;
12891363

1290-
},{"repeat-string":6}],6:[function(require,module,exports){
1364+
},{"repeat-string":7}],7:[function(require,module,exports){
12911365
/*!
12921366
* repeat-string <https://github.com/jonschlinkert/repeat-string>
12931367
*
@@ -1355,7 +1429,7 @@ function repeat(str, num) {
13551429
var res = '';
13561430
var cache;
13571431

1358-
},{}],7:[function(require,module,exports){
1432+
},{}],8:[function(require,module,exports){
13591433
'use strict';
13601434

13611435
/**
@@ -1386,7 +1460,7 @@ function normalizeURI(uri) {
13861460

13871461
module.exports = normalizeURI;
13881462

1389-
},{}],8:[function(require,module,exports){
1463+
},{}],9:[function(require,module,exports){
13901464
/* eslint-disable no-unused-vars */
13911465
'use strict';
13921466
var hasOwnProperty = Object.prototype.hasOwnProperty;
@@ -1427,7 +1501,7 @@ module.exports = Object.assign || function (target, source) {
14271501
return to;
14281502
};
14291503

1430-
},{}],9:[function(require,module,exports){
1504+
},{}],10:[function(require,module,exports){
14311505
'use strict';
14321506

14331507
/*
@@ -1459,7 +1533,7 @@ function trimLines(value) {
14591533

14601534
module.exports = trimLines;
14611535

1462-
},{}],10:[function(require,module,exports){
1536+
},{}],11:[function(require,module,exports){
14631537

14641538
exports = module.exports = trim;
14651539

@@ -1475,7 +1549,7 @@ exports.right = function(str){
14751549
return str.replace(/\s*$/, '');
14761550
};
14771551

1478-
},{}],11:[function(require,module,exports){
1552+
},{}],12:[function(require,module,exports){
14791553
/**
14801554
* @author Titus Wormer
14811555
* @copyright 2015 Titus Wormer. All rights reserved.

0 commit comments

Comments
 (0)