diff --git a/pseudocode.js b/pseudocode.js index d9a7a271c9c9ec588fe0012a8858d9e1da63e17c..97e8eedd5ce438e13c1c20112ecc1a776e6e6df0 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 2e9d4e1bd614bef4083b1c61985e5d350270fd5d..4cd5b80de837bbe301ce02a1fee13fe6114b59f1 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 738267470a58717347a3934baad95eeb43b03d99..dd93074c08acf93f2bb8489a44d8730ba4d94482 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 4beb1a87efeb7e2036ad852ad4bb496bf46cbd66..8f8e8b908d2f8b85fcc7da586c12d1c5181f980a 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 158a79dd05f10e48ac2c2072842cbca3deabdb47..af94c9c2a6e824122356999fa37395e63b37c139 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;