Repository: shepherdwind/velocity.js (ts)

Issue:
单行注释后面没内容时显示bug
出错代码如下：

~~~
var Velocity = require('velocityjs');
console.log(Velocity.render('##'));
~~~

输出结果为： ##

实际应该为空

建议修正： https://github.com/shepherdwind/velocity.js/blob/master/src/parse/velocity.l 第38行：

~~~
<h,mu>"##"[^\n]+                  { this.popState(); return 'COMMENT'; }
~~~

为

~~~
<h,mu>"##"[^\n]*                  { this.popState(); return 'COMMENT'; }
~~~

Pull request:
fix: comment should support just two ##
close #66

Patch:
diff --git a/src/parse/index.js b/src/parse/index.js
index 3efd7b8..caa4da3 100644
--- a/src/parse/index.js
+++ b/src/parse/index.js
@@ -766,10 +766,10 @@ case 0:
                                       this.begin('esc');
                                     }
                                     if (_num > 1) yy_.yytext = yy_.yytext.replace(/(\\\\)+$/, '\\');
-                                    if(yy_.yytext) return 80; 
+                                    if(yy_.yytext) return 80;
                                   
 break;
-case 1: 
+case 1:
                                     var _reg = /\\+$/;
                                     var _esc = yy_.yytext.match(_reg);
                                     var _num = _esc ? _esc[0].length: null;
@@ -780,7 +780,7 @@ case 1:
                                       this.begin('esc');
                                     }
                                     if (_num > 1) yy_.yytext = yy_.yytext.replace(/(\\\\)+$/, '\\');
-                                    if(yy_.yytext) return 80; 
+                                    if(yy_.yytext) return 80;
                                   
 break;
 case 2: return 80; 
@@ -935,7 +935,7 @@ case 59: return 4;
 break;
 }
 },
-rules: [/^(?:[^#]*?(?=\$))/,/^(?:[^\$]*?(?=#))/,/^(?:[^\x00]+)/,/^(?:#\*[\s\S]+?\*#)/,/^(?:#\[\[[\s\S]+?\]\]#)/,/^(?:##[^\n]+)/,/^(?:#(?=[a-zA-Z{]))/,/^(?:set[ ]*(?=[^a-zA-Z0-9_]+))/,/^(?:if[ ]*(?=[^a-zA-Z0-9_]+))/,/^(?:elseif[ ]*(?=[^a-zA-Z0-9_]+))/,/^(?:else\b)/,/^(?:\{else\})/,/^(?:end\b)/,/^(?:break\b)/,/^(?:foreach[ ]*(?=[^a-zA-Z0-9_]+))/,/^(?:noescape(?=[^a-zA-Z0-9_]+))/,/^(?:define[ ]*(?=[^a-zA-Z0-9_]+))/,/^(?:macro[ ]*(?=[^a-zA-Z0-9_]+))/,/^(?:in\b)/,/^(?:[%\+\-\*\/])/,/^(?:<=)/,/^(?:>=)/,/^(?:[><])/,/^(?:==)/,/^(?:\|\|)/,/^(?:&&)/,/^(?:!=)/,/^(?:\$!(?=[{a-zA-Z_]))/,/^(?:\$(?=[{a-zA-Z_]))/,/^(?:!)/,/^(?:=)/,/^(?:[ ]+(?=[^,]))/,/^(?:\s+)/,/^(?:\{)/,/^(?:\})/,/^(?::[\s]*)/,/^(?:\{)/,/^(?:\})/,/^(?:\([\s]*(?=[$'"\[\{\-0-9\w()!]))/,/^(?:\))/,/^(?:\[[\s]*(?=[\-$"'0-9{\[\]]+))/,/^(?:\])/,/^(?:\.\.)/,/^(?:\.(?=[a-zA-Z_]))/,/^(?:\.(?=[\d]))/,/^(?:,[ ]*)/,/^(?:"(\\"|[^\"])*")/,/^(?:'(\\'|[^\'])*')/,/^(?:null\b)/,/^(?:false\b)/,/^(?:true\b)/,/^(?:[0-9]+)/,/^(?:[_a-zA-Z][a-zA-Z0-9_\-]*)/,/^(?:[_a-zA-Z][a-zA-Z0-9_\-]*[ ]*(?=\())/,/^(?:#)/,/^(?:.)/,/^(?:\s+)/,/^(?:[\$#])/,/^(?:$)/,/^(?:$)/],
+rules: [/^(?:[^#]*?(?=\$))/,/^(?:[^\$]*?(?=#))/,/^(?:[^\x00]+)/,/^(?:#\*[\s\S]+?\*#)/,/^(?:#\[\[[\s\S]+?\]\]#)/,/^(?:##[^\n]*)/,/^(?:#(?=[a-zA-Z{]))/,/^(?:set[ ]*(?=[^a-zA-Z0-9_]+))/,/^(?:if[ ]*(?=[^a-zA-Z0-9_]+))/,/^(?:elseif[ ]*(?=[^a-zA-Z0-9_]+))/,/^(?:else\b)/,/^(?:\{else\})/,/^(?:end\b)/,/^(?:break\b)/,/^(?:foreach[ ]*(?=[^a-zA-Z0-9_]+))/,/^(?:noescape(?=[^a-zA-Z0-9_]+))/,/^(?:define[ ]*(?=[^a-zA-Z0-9_]+))/,/^(?:macro[ ]*(?=[^a-zA-Z0-9_]+))/,/^(?:in\b)/,/^(?:[%\+\-\*\/])/,/^(?:<=)/,/^(?:>=)/,/^(?:[><])/,/^(?:==)/,/^(?:\|\|)/,/^(?:&&)/,/^(?:!=)/,/^(?:\$!(?=[{a-zA-Z_]))/,/^(?:\$(?=[{a-zA-Z_]))/,/^(?:!)/,/^(?:=)/,/^(?:[ ]+(?=[^,]))/,/^(?:\s+)/,/^(?:\{)/,/^(?:\})/,/^(?::[\s]*)/,/^(?:\{)/,/^(?:\})/,/^(?:\([\s]*(?=[$'"\[\{\-0-9\w()!]))/,/^(?:\))/,/^(?:\[[\s]*(?=[\-$"'0-9{\[\]]+))/,/^(?:\])/,/^(?:\.\.)/,/^(?:\.(?=[a-zA-Z_]))/,/^(?:\.(?=[\d]))/,/^(?:,[ ]*)/,/^(?:"(\\"|[^\"])*")/,/^(?:'(\\'|[^\'])*')/,/^(?:null\b)/,/^(?:false\b)/,/^(?:true\b)/,/^(?:[0-9]+)/,/^(?:[_a-zA-Z][a-zA-Z0-9_\-]*)/,/^(?:[_a-zA-Z][a-zA-Z0-9_\-]*[ ]*(?=\())/,/^(?:#)/,/^(?:.)/,/^(?:\s+)/,/^(?:[\$#])/,/^(?:$)/,/^(?:$)/],
 conditions: {"mu":{"rules":[5,27,28,36,37,38,39,40,41,43,52,54,55,56,58],"inclusive":false},"c":{"rules":[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,38,39,40,41,43,44,45,46,47,48,49,50,51,52],"inclusive":false},"i":{"rules":[18,19,20,21,22,23,24,25,26,27,28,29,30,32,33,33,34,34,35,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52],"inclusive":false},"h":{"rules":[3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,27,28,29,30,35,38,39,40,41,43,51,53,55,56,58],"inclusive":false},"esc":{"rules":[57],"inclusive":false},"run":{"rules":[27,28,29,31,32,33,34,35,38,39,40,41,43,44,45,46,47,48,49,50,51,52,55,56,58],"inclusive":false},"INITIAL":{"rules":[0,1,2,59],"inclusive":true}}
 });
 return lexer;
diff --git a/src/parse/velocity.l b/src/parse/velocity.l
index 2f997ba..9dacaa0 100644
--- a/src/parse/velocity.l
+++ b/src/parse/velocity.l
@@ -15,10 +15,10 @@
                                       this.begin('esc');
                                     }
                                     if (_num > 1) yytext = yytext.replace(/(\\\\)+$/, '\\');
-                                    if(yytext) return 'CONTENT'; 
+                                    if(yytext) return 'CONTENT';
                                   }
 
-[^\$]*?/"#"                       { 
+[^\$]*?/"#"                       {
                                     var _reg = /\\+$/;
                                     var _esc = yytext.match(_reg);
                                     var _num = _esc ? _esc[0].length: null;
@@ -29,13 +29,13 @@
                                       this.begin('esc');
                                     }
                                     if (_num > 1) yytext = yytext.replace(/(\\\\)+$/, '\\');
-                                    if(yytext) return 'CONTENT'; 
+                                    if(yytext) return 'CONTENT';
                                   }
 
 [^\x00]+                          { return 'CONTENT'; }
 <h>"#"\*[\s\S]+?\*"#"             { this.popState(); return 'COMMENT'; }
 <h>"#"\[\[[\s\S]+?\]\]"#"         { this.popState(); yytext = yytext.replace(/^#\[\[|\]\]#$/g, ''); return 'RAW'}
-<h,mu>"##"[^\n]+                  { this.popState(); return 'COMMENT'; }
+<h,mu>"##"[^\n]*                  { this.popState(); return 'COMMENT'; }
 <h>"#"/[a-zA-Z{]                  { return 'HASH'; }
 <h>"set"[ ]*/[^a-zA-Z0-9_]+       { return 'SET'; }
 <h>"if"[ ]*/[^a-zA-Z0-9_]+        { return 'IF'; }


Test patch:
diff --git a/tests/comment.test.js b/tests/comment.test.js
new file mode 100644
index 0000000..f23478f
--- /dev/null
+++ b/tests/comment.test.js
@@ -0,0 +1,7 @@
+var Velocity = require('../src/velocity')
+
+describe('comment render', function() {
+  it('fix #66', function() {
+    Velocity.render('##').should.eql('');
+  });
+});
diff --git a/tests/parse.js b/tests/parse.js
index c226ba7..526da74 100644
--- a/tests/parse.js
+++ b/tests/parse.js
@@ -226,6 +226,17 @@ describe('Parser', function() {
       assert.equal('comment', asts[1].type)
     })
 
+    it('all comment', function() {
+      var asts = parse('##number literal')
+
+      asts.length.should.equal(1)
+      asts[0].type.should.equal('comment');
+
+      asts = parse('##');
+      asts.length.should.equal(1)
+      asts[0].type.should.equal('comment');
+    });
+
   })
 
   describe('raw identify', function() {