Skip to content

Commit

Permalink
issue #1: add support for inline elements
Browse files Browse the repository at this point in the history
  • Loading branch information
arve0 committed Nov 24, 2015
1 parent 17971c0 commit 4ad28b4
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 18 deletions.
46 changes: 34 additions & 12 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ var utils = require('./utils.js');
module.exports = function attributes(md) {

function curlyAttrs(state){
var l = state.tokens.length;
var tokens = state.tokens;
for (var i = 0; i < l; i++) {
var l = tokens.length;
for (var i = 0; i < l; ++i) {
if (tokens[i].type !== 'inline') {
continue;
}
Expand All @@ -17,6 +17,37 @@ module.exports = function attributes(md) {
continue;
}

// find {} in inline tokens
for (var j=0, k=inlineTokens.length; j<k; ++j) {
if (inlineTokens[j].type === 'text' || inlineTokens[j].type === 'softbreak') {
continue;
}
// next token should be text and contain { in begining
if (!inlineTokens[j + 1]) {
continue;
}
if (inlineTokens[j + 1].type !== 'text') {
continue;
}
if (inlineTokens[j + 1].content[0] !== '{') {
continue;
}
// } should be found
var endChar = inlineTokens[j + 1].content.indexOf('}');
if (endChar === -1) {
continue;
}
var attrs = utils.getAttrs(inlineTokens[j + 1].content, 1, endChar);
// remove {.bla bla}
if (attrs.length !== 0) {
// remove {}
inlineTokens[j + 1].content = inlineTokens[j + 1].content.substr(endChar + 1);
// add attributes
utils.addAttrs(attrs, inlineTokens[j - 2]);
}

}

var end = inlineTokens.length - 1;
var content = inlineTokens[end].content;

Expand All @@ -34,16 +65,7 @@ module.exports = function attributes(md) {

// read inside {}
var attrs = utils.getAttrs(content, curlyStart + 1, content.length - 1);
for (var j=0, l=attrs.length; j<l; ++j) {
var key = attrs[j][0];
if (key === 'class' && tokens[i - 1].attrIndex(key) !== -1) {
// append space seperated text string
var classIdx = tokens[i - 1].attrIndex(key);
tokens[i - 1].attrs[classIdx][1] += ' ' + attrs[j][1];
} else {
tokens[i - 1].attrPush(attrs[j]);
}
}
utils.addAttrs(attrs, tokens[i - 1]);

inlineTokens[end].content = content.slice(0, curlyStart).trim();

Expand Down
7 changes: 4 additions & 3 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ describe('markdown-it-attrs', function() {
});

it('should add classes to inline elements', function(){
var src = 'paragraph **bold**{.red}';
var expected = '<p>paragraph <strong class="red">bold</strong></p>\n';
md.render(src); // should not crash / throw error
var src = 'paragraph **bold**{.red} asdf';
var expected = '<p>paragraph <strong class="red">bold</strong> asdf</p>\n';
var res = md.render(src);
assert.equal(res, expected);
});
});
22 changes: 19 additions & 3 deletions utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* @param {int} end: where to stop parsing (not including })
* @returns {2d array}: [['key', 'val'], ['class', 'red']]
*/
function getAttrs(str, start, end) {
exports.getAttrs = function(str, start, end) {
// not tab, line feed, form feed, space, solidus, greater than sign, quotation mark, apostrophe and equals sign
var allowedKeyChars = /[^\t\n\f \/>"'=]/;
var pairSeparator = ' ';
Expand Down Expand Up @@ -77,6 +77,22 @@ function getAttrs(str, start, end) {
return attrs;
}

module.exports = {
getAttrs: getAttrs
/**
* add attributes from [['key', 'val']] list
* @param {array} attrs: [['key', 'val']]
* @param {token} token: which token to add attributes
* @returns token
*/
exports.addAttrs = function(attrs, token) {
for (var j=0, l=attrs.length; j<l; ++j) {
var key = attrs[j][0];
if (key === 'class' && token.attrIndex('class') !== -1) {
// append space seperated text string
var classIdx = token.attrIndex('class');
token.attrs[classIdx][1] += ' ' + attrs[j][1];
} else {
token.attrPush(attrs[j]);
}
}
return token;
}

0 comments on commit 4ad28b4

Please sign in to comment.