Number support
authorKris Kowal <kris.kowal@cixar.com>
Tue, 4 Sep 2012 23:04:33 +0000 (16:04 -0700)
committerKris Kowal <kris.kowal@cixar.com>
Tue, 4 Sep 2012 23:05:06 +0000 (16:05 -0700)
beleriand.js
classical.js
dan-smith.js
document-parser.js
general-use.js
minify.sh
numbers.js [new file with mode: 0644]
numerals.js [deleted file]
parser.js

index a7b8dea..22539cd 100644 (file)
@@ -4,6 +4,7 @@ var Parser = require("./parser");
 var makeDocumentParser = require("./document-parser");
 var normalize = require("./normalize");
 var punctuation = require("./punctuation");
+var parseNumber = require("./numbers");
 
 exports.name = "Mode of Beleriand";
 
@@ -47,7 +48,15 @@ function parseWord(callback, options, columns) {
                 columns.concat([column])
             );
         } else {
-            return callback(columns);
+            return function (character) {
+                if (/\d/.test(character)) {
+                    return parseNumber(function (number) {
+                        return parseWord(callback, options, columns.concat(number));
+                    }, options)(character);
+                } else {
+                    return callback(columns)(character);
+                }
+            };
         }
     }, options);
 }
@@ -300,7 +309,7 @@ function parseTengwa(callback, options) {
             return callback(makeColumn("silme").addError("Z does not appear in the mode of Beleriand"));
         } else if (punctuation[character]) {
             return callback(makeColumn(punctuation[character]));
-        } else if (Parser.isBreak(character)) {
+        } else if (Parser.isBreak(character) || /\d/.test(character)) {
             return callback()(character);
         } else {
             return callback(makeColumn("anna").addError("Unexpected character: " + JSON.stringify(character)));
index 50a1d32..ed94029 100644 (file)
@@ -5,6 +5,7 @@ var Parser = require("./parser");
 var makeDocumentParser = require("./document-parser");
 var normalize = require("./normalize");
 var punctuation = require("./punctuation");
+var parseNumber = require("./numbers");
 
 exports.name = "Classical Mode";
 
@@ -105,6 +106,8 @@ function parseColumn(callback, options, previous) {
                 return function (character) {
                     if (Parser.isBreak(character)) {
                         return callback([])(character);
+                    } else if (/\d/.test(character)) {
+                        return parseNumber(callback, options)(character);
                     } else if (punctuation[character]) {
                         return callback([makeColumn(punctuation[character])]);
                     } else {
index dc573d9..d4a5043 100644 (file)
@@ -64,19 +64,19 @@ exports.tengwar = {
     "close-paren": "&#156;",
     "flourish-left": "&#286;",
     "flourish-right": "&#287;",
-    // numerals
-    "#0": "",
-    "#1": "Ò",
-    "#2": "Ú",
-    "#3": "Û",
-    "#4": "Ù",
-    "#5": "ı",
-    "#6": "ˆ",
-    "#7": "˜",
-    "#8": "¯",
-    "#9": "˘",
-    "#10": "˙",
-    "#11": "˚"
+    // numbers
+    "0":  "&#240",
+    "1":  "&#241",
+    "2":  "&#242",
+    "3":  "&#243",
+    "4":  "&#244",
+    "5":  "&#245",
+    "6":  "&#246",
+    "7":  "&#247",
+    "8":  "&#248",
+    "9":  "&#249",
+    "10": "&#250",
+    "11": "&#251"
 };
 
 exports.tehtar = {
index 044a34f..afd9f91 100644 (file)
@@ -15,10 +15,11 @@ function makeDocumentParser(parseWord, makeOptions) {
     });
 }
 
-var parseAnySpaces = Parser.makeParseAny(" ");
-var parseSomeSpaces = Parser.makeParseSome(" ");
+var parseSpace = Parser.makeExpect(" ");
+var parseAnySpaces = Parser.makeParseAny(parseSpace);
+var parseSomeSpaces = Parser.makeParseSome(parseSpace);
 var parseNewline = Parser.makeExpect("\n");
-var parseNewlines = Parser.makeParseSome("\n");
+var parseNewlines = Parser.makeParseSome(parseNewline);
 
 function parseNewlineSpace(callback) {
     return parseAnySpaces(function () {
index caa81a0..3ca096f 100644 (file)
@@ -5,7 +5,7 @@ var Parser = require("./parser");
 var makeDocumentParser = require("./document-parser");
 var normalize = require("./normalize");
 var punctuation = require("./punctuation");
-var parseNumber = require("./numerals");
+var parseNumber = require("./numbers");
 
 exports.name = "General Use Mode";
 
@@ -154,6 +154,8 @@ function parseColumn(callback, options, previous) {
                 return function (character) {
                     if (Parser.isBreak(character)) {
                         return callback([]);
+                    } else if (/\d/.test(character)) {
+                        return parseNumber(callback, options)(character);
                     } else if (punctuation[character]) {
                         return callback([makeColumn(punctuation[character])]);
                     } else {
index 867798f..535281d 100644 (file)
--- a/minify.sh
+++ b/minify.sh
@@ -15,7 +15,7 @@
             dan-smith.js \
             alphabet.js \
             punctuation.js \
-            numerals.js \
+            numbers.js \
             notation.js \
             normalize.js \
             parser.js \
diff --git a/numbers.js b/numbers.js
new file mode 100644 (file)
index 0000000..ed96ed7
--- /dev/null
@@ -0,0 +1,59 @@
+
+var Parser = require("./parser");
+
+var array_ = Array.prototype;
+
+module.exports = parseNumber;
+function parseNumber(callback, options) {
+    var font = options.font;
+    var makeColumn = font.makeColumn;
+    return parseDigits(function (digits) {
+        if (digits) {
+            return parseConvert(callback, digits.join(""), makeColumn);
+        } else {
+            return callback();
+        }
+    });
+}
+
+var digits = "0123456789";
+var parseDigit = function (callback) {
+    return function (character) {
+        if (character !== "" && digits.indexOf(character) !== -1) {
+            return callback(character);
+        } else {
+            return callback()(character);
+        }
+    };
+};
+
+function parseConvert(callback, number, makeColumn) {
+    return Parser.countPrimes(function (primes) {
+        return callback(convert(number, primes, makeColumn));
+    });
+}
+
+function convert(string, primes, makeColumn) {
+    var error;
+    var radix;
+    if (primes == 0) {
+        radix = 10;
+    } else {
+        radix = 12;
+        error = primes > 1;
+    }
+    var number = parseInt(string, 10);
+    var string = number.toString(radix).split("");
+    return string.map(function (character) {
+        var column = makeColumn(""+parseInt(character, 12));
+        if (error) {
+            column.addError("Numbers can only be parsed in either decimal or dudecimal.");
+        }
+        return column;
+    });
+}
+
+
+var parseDigits = Parser.makeParseSome(parseDigit);
+var parseDot = Parser.makeExpect(".");
+
diff --git a/numerals.js b/numerals.js
deleted file mode 100644 (file)
index 6892c16..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-
-var array_ = Array.prototype;
-
-module.exports = function parseNumber(text, radix, options) {
-    var font = options.font;
-    var makeColumn = font.makeColumn;
-    return array_.map.call(parseInt(text, radix).toString(radix), function (character) {
-        return makeColumn("#" + character);
-    });
-};
-
index 5cfe7d1..f526989 100644 (file)
--- a/parser.js
+++ b/parser.js
@@ -56,30 +56,31 @@ function makeExpect(expected) {
 }
 
 exports.makeParseSome = makeParseSome;
-function makeParseSome(expected) {
+function makeParseSome(parseOne) {
     var parseSome = function (callback) {
-        return function (character) {
-            if (character === expected) {
-                return parseRemaining(callback);
+        return parseOne(function (one) {
+            if (one != null) {
+                return parseRemaining(callback, [one]);
             } else {
-                return callback()(character);
+                return callback([]);
             }
-        };
+        });
     };
-    var parseRemaining = makeParseAny(expected);
+    var parseRemaining = makeParseAny(parseOne);
     return parseSome;
 }
 
 exports.makeParseAny = makeParseAny;
-function makeParseAny(expected) {
-    return function parseRemaining(callback) {
-        return function (character) {
-            if (character === expected) {
-                return parseRemaining(callback);
+function makeParseAny(parseOne) {
+    return function parseRemaining(callback, any) {
+        any = any || [];
+        return parseOne(function (one) {
+            if (one != null) {
+                return parseRemaining(callback, any.concat([one]));
             } else {
-                return callback(expected)(character);
+                return callback(any);
             }
-        };
+        });
     };
 }