Skip to content

Instantly share code, notes, and snippets.

@TimothyGu
Last active August 11, 2016 20:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TimothyGu/4e54336c988a6adbbd02d276b539937c to your computer and use it in GitHub Desktop.
Save TimothyGu/4e54336c988a6adbbd02d276b539937c to your computer and use it in GitHub Desktop.
{
"name": "posthtml-pug",
"version": "1.0.0",
"description": "PostHTML Pug parser",
"main": "index.js",
"dependencies": {
"constantinople": "^3.1.0",
"isobject": "^2.1.0",
"object-assign": "^4.1.0",
"pug": "^2.0.0-beta5",
"pug-error": "^1.3.1",
"pug-walk": "0.0.3"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/timothygu/posthtml-pug.git"
},
"keywords": [
"pug",
"posthtml"
],
"author": "Timothy Gu <timothygu99@gmail.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/timothygu/posthtml-pug/issues"
},
"homepage": "https://github.com/timothygu/posthtml-pug#readme"
}
var constantinople = require('constantinople');
var pug = require('pug');
var pugError = require('pug-error');
var walk = require('pug-walk');
var objectAssign = require('object-assign');
var isObject = require('isobject');
var isConstant = constantinople.isConstant;
var toConstant = constantinople.toConstant;
var defaultOptions = {
plugins: []
};
function postHTMLPugParser(html, options) {
var stack = [];
var results = [];
var pugPlugin = {
postLex: function (toks) {
var out = [];
toks.forEach(function (tok) {
switch (tok.type) {
case 'attribute':
if (isConstant(tok.val)) {
tok.val = toConstant(tok.val);
if (tok.val === true) tok.val = '';
if (tok.val !== false) out.push(tok);
} else {
throw error('POSTHTML_NOT_CONSTANT', 'Attribute value is not constant');
}
break;
default:
out.push(tok);
}
function error(code, msg) {
return pugError(code, msg, {
line: tok.line,
column: tok.col,
src: html
});
}
});
return out;
},
preCodeGen: function (ast) {
walk(ast, function (node) {
switch (node.type) {
case 'Tag':
stack.push({
tag: node.name,
attrs: node.attrs.reduce(function (attrs, cur) {
attrs[cur.name] = cur.val;
return attrs;
}, {}),
content: []
});
break;
}
}, function (node) {
switch (node.type) {
case 'Text':
var last = stack[stack.length - 1] || {content: results};
if (typeof last.content[last.content.length - 1] === 'string') {
last.content[last.content.length - 1] += node.val;
} else {
last.content.push(node.val);
}
break;
case 'Tag':
var buf = stack.pop();
var last = stack[stack.length - 1] || {content: results};
last.content.push(buf);
break;
}
});
throw 'DONE';
}
};
options.plugins.push(pugPlugin);
try {
pug.compile(html, options);
} catch (err) {
if (err === 'DONE') return results;
throw err;
}
};
function parserWrapper(html, options) {
if (isObject(html)) {
options = objectAssign({}, defaultOptions);
return function (html) {
return postHTMLPugParser(html, options);
};
}
options = objectAssign({}, defaultOptions);
return postHTMLPugParser(html, options);
}
module.exports = parserWrapper;
module.exports.defaultOptions = defaultOptions;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment