Skip to content

Commit

Permalink
Make the scanner comment-aware so <% # ... : %> works as expected. F…
Browse files Browse the repository at this point in the history
  • Loading branch information
sstephenson committed May 27, 2011
1 parent e9b9e3c commit 6c3d650
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 19 deletions.
38 changes: 27 additions & 11 deletions lib/scanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
trim = require("./util").trim;
module.exports = Scanner = (function() {
Scanner.modePatterns = {
data: /(.*?)(<%%|<%(([=-])?)|\n|$)/,
code: /(.*?)(((:|(->|=>))\s*)?%>|\n|$)/
data: /(.*?)(<%%|<%\s*(\#)|<%(([=-])?)|\n|$)/,
code: /(.*?)((((:|(->|=>))\s*))?%>|\n|$)/,
comment: /(.*?)(%>|\n|$)/
};
Scanner.dedentablePattern = /^(end|when|else|catch|finally)(?:\W|$)/;
Scanner.scan = function(source) {
Expand Down Expand Up @@ -45,15 +46,18 @@
return this.scanData(callback);
case "code":
return this.scanCode(callback);
case "comment":
return this.scanComment(callback);
}
}
};
Scanner.prototype.advance = function() {
this.scanner.scanUntil(Scanner.modePatterns[this.mode]);
this.buffer += this.scanner.getCapture(0);
this.tail = this.scanner.getCapture(1);
this.directive = this.scanner.getCapture(3);
return this.arrow = this.scanner.getCapture(4);
this.comment = this.scanner.getCapture(2);
this.directive = this.scanner.getCapture(4);
return this.arrow = this.scanner.getCapture(5);
};
Scanner.prototype.scanData = function(callback) {
if (this.tail === "<%%") {
Expand All @@ -64,14 +68,18 @@
this.lineNo++;
return this.scan(callback);
} else if (this.tail) {
this.mode = "code";
callback(["printString", this.flush()]);
return callback([
"beginCode", {
print: this.directive != null,
safe: this.directive === "-"
}
]);
if (this.comment) {
return this.mode = "comment";
} else {
this.mode = "code";
return callback([
"beginCode", {
print: this.directive != null,
safe: this.directive === "-"
}
]);
}
}
};
Scanner.prototype.scanCode = function(callback) {
Expand All @@ -93,6 +101,14 @@
}
}
};
Scanner.prototype.scanComment = function(callback) {
if (this.tail === "\n") {
return callback(["fail", "unexpected newline in code block"]);
} else if (this.tail) {
this.mode = "data";
return this.buffer = "";
}
};
Scanner.prototype.flush = function() {
var buffer;
buffer = this.buffer;
Expand Down
30 changes: 22 additions & 8 deletions src/scanner.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
{trim} = require "./util"

module.exports = class Scanner
@modePatterns: {
data: /(.*?)(<%%|<%(([=-])?)|\n|$)/
code: /(.*?)(((:|(->|=>))\s*)?%>|\n|$)/
}
@modePatterns:
data: /(.*?)(<%%|<%\s*(\#)|<%(([=-])?)|\n|$)/
code: /(.*?)((((:|(->|=>))\s*))?%>|\n|$)/
comment: /(.*?)(%>|\n|$)/

@dedentablePattern: /^(end|when|else|catch|finally)(?:\W|$)/

Expand Down Expand Up @@ -43,13 +43,16 @@ module.exports = class Scanner
@scanData callback
when "code"
@scanCode callback
when "comment"
@scanComment callback

advance: ->
@scanner.scanUntil Scanner.modePatterns[@mode]
@buffer += @scanner.getCapture 0
@tail = @scanner.getCapture 1
@directive = @scanner.getCapture 3
@arrow = @scanner.getCapture 4
@comment = @scanner.getCapture 2
@directive = @scanner.getCapture 4
@arrow = @scanner.getCapture 5

scanData: (callback) ->
if @tail is "<%%"
Expand All @@ -62,9 +65,12 @@ module.exports = class Scanner
@scan callback

else if @tail
@mode = "code"
callback ["printString", @flush()]
callback ["beginCode", print: @directive?, safe: @directive is "-"]
if @comment
@mode = "comment"
else
@mode = "code"
callback ["beginCode", print: @directive?, safe: @directive is "-"]

scanCode: (callback) ->
if @tail is "\n"
Expand All @@ -79,6 +85,14 @@ module.exports = class Scanner
callback ["recordCode", code]
callback ["indent", @arrow] if @directive

scanComment: (callback) ->
if @tail is "\n"
callback ["fail", "unexpected newline in code block"]

else if @tail
@mode = "data"
@buffer = ""

flush: ->
buffer = @buffer
@buffer = ""
Expand Down
11 changes: 11 additions & 0 deletions test/test_scanner.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,14 @@ module.exports =
test.same ["fail", "unexpected end of template"], tokens.shift()
test.done()

"comments are ignored": (test) ->
tokens = scan "foo\n<%# bar %>\nbaz"
test.same ["printString", "foo\n"], tokens.shift()
test.same ["printString", "\nbaz"], tokens.shift()
test.done()

"a comment tag can end with a colon": (test) ->
tokens = scan "foo\n<% # This is a comment: %>\nbar"
test.same ["printString", "foo\n"], tokens.shift()
test.same ["printString", "\nbar"], tokens.shift()
test.done()

0 comments on commit 6c3d650

Please sign in to comment.