81 lines
2.3 KiB
JavaScript
81 lines
2.3 KiB
JavaScript
module.exports = function regionExtractor() {
|
|
|
|
var nullLine = '###';
|
|
var nullLinePattern = new RegExp(nullLine + '\n', 'g');
|
|
|
|
// split out each fragment in {content} into a separate doc
|
|
// a fragment is a section of text surrounded by
|
|
// 1) In front: a comment marker followed by '#docregion' followed by an optional region name. For example:
|
|
// <-- #docregion foo --> for html
|
|
// or // #docregion foo for js/ts
|
|
// 2) In back: a comment marker followed by '#enddocregion'
|
|
// Regions can be nested and any regions not 'closed' are automatically closed at the end of the doc.
|
|
return function(content, commentPrefixes) {
|
|
|
|
var lines = result = content.split(/\r?\n/);
|
|
var docs = [];
|
|
var docStack = [];
|
|
var doc = null;
|
|
|
|
lines.forEach(function(line, ix) {
|
|
if (isCommentLine(line, commentPrefixes)) {
|
|
if (hasRegionTag(line)) {
|
|
if (doc) docStack.push(doc);
|
|
doc = {startIx: ix, regionName: getRegionName(line)};
|
|
lines[ix] = nullLine;
|
|
docs.push(doc);
|
|
} else if (hasEndRegionTag(line)) {
|
|
if (doc) {
|
|
lines[ix] = nullLine;
|
|
doc.endIx = ix;
|
|
doc = docStack.pop();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
docs.forEach(function(doc) {
|
|
var content;
|
|
if (doc.endIx) {
|
|
content = lines.slice(doc.startIx + 1, doc.endIx).join('\n');
|
|
} else {
|
|
content = lines.slice(doc.startIx + 1).join('\n');
|
|
}
|
|
// eliminate all #docregion lines
|
|
content = content.replace(nullLinePattern, '');
|
|
if (content.substr(-3) === nullLine) {
|
|
content = content.substr(0, content.length-3);
|
|
}
|
|
doc.content = content;
|
|
});
|
|
return docs;
|
|
}
|
|
|
|
};
|
|
|
|
function isCommentLine(line, commentPrefixes) {
|
|
return commentPrefixes.some(function(prefix) {
|
|
return line.trim().indexOf(prefix) == 0;
|
|
});
|
|
}
|
|
|
|
function hasRegionTag(line) {
|
|
return line.indexOf("#docregion") >= 0;
|
|
}
|
|
|
|
function hasEndRegionTag(line) {
|
|
return line.indexOf("#enddocregion") >= 0;
|
|
}
|
|
|
|
function getRegionName(line) {
|
|
try {
|
|
var name = line.match(/#docregion\s*(\S*).*/)[1];
|
|
// Hack for html regions that look like <!-- #docregion --> or */
|
|
name = name.replace("-->","").replace('\*\/',"");
|
|
return name;
|
|
} catch (e) {
|
|
return '';
|
|
}
|
|
}
|