From a1f72af13f6de3b000a6f3103af73fe6d09d37d7 Mon Sep 17 00:00:00 2001
From: "Tate, Hongliang Tian" <tatetian@gmail.com>
Date: Wed, 18 Mar 2015 10:10:44 +0800
Subject: [PATCH] Commands are no longer case-insensitive

---
 pseudocode.js         |  3 +--
 src/Lexer.js          |  9 ++++++---
 src/Parser.js         | 30 +++++++++++++++---------------
 src/Renderer.js       | 18 +++++++++---------
 static/pseudocode.css |  1 +
 5 files changed, 32 insertions(+), 29 deletions(-)

diff --git a/pseudocode.js b/pseudocode.js
index d9a7a27..97e8eed 100644
--- a/pseudocode.js
+++ b/pseudocode.js
@@ -1,8 +1,7 @@
 /*
- * The entry point of pseudocode-js
+ * The entry points of pseudocode-js
  *
  * TODO:
- *      * demo
  *      * Support color
  *      * Case-insensitive
  *      * elsif
diff --git a/src/Lexer.js b/src/Lexer.js
index 2e9d4e1..4cd5b80 100644
--- a/src/Lexer.js
+++ b/src/Lexer.js
@@ -137,10 +137,13 @@ Lexer.prototype._matchText = function(text) {
     // don't need to match
     if (text === null || text === undefined) return true;
 
+    // string comparisons are case-insensitive
     if (utils.isString(text)) // is a string, exactly the same?
-        return text === this._nextAtom.text;
-    else // is a list, match any of them?
-        return text.indexOf(this._nextAtom.text) >= 0;
+        return text.toLowerCase() === this._nextAtom.text.toLowerCase();
+    else {// is a list, match any of them?
+        text = text.map(function(str) { return str.toLowerCase(); });
+        return text.indexOf(this._nextAtom.text.toLowerCase()) >= 0;
+    }
 };
 
 module.exports = Lexer;
diff --git a/src/Parser.js b/src/Parser.js
index 7382674..dd93074 100644
--- a/src/Parser.js
+++ b/src/Parser.js
@@ -254,7 +254,7 @@ Parser.prototype._parseControl = function() {
 
 Parser.prototype._parseFunction = function() {
     var lexer = this._lexer;
-    if (!lexer.accept('func', ['FUNCTION', 'PROCEDURE'])) return null;
+    if (!lexer.accept('func', ['function', 'procedure'])) return null;
 
     // \FUNCTION{funcName}{funcArgs}
     var funcType = this._lexer.get().text; // FUNCTION or PROCEDURE
@@ -267,7 +267,7 @@ Parser.prototype._parseFunction = function() {
     // <block>
     var blockNode = this._parseBlock();
     // \ENDFUNCTION
-    lexer.expect('func', 'END' + funcType);
+    lexer.expect('func', 'end' + funcType);
 
     var functionNode = new ParseNode('function',
                         {type: funcType, name: funcName});
@@ -277,7 +277,7 @@ Parser.prototype._parseFunction = function() {
 };
 
 Parser.prototype._parseIf = function() {
-    if (!this._lexer.accept('func', 'IF')) return null;
+    if (!this._lexer.accept('func', 'if')) return null;
 
     var ifNode = new ParseNode('if');
 
@@ -289,7 +289,7 @@ Parser.prototype._parseIf = function() {
 
     // ( \ELIF { <cond> } <block> )[0...n]
     var numElif = 0;
-    while (this._lexer.accept('func', 'ELIF')) {
+    while (this._lexer.accept('func', ['elif', 'elsif', 'elseif'])) {
         this._lexer.expect('open');
         ifNode.addChild(this._parseCond());
         this._lexer.expect('close');
@@ -299,13 +299,13 @@ Parser.prototype._parseIf = function() {
 
     // ( \ELSE <block> )[0..1]
     var hasElse = false;
-    if (this._lexer.accept('func', 'ELSE')) {
+    if (this._lexer.accept('func', 'else')) {
         hasElse = true;
         ifNode.addChild(this._parseBlock());
     }
 
     // \ENDIF
-    this._lexer.expect('func', 'ENDIF');
+    this._lexer.expect('func', 'endif');
 
     ifNode.value = {numElif: numElif, hasElse: hasElse};
     return ifNode;
@@ -314,7 +314,7 @@ Parser.prototype._parseIf = function() {
 Parser.prototype._parseLoop = function() {
     if (!this._lexer.accept('func', ['FOR', 'FORALL', 'WHILE'])) return null;
 
-    var loopName = this._lexer.get().text;
+    var loopName = this._lexer.get().text.toLowerCase();
     var loopNode = new ParseNode('loop', loopName);
 
     // { <cond> } <block>
@@ -324,25 +324,25 @@ Parser.prototype._parseLoop = function() {
     loopNode.addChild(this._parseBlock());
 
     // \ENDFOR
-    var endLoop = loopName !== 'FORALL' ? 'END' + loopName : 'ENDFOR';
+    var endLoop = loopName !== 'forall' ? 'end' + loopName : 'endfor';
     this._lexer.expect('func', endLoop);
 
     return loopNode;
 };
 
-var INPUTS_OUTPUTS_COMMANDS = ['ENSURE', 'REQUIRE'];
-var STATEMENT_COMMANDS = ['STATE', 'PRINT', 'RETURN'];
+var INPUTS_OUTPUTS_COMMANDS = ['ensure', 'require'];
+var STATEMENT_COMMANDS = ['state', 'print', 'return'];
 Parser.prototype._parseCommand = function(acceptCommands) {
     if (!this._lexer.accept('func', acceptCommands)) return null;
 
-    var cmdName = this._lexer.get().text;
+    var cmdName = this._lexer.get().text.toLowerCase();
     var cmdNode = new ParseNode('command', cmdName);
     cmdNode.addChild(this._parseOpenText());
     return cmdNode;
 };
 
 Parser.prototype._parseComment = function() {
-    if (!this._lexer.accept('func', 'COMMENT')) return null;
+    if (!this._lexer.accept('func', 'comment')) return null;
 
     var commentNode = new ParseNode('comment');
 
@@ -356,7 +356,7 @@ Parser.prototype._parseComment = function() {
 
 Parser.prototype._parseCall = function() {
     var lexer = this._lexer;
-    if (!lexer.accept('func', 'CALL')) return null;
+    if (!lexer.accept('func', 'call')) return null;
 
     var anyWhitespace = lexer.get().whitespace;
 
@@ -424,7 +424,7 @@ var ACCEPTED_TOKEN_BY_ATOM = {
     'special': { tokenType: 'special' },
     'cond-symbol': {
         tokenType: 'func',
-        tokenValues: ['AND', 'OR', 'NOT', 'TRUE', 'FALSE', 'TO']
+        tokenValues: ['and', 'or', 'not', 'true', 'false', 'to']
     },
     'quote-symbol': {
         tokenType: 'quote'
@@ -461,7 +461,7 @@ Parser.prototype._parseAtom = function() {
         if (tokenText === null) continue;
 
         var anyWhitespace = this._lexer.get().whitespace;
-        return new AtomNode(atomType, tokenText, anyWhitespace);
+        return new AtomNode(atomType, tokenText.toLowerCase(), anyWhitespace);
     }
     return null;
 };
diff --git a/src/Renderer.js b/src/Renderer.js
index 4beb1a8..8f8e8b9 100644
--- a/src/Renderer.js
+++ b/src/Renderer.js
@@ -503,7 +503,7 @@ Renderer.prototype._newLine = function() {
             this._html.beginSpan('ps-linenum', {
                 'left': - ((this._blockLevel - 1)*(indentSize* 1.25)) + 'em'
             })
-            .putText(this._numLOC + this._options.lineNumberPunc + ' ')
+            .putText(this._numLOC + this._options.lineNumberPunc)
             .endSpan();
         }
     }
@@ -706,9 +706,9 @@ Renderer.prototype._buildTree = function(node) {
         this._newLine();
         var loopType = node.value;
         var displayLoopName = {
-            'FOR': 'for',
-            'FORALL': 'for all',
-            'WHILE': 'while'
+            'for': 'for',
+            'forall': 'for all',
+            'while': 'while'
         };
         this._typeKeyword(displayLoopName[loopType] + ' ');
         var loopCond = node.children[0];
@@ -736,11 +736,11 @@ Renderer.prototype._buildTree = function(node) {
         // commands: \STATE, \ENSURE, \PRINT, \RETURN, etc.
         var cmdName = node.value;
         var displayName = {
-            'STATE': '',
-            'ENSURE': 'Ensure: ',
-            'REQUIRE': 'Require: ',
-            'PRINT': 'print ',
-            'RETURN': 'return '
+            'state': '',
+            'ensure': 'Ensure: ',
+            'require': 'Require: ',
+            'print': 'print ',
+            'return': 'return '
         }[cmdName];
 
         this._newLine();
diff --git a/static/pseudocode.css b/static/pseudocode.css
index 158a79d..af94c9c 100644
--- a/static/pseudocode.css
+++ b/static/pseudocode.css
@@ -50,6 +50,7 @@
     text-align: right;
     display: inline-block;
     position: relative;
+    padding-right: 0.3em;
 }
 .ps-root .ps-algorithmic.with-linenum .ps-line.ps-code {
     text-indent: -1.6em;
-- 
GitLab