more tweaks and futzes to block comments.

This commit is contained in:
Jeremy Ashkenas 2010-08-23 21:00:47 -04:00
parent b4de17d504
commit 1b88d18d61
2 changed files with 25 additions and 15 deletions

View File

@ -169,9 +169,10 @@
} }
this.line += count(match[1], "\n"); this.line += count(match[1], "\n");
this.i += match[1].length; this.i += match[1].length;
if (match[2]) { if (match[4]) {
this.token('HERECOMMENT', this.sanitizeHeredoc(match[2], { this.token('HERECOMMENT', this.sanitizeHeredoc(match[4], {
herecomment: true herecomment: true,
indent: match[3]
})); }));
this.token('TERMINATOR', '\n'); this.token('TERMINATOR', '\n');
} }
@ -389,10 +390,16 @@
}; };
Lexer.prototype.sanitizeHeredoc = function(doc, options) { Lexer.prototype.sanitizeHeredoc = function(doc, options) {
var _d, attempt, indent, match; var _d, attempt, indent, match;
while (match = HEREDOC_INDENT.exec(doc)) { indent = options.indent || '';
attempt = (typeof (_d = match[2]) !== "undefined" && _d !== null) ? match[2] : match[3]; if (options.herecomment && !include(doc, '\n')) {
if (!indent || attempt.length < indent.length) { return doc;
indent = attempt; }
if (!(options.herecomment)) {
while (match = HEREDOC_INDENT.exec(doc)) {
attempt = (typeof (_d = match[2]) !== "undefined" && _d !== null) ? match[2] : match[3];
if (!indent || attempt.length < indent.length) {
indent = attempt;
}
} }
} }
doc = doc.replace(new RegExp("^" + indent, 'gm'), ''); doc = doc.replace(new RegExp("^" + indent, 'gm'), '');
@ -603,7 +610,7 @@
HEREDOC = /^("{6}|'{6}|"{3}\n?([\s\S]*?)\n?([ \t]*)"{3}|'{3}\n?([\s\S]*?)\n?([ \t]*)'{3})/; HEREDOC = /^("{6}|'{6}|"{3}\n?([\s\S]*?)\n?([ \t]*)"{3}|'{3}\n?([\s\S]*?)\n?([ \t]*)'{3})/;
OPERATOR = /^(-[\-=>]?|\+[+=]?|[*&|\/%=<>^:!?]+)([ \t]*)/; OPERATOR = /^(-[\-=>]?|\+[+=]?|[*&|\/%=<>^:!?]+)([ \t]*)/;
WHITESPACE = /^([ \t]+)/; WHITESPACE = /^([ \t]+)/;
COMMENT = /^(\s*###(?!#)([\s\S]*?)(###[ \t]*\n|(###)?$)|(\s*#(?!##[^#])[^\n]*)+)/; COMMENT = /^(([ \t]*\n)*([ \t]*)###([^#][\s\S]*?)(###[ \t]*\n|(###)?$)|(\s*#(?!##[^#])[^\n]*)+)/;
CODE = /^((-|=)>)/; CODE = /^((-|=)>)/;
MULTI_DENT = /^((\n([ \t]*))+)(\.)?/; MULTI_DENT = /^((\n([ \t]*))+)(\.)?/;
LAST_DENTS = /\n([ \t]*)/g; LAST_DENTS = /\n([ \t]*)/g;

View File

@ -144,8 +144,8 @@ exports.Lexer = class Lexer
return false unless match = @chunk.match(COMMENT) return false unless match = @chunk.match(COMMENT)
@line += count match[1], "\n" @line += count match[1], "\n"
@i += match[1].length @i += match[1].length
if match[2] if match[4]
@token 'HERECOMMENT', @sanitizeHeredoc match[2], herecomment: true @token 'HERECOMMENT', @sanitizeHeredoc match[4], herecomment: true, indent: match[3]
@token 'TERMINATOR', '\n' @token 'TERMINATOR', '\n'
true true
@ -319,10 +319,13 @@ exports.Lexer = class Lexer
# Sanitize a heredoc or herecomment by escaping internal double quotes and # Sanitize a heredoc or herecomment by escaping internal double quotes and
# erasing all external indentation on the left-hand side. # erasing all external indentation on the left-hand side.
sanitizeHeredoc: (doc, options) -> sanitizeHeredoc: (doc, options) ->
while match = HEREDOC_INDENT.exec(doc) indent = options.indent or ''
attempt = if match[2]? then match[2] else match[3] return doc if options.herecomment and not include doc, '\n'
indent = attempt if not indent or attempt.length < indent.length unless options.herecomment
doc = doc.replace(new RegExp("^" +indent, 'gm'), '') while match = HEREDOC_INDENT.exec(doc)
attempt = if match[2]? then match[2] else match[3]
indent = attempt if not indent or attempt.length < indent.length
doc = doc.replace(new RegExp("^" + indent, 'gm'), '')
return doc if options.herecomment return doc if options.herecomment
doc.replace(MULTILINER, "\\n") doc.replace(MULTILINER, "\\n")
.replace(new RegExp(options.quote, 'g'), "\\#{options.quote}") .replace(new RegExp(options.quote, 'g'), "\\#{options.quote}")
@ -520,7 +523,7 @@ NUMBER = /^(((\b0(x|X)[0-9a-fA-F]+)|((\b[0-9]+(\.[0-9]+)?|\.[0-9]+)(e[+\-
HEREDOC = /^("{6}|'{6}|"{3}\n?([\s\S]*?)\n?([ \t]*)"{3}|'{3}\n?([\s\S]*?)\n?([ \t]*)'{3})/ HEREDOC = /^("{6}|'{6}|"{3}\n?([\s\S]*?)\n?([ \t]*)"{3}|'{3}\n?([\s\S]*?)\n?([ \t]*)'{3})/
OPERATOR = /^(-[\-=>]?|\+[+=]?|[*&|\/%=<>^:!?]+)([ \t]*)/ OPERATOR = /^(-[\-=>]?|\+[+=]?|[*&|\/%=<>^:!?]+)([ \t]*)/
WHITESPACE = /^([ \t]+)/ WHITESPACE = /^([ \t]+)/
COMMENT = /^(\s*###(?!#)([\s\S]*?)(###[ \t]*\n|(###)?$)|(\s*#(?!##[^#])[^\n]*)+)/ COMMENT = /^(([ \t]*\n)*([ \t]*)###([^#][\s\S]*?)(###[ \t]*\n|(###)?$)|(\s*#(?!##[^#])[^\n]*)+)/
CODE = /^((-|=)>)/ CODE = /^((-|=)>)/
MULTI_DENT = /^((\n([ \t]*))+)(\.)?/ MULTI_DENT = /^((\n([ \t]*))+)(\.)?/
LAST_DENTS = /\n([ \t]*)/g LAST_DENTS = /\n([ \t]*)/g