marko/compiler/taglib-loader/tag-def-from-code.js

59 lines
1.9 KiB
JavaScript

// Rather than using a full-blown JavaScript parser, we are going to use a few regular expressions
// to tokenize the code and find what we are interested in
var tagStartRegExp = /(^\s*(?:(?:exports.(?:tag|TAG))|(?:TAG))\s*=\s*)\{/m;
// Tokens: "<string>", '<string>', /*<some comment*/, //<single line comment>, {, }, ;
var tokensRegExp = /"(?:[^"]|\\")*"|'(?:[^'])|(\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\/)|(\/\/.*)|[\{\};]/g;
function extractTagDef(code) {
var startMatches = tagStartRegExp.exec(code);
var tagDefStart;
var tagDefEnd;
if (startMatches) {
tagDefStart = startMatches.index + startMatches[1].length;
var nextTokenMatches;
tokensRegExp.lastIndex = tagDefStart;
var depth = 0;
while ((nextTokenMatches = tokensRegExp.exec(code))) {
if (nextTokenMatches[0] === '{') {
depth++;
continue;
} else if (nextTokenMatches[0] === '}') {
if (--depth === 0) {
tagDefEnd = tokensRegExp.lastIndex;
break;
}
}
else if (nextTokenMatches[0] === ';') {
tagDefEnd = nextTokenMatches.index;
break;
}
}
if (tagDefStart != null && tagDefEnd != null) {
var jsTagDef = code.substring(tagDefStart, tagDefEnd);
var tagDefObject;
try {
// Try parsing it as JSON
tagDefObject = JSON.parse(jsTagDef);
} catch(e) {
// Try parsing it as JavaScript
try {
tagDefObject = eval('(' + jsTagDef + ')');
} catch(e) {
tagDefObject = {};
}
}
return tagDefObject;
}
} else {
return null;
}
}
exports.extractTagDef = extractTagDef;