Skip to content

Commit

Permalink
feat(parser): Support array results. Support custom bem naming
Browse files Browse the repository at this point in the history
  • Loading branch information
voischev committed Aug 3, 2015
1 parent 2e40cdd commit cfc63c1
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 32 deletions.
97 changes: 70 additions & 27 deletions lib/parser.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,77 @@
import htmlparser from 'htmlparser2';
import bemNaming from 'bem-naming';
import stringifyObj from 'stringify-object';
import vm from 'vm';

var parser = {};

class Convert {
parse(html, options = {}) {

constructor() {
this.bufArray = [];
this.bufArray.last = function() {
let naming = bemNaming(options),
bufArray = [],
results = [];

bufArray.last = function() {
return this[this.length - 1];
};

this.results = {};
}

parse(html) {
let _this = this;
let parser = new htmlparser.Parser({
onopentag: function(tag, attrs) {
let buf = {},
var buf = {},
classes = attrs.class && attrs.class.split(' '),
block = classes && bemNaming.parse(classes.shift()),
block = classes && naming.parse(classes.shift()),
i;

for (i in block) {
buf[i] = block[i];
}

if (classes && classes.length) {
classes.map(bemNaming.parse).forEach(entity => {
if (entity.block === buf.block && entity.modName) {
buf.mods || (buf.mods = {});
buf.mods[entity.modName] = entity.modVal;
} else {
classes.map(naming.parse, naming).forEach(entity => {
var modFieldName = entity.elem ? 'elemMods' : 'mods';

if (
entity.block === buf.block &&
entity.elem === buf.elem &&
entity.modName
) {
buf[modFieldName] || (buf[modFieldName] = {});
buf[modFieldName][entity.modName] = entity.modVal;
} else { // build mixes
if (entity.modName) {
var mixes = buf.mix,
currentMixingItem;

if (mixes) {
for (var i = 0; i < buf.mix.length; i++) {
if ((mixes[i].block === entity.block) && mixes[i].elem === entity.elem) {
currentMixingItem = mixes[i];
}
}
}

if (currentMixingItem) {
currentMixingItem[modFieldName] || (currentMixingItem[modFieldName] = {});
currentMixingItem[modFieldName][entity.modName] = entity.modVal;

return;
} else {
entity[modFieldName] = {};
entity[modFieldName][entity.modName] = entity.modVal;
delete entity.modName;
delete entity.modVal;
}
}

buf.mix = (buf.mix || []).concat(entity);
}
});
}

delete attrs.class;

let js = attrs['data-bem'] || attrs.onclick;
var js = attrs['data-bem'] || attrs.onclick;

if (js) {
js = js.replace(/&quot;/g, '\'');
Expand Down Expand Up @@ -79,15 +109,20 @@ class Convert {

if (!isEmpty(attrs)) buf.attrs = attrs;

_this.bufArray.push(buf);
if (isEmpty(buf)) buf = { content: '' };

bufArray.push(buf);
},
onclosetag: function() {
let buf = _this.bufArray.pop();
if (_this.bufArray.length === 0) {
_this.results = buf;
return _this.results;
var buf = bufArray.pop();

if (bufArray.length === 0) {
results.push(buf);

return;
}
let last = _this.bufArray.last();

var last = bufArray.last();
if (!(last.content instanceof Array)) {
last.content = [];
}
Expand All @@ -96,22 +131,27 @@ class Convert {
ontext: function(text) {
if (text.match(/(^\n|^\n\s+$)/g)) return;

let last = _this.bufArray.last();
var last = bufArray.last();
if (!last) return;

last.content = last.content || [];
last.content || (last.content = []);
last.content.push(text);
}
});

parser.write(html);
parser.end();

return this.results;
return results;
}

}

parser.convert = new Convert();
parser.stringify = stringify;
export default parser;


function isEmpty(obj) {
for(let key in obj) {
if(Object.prototype.hasOwnProperty.call(obj, key)) {
Expand All @@ -121,6 +161,9 @@ function isEmpty(obj) {
return true;
}

parser.convert = new Convert();
function stringify(html, options) {
options || (options = {});
options.indent || (options.indent = ' ');

export default parser;
return stringifyObj(parser.convert(html, options), options);
}
9 changes: 5 additions & 4 deletions lib/posthtml.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ class Posthtml {
/**
* Parse html to json tree
* @param {String} html htmltree
* @param {Object} options options for parser
* @return {String} json jsontree
*/
parse(html) {
return [convert.parse(html)];
parse(html, options) {
return convert.parse(html, options);
}

/**
Expand All @@ -32,13 +33,13 @@ class Posthtml {
* @param {Object} options Options obj
* @return {Object} result
*/
process(tree, { tmplOptions, skipParse } = {}) {
process(tree, { tmplOptions, skipParse, naming } = {}) {

tmplOptions && tmpl.setOptions(tmplOptions);

return new Promise(resolve => {

tree = skipParse ? tree : this.parse(tree);
tree = skipParse ? tree : this.parse(tree, naming);

this.plugins.forEach(plugin => {
let result = plugin(tree);
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
"babel": "^5.6.14",
"bem-naming": "^0.5.1",
"bh": "^4.1.0",
"htmlparser2": "^3.8.3"
"htmlparser2": "^3.8.3",
"stringify-object": "^2.3.0"
},
"peerDependencies": {},
"devDependencies": {
Expand Down

0 comments on commit cfc63c1

Please sign in to comment.