diff --git a/index.html b/index.html
index 7a270d3d..d30008dd 100644
--- a/index.html
+++ b/index.html
@@ -63,171 +63,171 @@
Dark Sky Multilingual Text Summaries
(title
- (condition clear)) |
+ clear)
Clear |
(title
- (condition very-light-precipitation)) |
+ very-light-precipitation)
Light Precipitation |
(title
- (condition light-precipitation)) |
+ light-precipitation)
Light Precipitation |
(title
- (condition medium-precipitation)) |
+ medium-precipitation)
Precipitation |
(title
- (condition heavy-precipitation)) |
+ heavy-precipitation)
Heavy Precipitation |
(title
- (condition very-light-rain)) |
+ very-light-rain)
Drizzle |
(title
- (condition light-rain)) |
+ light-rain)
Light Rain |
(title
- (condition medium-rain)) |
+ medium-rain)
Rain |
(title
- (condition heavy-rain)) |
+ heavy-rain)
Heavy Rain |
(title
- (condition very-light-sleet)) |
+ very-light-sleet)
Light Sleet |
(title
- (condition light-sleet)) |
+ light-sleet)
Light Sleet |
(title
- (condition medium-sleet)) |
+ medium-sleet)
Sleet |
(title
- (condition heavy-sleet)) |
+ heavy-sleet)
Heavy Sleet |
(title
- (condition very-light-snow)) |
+ very-light-snow)
Flurries |
(title
- (condition light-snow)) |
+ light-snow)
Light Snow |
(title
- (condition medium-snow)) |
+ medium-snow)
Snow |
(title
- (condition heavy-snow)) |
+ heavy-snow)
Heavy Snow |
(title
- (condition light-wind)) |
+ light-wind)
Breezy |
(title
- (condition medium-wind)) |
+ medium-wind)
Windy |
(title
- (condition heavy-wind)) |
+ heavy-wind)
Dangerously Windy |
(title
- (condition very-heavy-wind)) |
+ very-heavy-wind)
Violently Windy |
(title
- (condition low-humidity)) |
+ low-humidity)
Dry |
(title
- (condition high-humidity)) |
+ high-humidity)
Humid |
(title
- (condition fog)) |
+ fog)
Foggy |
(title
- (condition light-clouds)) |
+ light-clouds)
Partly Cloudy |
(title
- (condition medium-clouds)) |
+ medium-clouds)
Mostly Cloudy |
(title
- (condition heavy-clouds)) |
+ heavy-clouds)
Overcast |
(title
(and
- (condition high-humidity)
- (condition light-clouds))) |
+ high-humidity
+ light-clouds))
Humid and Partly Cloudy |
@@ -241,45 +241,51 @@ Dark Sky Multilingual Text Summaries
(sentence
(for-hour
- (condition clear))) |
+ clear))
Clear for the hour. |
(sentence
(starting
- (condition very-light-snow)
- (quantity minute 35))) |
+ very-light-snow
+ (minutes
+ 35)))
Flurries starting in 35 min. |
(sentence
(stopping
- (condition light-rain)
- (quantity minute 15))) |
+ light-rain
+ (minutes
+ 15)))
Light rain stopping in 15 min. |
(sentence
- (clause
+ (clauses
(starting
- (condition heavy-sleet)
- (quantity minute 20))
+ heavy-sleet
+ (minutes
+ 20))
(stopping-later
- (quantity minute 30)))) |
+ (minutes
+ 30))))
Heavy sleet starting in 20 min., stopping 30 min. later. |
(sentence
- (clause
+ (clauses
(stopping
- (condition medium-rain)
- (quantity minute 25))
+ medium-rain
+ (minutes
+ 25))
(starting-later
- (quantity minute 8)))) |
+ (minutes
+ 8))))
Rain stopping in 25 min., starting again 8 min. later. |
@@ -297,62 +303,74 @@ Dark Sky Multilingual Text Summaries
(sentence
- (clause
+ (clauses
(for-week
- (condition no-precipitation))
- (temperatures-peaking
- (quantity fahrenheit 85)
- (day tomorrow)))) |
+ no-precipitation)
+ (on
+ (temperatures-peaking
+ (fahrenheit
+ 85))
+ tomorrow)))
No precipitation throughout the week, temperatures peaking at 85°F tomorrow. |
(sentence
- (clause
+ (clauses
(over-weekend
- (condition mixed-precipitation))
- (temperatures-rising
- (quantity celsius 32)
- (day thursday)))) |
+ mixed-precipitation)
+ (on
+ (temperatures-rising
+ (celsius
+ 32))
+ thursday)))
Mixed precipitation over the weekend, temperatures rising to 32°C on Thursday. |
(sentence
- (clause
+ (clauses
+ (on
+ medium-rain
+ today)
(on
- (condition medium-rain)
- (day today))
- (temperatures-valleying
- (quantity fahrenheit 15)
- (day friday)))) |
+ (temperatures-valleying
+ (fahrenheit
+ 15))
+ friday)))
Rain today, temperatures bottoming out at 15°F on Friday. |
(sentence
- (clause
+ (clauses
(on
- (condition very-light-snow)
+ very-light-snow
(and
- (day monday)
- (day tuesday)))
- (temperatures-falling
- (quantity celsius 0)
- (day sunday)))) |
+ monday
+ tuesday))
+ (on
+ (temperatures-falling
+ (celsius
+ 0))
+ sunday)))
Flurries on Monday and Tuesday, temperatures falling to 0°C on Sunday. |
(sentence
- (clause
+ (clauses
(on
- (condition medium-precipitation)
+ medium-precipitation
(range
- (day wednesday)
- (day saturday)))
- (...))) |
- Precipitation on Wednesday through Saturday, ... |
+ wednesday
+ saturday))
+ (on
+ (temperatures-peaking
+ (fahrenheit
+ 100))
+ monday)))
+ Precipitation on Wednesday through Saturday, temperatures peaking at 100°F on Monday. |
diff --git a/src/darksky.js b/src/darksky.js
index 691efd88..27660c93 100644
--- a/src/darksky.js
+++ b/src/darksky.js
@@ -3,36 +3,27 @@ var DarkSky;
(function() {
"use strict";
- var LANGUAGES = {};
-
DarkSky = {
- hasLanguage: function(code) {
- return LANGUAGES.hasOwnProperty(code);
- },
- language: function(code, predicates) {
- if(DarkSky.hasLanguage(code))
- throw new Error("DarkSky already has the language code \"" + code + "\" defined.");
-
- LANGUAGES[code] = predicates;
- },
- translate: function(code, expr) {
- if(!LANGUAGES.hasOwnProperty(code))
- throw new Error("DarkSky doesn't know about the language code \"" + code + "\".");
-
- if(!Array.isArray(expr) || !expr.length)
- throw new Error("Invalid expression.");
-
- function recurse(expr) {
- if(typeof expr === "string")
- return expr;
-
- if(!Array.isArray(expr) || !expr.length)
- throw new Error("Invalid expression.");
-
- return LANGUAGES[code][expr[0]].apply(null, expr.slice(1).map(recurse));
+ translate: function parse(template, expr) {
+ if(typeof expr === "number")
+ return expr.toString();
+
+ if(typeof expr === "string")
+ return template.hasOwnProperty(expr) ? template[expr] : expr;
+
+ if(Array.isArray(expr) && template.hasOwnProperty(expr[0])) {
+ if(typeof template[expr[0]] === "string")
+ return template[expr[0]].replace(/\$\d+/g, function(n) {
+ return parse(template, expr[n.slice(1)|0]);
+ });
+
+ if(typeof template[expr[0]] === "function")
+ return template[expr[0]].apply(null, expr.slice(1).map(function(arg) {
+ return parse(template, arg);
+ }));
}
- return recurse(expr);
+ throw new Error("Invalid expression.");
}
};
})();
diff --git a/src/lang/en.js b/src/lang/en.js
index 7e9aa4df..c78a436c 100644
--- a/src/lang/en.js
+++ b/src/lang/en.js
@@ -1,146 +1,88 @@
-DarkSky.language("en", {
- "condition": function(word) {
- switch(word) {
- case "clear": return "clear";
+var DarkSkyEnglish = {
+ "clear": "clear",
+ "no-precipitation": "no precipitation",
+ "mixed-precipitation": "mixed precipitation",
+ "very-light-precipitation": "light precipitation",
+ "light-precipitation": "light precipitation",
+ "medium-precipitation": "precipitation",
+ "heavy-precipitation": "heavy precipitation",
+ "very-light-rain": "drizzle",
+ "light-rain": "light rain",
+ "medium-rain": "rain",
+ "heavy-rain": "heavy rain",
+ "very-light-sleet": "light sleet",
+ "light-sleet": "light sleet",
+ "medium-sleet": "sleet",
+ "heavy-sleet": "heavy sleet",
+ "very-light-snow": "flurries",
+ "light-snow": "light snow",
+ "medium-snow": "snow",
+ "heavy-snow": "heavy snow",
+ "light-wind": "breezy",
+ "medium-wind": "windy",
+ "heavy-wind": "dangerously windy",
+ "very-heavy-wind": "violently windy",
+ "low-humidity": "dry",
+ "high-humidity": "humid",
+ "fog": "foggy",
+ "light-clouds": "partly cloudy",
+ "medium-clouds": "mostly cloudy",
+ "heavy-clouds": "overcast",
+ "today": "today",
+ "tomorrow": "tomorrow",
+ "sunday": "Sunday",
+ "monday": "Monday",
+ "tuesday": "Tuesday",
+ "wednesday": "Wednesday",
+ "thursday": "Thursday",
+ "friday": "Friday",
+ "saturday": "Saturday",
+ "minutes": "$1 min.",
+ "fahrenheit": "$1°F",
+ "celsius": "$1°C",
+ "and": "$1 and $2",
+ "clauses": function(one, two) {
+ return one +
+ (one.indexOf(",") === -1 && two.indexOf(",") === -1 ? ", " : "; ") +
+ two;
+ },
+ "range": "$1 through $2",
+ "for-hour": "$1 for the hour",
+ "starting": "$1 starting in $2",
+ "stopping": "$1 stopping in $2",
+ "starting-later": "starting again $1 later",
+ "stopping-later": "stopping $1 later",
+ "for-week": "$1 throughout the week",
+ "over-weekend": "$1 over the weekend",
+ "temperatures-peaking": "temperatures peaking at $1",
+ "temperatures-rising": "temperatures rising to $1",
+ "temperatures-valleying": "temperatures bottoming out at $1",
+ "temperatures-falling": "temperatures falling to $1",
+ "on": function(condition, day) {
+ return condition +
+ (day === "today" || day === "tomorrow" ? " " : " on ") +
+ day;
+ },
+ /* Capitalize the first letter of every word, except if that word is
+ * "and". (This is a very crude bastardization of proper English titling
+ * rules, but it is adequate for the purposes of this module.) */
+ "title": function(str) {
+ return str.replace(
+ /\b(?:a(?!nd\b)|[^\Wa])/g,
+ function(letter) {
+ return letter.toUpperCase();
+ }
+ );
+ },
+ /* Capitalize the first word of the sentence and end with a period. */
+ "sentence": function(str) {
+ /* Capitalize. */
+ str = str.charAt(0).toUpperCase() + str.slice(1);
- case "no-precipitation": return "no precipitation";
- case "mixed-precipitation": return "mixed precipitation";
- case "very-light-precipitation": return "light precipitation";
- case "light-precipitation": return "light precipitation";
- case "medium-precipitation": return "precipitation";
- case "heavy-precipitation": return "heavy precipitation";
+ /* Add a period if there isn't already one. */
+ if(str.charAt(str.length - 1) !== ".")
+ str += ".";
- case "very-light-rain": return "drizzle";
- case "light-rain": return "light rain";
- case "medium-rain": return "rain";
- case "heavy-rain": return "heavy rain";
-
- case "very-light-sleet": return "light sleet";
- case "light-sleet": return "light sleet";
- case "medium-sleet": return "sleet";
- case "heavy-sleet": return "heavy sleet";
-
- case "very-light-snow": return "flurries";
- case "light-snow": return "light snow";
- case "medium-snow": return "snow";
- case "heavy-snow": return "heavy snow";
-
- case "light-wind": return "breezy";
- case "medium-wind": return "windy";
- case "heavy-wind": return "dangerously windy";
- case "very-heavy-wind": return "violently windy";
-
- case "low-humidity": return "dry";
- case "high-humidity": return "humid";
-
- case "fog": return "foggy";
-
- case "light-clouds": return "partly cloudy";
- case "medium-clouds": return "mostly cloudy";
- case "heavy-clouds": return "overcast";
- }
- },
- "day": function(word) {
- switch(word) {
- case "today": return "today";
- case "tomorrow": return "tomorrow";
-
- case "sunday": return "Sunday";
- case "monday": return "Monday";
- case "tuesday": return "Tuesday";
- case "wednesday": return "Wednesday";
- case "thursday": return "Thursday";
- case "friday": return "Friday";
- case "saturday": return "Saturday";
- }
- },
- "quantity": function(unit, count) {
- switch(unit) {
- case "minute": return count + " min.";
-
- case "inch": return count + " in.";
- case "centimeter": return count + " cm.";
-
- case "fahrenheit": return count + "°F";
- case "celsius": return count + "°C";
- }
- },
- "qualify": function(phrase, qualifier) {
- return phrase + " (" + qualifier + ")";
- },
- "and": function() {
- switch(arguments.length) {
- case 1: return arguments[0];
- case 2: return arguments[0] + " and " + arguments[1];
- default: return Array.prototype.slice.call(arguments, 0, -1).join(", ") +
- ", and " + arguments[arguments.length - 1];
- }
- },
- "clause": function() {
- var separator = ", ",
- i;
-
- for(i = arguments.length; i--; )
- if(arguments[i].indexOf(",") !== -1) {
- separator = "; ";
- break;
+ return str;
}
-
- return Array.prototype.join.call(arguments, separator);
- },
- "range": function(start, end) {
- return start + " through " + end;
- },
- "for-hour": function(condition, duration) {
- return condition + " for the hour";
- },
- "for-week": function(condition, duration) {
- return condition + " throughout the week";
- },
- "starting": function(condition, duration) {
- return condition + " starting in " + duration;
- },
- "stopping": function(condition, duration) {
- return condition + " stopping in " + duration;
- },
- "starting-later": function(duration) {
- return "starting again " + duration + " later";
- },
- "stopping-later": function(duration) {
- return "stopping " + duration + " later";
- },
- "temperatures-peaking": function(max, day) {
- "temperatures peaking at " + max + " on " + day;
- },
- "temperatures-rising": function(max, day) {
- "temperatures rising to " + max + " on " + day;
- },
- "temperatures-valleying": function(min, day) {
- "temperatures bottoming out at " + min + " on " + day;
- },
- "temperatures-falling": function(min, day) {
- "temperatures falling to " + min + " on " + day;
- },
- /* Capitalize the first letter of every word, except if that word is "and".
- * (This is a very crude bastardization of proper English titling rules, but
- * it is adequate for the purposes of this module.) */
- "title": function(str) {
- return str.replace(
- /\b(?:a(?!nd\b)|[^\Wa])/g,
- function(letter) {
- return letter.toUpperCase();
- }
- );
- },
- /* Capitalize the first word of the sentence and end with a period. */
- "sentence": function(str) {
- /* Capitalize. */
- str = str.charAt(0).toUpperCase() + str.slice(1);
-
- /* Add a period if there isn't already one. */
- if(str.charAt(str.length - 1) !== ".")
- str += ".";
-
- return str;
- }
-});
+ };
diff --git a/src/sexp.js b/src/sexp.js
index c6dd4408..163e26d4 100644
--- a/src/sexp.js
+++ b/src/sexp.js
@@ -20,9 +20,12 @@ var SExp;
stack[stack.length - 1].push(top);
}
- else
+ else if(isNaN(str[i]))
stack[stack.length - 1].push(str[i]);
+ else
+ stack[stack.length - 1].push(+str[i]);
+
return stack[0][0];
}
};
diff --git a/src/test.js b/src/test.js
index b81770fa..fe172e48 100644
--- a/src/test.js
+++ b/src/test.js
@@ -1,4 +1,5 @@
-var rows = document.getElementById("tests").getElementsByTagName("tr"),
+var mapping = {"en": DarkSkyEnglish},
+ rows = document.getElementById("tests").getElementsByTagName("tr"),
i, cells, input, j, output;
for(i = 0; i !== rows.length; ++i) {
@@ -15,12 +16,12 @@ for(i = 0; i !== rows.length; ++i) {
input = undefined;
}
- else if(!input || !DarkSky.hasLanguage(cells[j].className))
+ else if(!input || !mapping.hasOwnProperty(cells[j].className))
cells[j].className += " skip";
else
try {
- output = DarkSky.translate(cells[j].className, input);
+ output = DarkSky.translate(mapping[cells[j].className], input);
if(output === cells[j].textContent)
cells[j].className += " pass";