From 1b88d18d613be4d7d9401195f1dd96b4d4119cbf Mon Sep 17 00:00:00 2001 From: Jeremy Ashkenas Date: Mon, 23 Aug 2010 21:00:47 -0400 Subject: [PATCH] more tweaks and futzes to block comments. --- lib/lexer.js | 23 +++++++++++++++-------- src/lexer.coffee | 17 ++++++++++------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/lib/lexer.js b/lib/lexer.js index e847085d..5993ddc3 100644 --- a/lib/lexer.js +++ b/lib/lexer.js @@ -169,9 +169,10 @@ } this.line += count(match[1], "\n"); this.i += match[1].length; - if (match[2]) { - this.token('HERECOMMENT', this.sanitizeHeredoc(match[2], { - herecomment: true + if (match[4]) { + this.token('HERECOMMENT', this.sanitizeHeredoc(match[4], { + herecomment: true, + indent: match[3] })); this.token('TERMINATOR', '\n'); } @@ -389,10 +390,16 @@ }; Lexer.prototype.sanitizeHeredoc = function(doc, options) { var _d, attempt, indent, match; - 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; + indent = options.indent || ''; + if (options.herecomment && !include(doc, '\n')) { + return doc; + } + 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'), ''); @@ -603,7 +610,7 @@ HEREDOC = /^("{6}|'{6}|"{3}\n?([\s\S]*?)\n?([ \t]*)"{3}|'{3}\n?([\s\S]*?)\n?([ \t]*)'{3})/; OPERATOR = /^(-[\-=>]?|\+[+=]?|[*&|\/%=<>^:!?]+)([ \t]*)/; WHITESPACE = /^([ \t]+)/; - COMMENT = /^(\s*###(?!#)([\s\S]*?)(###[ \t]*\n|(###)?$)|(\s*#(?!##[^#])[^\n]*)+)/; + COMMENT = /^(([ \t]*\n)*([ \t]*)###([^#][\s\S]*?)(###[ \t]*\n|(###)?$)|(\s*#(?!##[^#])[^\n]*)+)/; CODE = /^((-|=)>)/; MULTI_DENT = /^((\n([ \t]*))+)(\.)?/; LAST_DENTS = /\n([ \t]*)/g; diff --git a/src/lexer.coffee b/src/lexer.coffee index 483023dc..4e9aa8e6 100644 --- a/src/lexer.coffee +++ b/src/lexer.coffee @@ -144,8 +144,8 @@ exports.Lexer = class Lexer return false unless match = @chunk.match(COMMENT) @line += count match[1], "\n" @i += match[1].length - if match[2] - @token 'HERECOMMENT', @sanitizeHeredoc match[2], herecomment: true + if match[4] + @token 'HERECOMMENT', @sanitizeHeredoc match[4], herecomment: true, indent: match[3] @token 'TERMINATOR', '\n' true @@ -319,10 +319,13 @@ exports.Lexer = class Lexer # Sanitize a heredoc or herecomment by escaping internal double quotes and # erasing all external indentation on the left-hand side. sanitizeHeredoc: (doc, options) -> - 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'), '') + indent = options.indent or '' + return doc if options.herecomment and not include doc, '\n' + unless options.herecomment + 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 doc.replace(MULTILINER, "\\n") .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})/ OPERATOR = /^(-[\-=>]?|\+[+=]?|[*&|\/%=<>^:!?]+)([ \t]*)/ WHITESPACE = /^([ \t]+)/ -COMMENT = /^(\s*###(?!#)([\s\S]*?)(###[ \t]*\n|(###)?$)|(\s*#(?!##[^#])[^\n]*)+)/ +COMMENT = /^(([ \t]*\n)*([ \t]*)###([^#][\s\S]*?)(###[ \t]*\n|(###)?$)|(\s*#(?!##[^#])[^\n]*)+)/ CODE = /^((-|=)>)/ MULTI_DENT = /^((\n([ \t]*))+)(\.)?/ LAST_DENTS = /\n([ \t]*)/g