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";