Skip to content

Instantly share code, notes, and snippets.

@nknapp
Created March 11, 2017 11:37
Show Gist options
  • Save nknapp/ff5b93c7366f6458cea10c88c9521069 to your computer and use it in GitHub Desktop.
Save nknapp/ff5b93c7366f6458cea10c88c9521069 to your computer and use it in GitHub Desktop.
Concept for source-mapping the output of a Handlebars-template back to the template
var Handlebars = require('handlebars');
var LineCounter = require("line-counter");
var env = Handlebars.create();
function SourceMapCompiler() {
}
SourceMapCompiler.prototype = new Handlebars.JavaScriptCompiler();
SourceMapCompiler.prototype.appendToBuffer = function (source, location, explicit) {
var result = Handlebars.JavaScriptCompiler.prototype.appendToBuffer.apply(this, [source, location, true])
return [`helpers.$consumeSourceMapEntry(${result[1].line}, ${result[1].column}, buffer.length);`, result]
}
env.JavaScriptCompiler = SourceMapCompiler
var sourceMappings = []
// A helper seems to be about the only way to pass data from the template function to the calling context
env.registerHelper("$consumeSourceMapEntry", function (sourceLine, sourceColumn, targetIndex) {
sourceMappings.push({
source: {
column: sourceColumn+1,
line: sourceLine
},
target: targetIndex
})
}
)
const template = '1{{abc}}\n2a\n3{{cde}}\n4\n5b\n6\n\n\n\n\n{{abc}}';
var output = env.compile(template)({
abc: 'a\nmultiline\string',
cde: 'x'
});
// Map target-indexes to lines/columns
var counter = new LineCounter(output);
sourceMappings.forEach(function(entry) {
entry.target = counter.locate(entry.target)
})
console.log(sourceMappings)
console.log(JSON.stringify({template, output},null,2))
@nknapp
Copy link
Author

nknapp commented Mar 11, 2017

Mhm, this does not work with partials and block-helpers:

  • The buffer is new when sub-programs are executed. Somehow I have to grab the point where the partial is called and recalculated the target-index based on that point.
  • The SourceNodes in the compile function do not have the information in which partial they occur.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment