Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update from darkskyapp/translations #1

Merged
merged 19 commits into from
Jan 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 39 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,36 @@ Below is a listing of every possible machine-readable summary produced by
Dark Sky. The listing is recursive so as to better describe how the various
structural components interact.

### Status Information

Instead of producing a summary of weather information, we may sometimes generate
a status message indicating an error of some sort. Such messages may take one of
the following forms:

* `["sentence", [STATUS_MESSAGE, STATUS_TYPE, REASON]]`

`STATUS_MESSAGE` may be one of the following:

* `"next-hour-forecast-status"`: we have information to convey about our
hyperlocal next-hour forecasts

`STATUS_TYPE` may be one of the following:

* `"unavailable"`: no forecast is available for this request
* `"partially-unavailable"`: only a partial forecast is available for this request
* `"temporarily-unavailable"`: no forecast is available for this request, but we
expect it to be available again in the future

`REASON` may be one of the following:

* `"station-offline"`: we cannot generate a forecast because all nearby weather
stations are offline (e.g. for maintenance)
* `"station-incomplete"`: we cannot generate a forecast because of gaps in the
coverage of all nearby weather stations (e.g. radar beams are blocked by
local terrain)

`"next-hour-forecast-status"`, `"unavailable"`, `"partially-unavailable"`, `"temporarily-unavailable"`, `"station-offline"`, and `"station-incomplete"` are not used in any other forms.

### Moment Summaries

When the API is producing a text summary for a single moment in time (that is,
Expand Down Expand Up @@ -426,10 +456,15 @@ would be `["during", "rain", "next-wednesday"]`.
* `RAIN_TYPE`
* `SLEET_TYPE`
* `SNOW_TYPE`
* `["parenthetical", SNOW_TYPE, SNOW_ACCUMULATION]`: For daily or weekly
summaries, if a significant amount of snow is expected, we will qualify it
with the amount of expected snow accumulation on the ground. (For example,
"snow (3-4 in.) throughout the day".)
* `["parenthetical", EXPECTED_PRECIP_TYPE, SNOW_ACCUMULATION]`: For daily or
weekly summaries, if a significant amount of snow is expected, we will
qualify it with the amount of expected snow accumulation. (For example,
"snow (3-4 in.) throughout the day".) PLEASE NOTE that it is possible for a
chance of snow accumulation to be forecasted even if the expected
precipitation type is rain or sleet: this may occur if the forecasted
temperature is right around the freezing point. Translations should clarify
that the parenthetical refers to a chance of snow in such circumstances.
(For example, "sleet (chance of 3-4 in. of snow) throughout the day".)

In each of the below precipitation types, the intensity of precipitation is
(very approximately) as follows:
Expand Down
8 changes: 6 additions & 2 deletions lib/lang/bg.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ module.exports = {

return str;
},
"unavailable-radar": "Прогнозата за идния час временно не е на разположение поради $1.",
"station-offline": "липса на информация от всички близки станции",
"next-hour-forecast-status": "Прогнозата за идния час $1 поради $2.",
"unavailable": "не е налична",
"temporarily-unavailable": "временно не е на разположение",
"partially-unavailable": "е частична",
"station-offline": "това че всички близки станции не са на линия",
"station-incomplete": "пропуски в покритието от близки станции",
};
16 changes: 13 additions & 3 deletions lib/lang/cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ module.exports = {
"later-today-morning": "yn hwyrach bore yma",
"today-afternoon": "y prynhawn yma",
"later-today-afternoon": "yn hwyrach prynhawn yma",
"today-evening": "fin nos heno",
"today-evening": "gyda’r hwyr heno",
"later-today-evening": "yn hwyrach fin nos heno",
"today-night": "heno",
"later-today-night": "yn hwyrach heno",
Expand All @@ -58,7 +58,7 @@ module.exports = {
"tomorrow-night": "nos yfory",
"morning": "yn y bore",
"afternoon": "yn y prynhawn",
"evening": "fin nos",
"evening": "gyda’r hwyr",
"night": "dros nos",
"today": "heddiw",
"tomorrow": "yfory",
Expand Down Expand Up @@ -89,8 +89,12 @@ module.exports = {
return "llai na" + (/^(1|8|11|16)[\D\b]/.test(a) ? "g " : " ") + a;
},
"and": function(a, b) {
// don't repeat 'yn y'
if (a.slice(0,5) === "yn y " && b.slice(0,5) === "yn y ")
return a + " a’r " + b.slice(5);
// don't repeat 'ar'
if (a.slice(0,9) === "ar ddydd " && b.slice(0,9) === "ar ddydd ") b = b.slice(4);
if (a.slice(0,9) === "ar ddydd " && b.slice(0,9) === "ar ddydd ")
b = b.slice(4);
return a
// include comma if a list
+ (a.indexOf(",") !== -1 ? "," : "")
Expand Down Expand Up @@ -141,4 +145,10 @@ module.exports = {
str += ".";
return str;
},
"next-hour-forecast-status": "Dydi rhagolygon yr awr nesa $1 oherwydd $2.",
"unavailable": "ddim ar gael",
"temporarily-unavailable": "ddim ar gael ar hyn o bryd",
"partially-unavailable": "ddim yn gyflawn",
"station-offline": "diffyg gwybodaeth o orsafoedd radar gerllaw",
"station-incomplete": "bylchau yn narpariaeth gorsafoedd radar gerllaw",
};
88 changes: 60 additions & 28 deletions lib/lang/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,49 @@ function join_with_shared_prefix(a, b, joiner) {

// HACK: This gets around "today through on Tuesday" or cases like it, which
// are incorrect in English.
if(m === "today" || m === "tomorrow")
if(m === "today" || m === "tomorrow") {
m = "on " + m;
}

while(i !== m.length &&
i !== b.length &&
m.charCodeAt(i) === b.charCodeAt(i))
// Skip the prefix of b that is shared with a.
while(
i !== m.length &&
i !== b.length &&
m.charCodeAt(i) === b.charCodeAt(i)
) {
++i;
}

while(i && m.charCodeAt(i - 1) !== 32)
// ...except whitespace! We need that whitespace!
while(i && b.charCodeAt(i - 1) !== 32) {
--i;
}

return a + joiner + b.slice(i);
}

function strip_prefix(period) {
return period.slice(0, 9) === "overnight" ? period.slice(4) :
period.slice(0, 7) === "in the " ? period.slice(7) :
return period.startsWith("overnight")? period.slice(4):
period.startsWith("in the ")? period.slice(7):
period;
}

function capitalize(str) {
// Do not capitalize articles, very short words, or units.
if(
str === "a" ||
str === "and" ||
str === "cm" ||
str === "in" ||
str === "of" ||
str === "with"
) {
return str;
}

return str[0].toUpperCase() + str.slice(1);
}

module.exports = {
"clear": "clear",
"no-precipitation": "no precipitation",
Expand Down Expand Up @@ -104,19 +127,28 @@ module.exports = {
"centimeters": "$1 cm.",
"less-than": "< $1",
"and": function(a, b) {
return join_with_shared_prefix(
a,
b,
a.indexOf(",") !== -1 ? ", and " : " and "
);
return join_with_shared_prefix(a, b, a.includes(",")? ", and ": " and ");
},
"through": function(a, b) {
return join_with_shared_prefix(a, b, " through ");
},
"with": "$1, with $2",
"range": "$1\u2013$2",
"parenthetical": function(a, b) {
return a + " (" + b + (a === "mixed precipitation" ? " of snow)" : ")");
// In the case of mixed precipitation, we want to clarify that the
// snow accumulation in the parenthetical is snow. In the case that it's
// of an unknown type or rain or sleet, we want to clarify that while snow
// isn't expected, it has a chance of occurring. The below checks do this.

// HACK: These are not the best ways to determine the precipitation type...
if(!a.endsWith("flurries") && !a.endsWith("snow")) {
if(!a.startsWith("mixed")) {
b = "with a chance of " + b;
}
b += " of snow";
}

return a + " (" + b + ")";
},
"for-hour": "$1 for the hour",
"starting-in": "$1 starting in $2",
Expand All @@ -141,28 +173,28 @@ module.exports = {
"temperatures-rising": "high temperatures rising to $1 $2",
"temperatures-valleying": "high temperatures bottoming out at $1 $2",
"temperatures-falling": "high temperatures falling to $1 $2",
// 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.)
// Capitalize the first letter of every word except "and", "or", and units.
// (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)|c(?!m\.)|i(?!n\.)|[^\Waci])/g,
function(letter) {
return letter.toUpperCase();
}
);
return str.replace(/\w+/g, capitalize);
},
/* Capitalize the first word of the sentence and end with a period. */
// Capitalize the first word of the sentence and end with a period.
"sentence": function(str) {
/* Capitalize. */
str = str.charAt(0).toUpperCase() + str.slice(1);
// Capitalize.
str = capitalize(str);

/* Add a period if there isn't already one. */
if(str.charAt(str.length - 1) !== ".")
// Add a period if there isn't already one.
if(!str.endsWith(".")) {
str += ".";
}

return str;
},
"unavailable-radar": "Next hour forecasts are temporarily unavailable due to $1.",
"next-hour-forecast-status": "next hour forecasts are $1 due to $2",
"unavailable": "unavailable",
"temporarily-unavailable": "temporarily unavailable",
"partially-unavailable": "partially unavailable",
"station-offline": "all nearby radar stations being offline",
"station-incomplete": "gaps in coverage from nearby radar stations",
};
6 changes: 6 additions & 0 deletions lib/lang/fr.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,4 +177,10 @@ module.exports = {

return str;
},
"next-hour-forecast-status": "Les prévisions pour la prochaine heure sont $1 car $2.",
"unavailable": "indisponibles",
"temporarily-unavailable": "temporairement indisponibles",
"partially-unavailable": "partiellement indisponibles",
"station-offline": "les stations radars voisines sont hors-ligne",
"station-incomplete": "il y a des lacunes dans la couverture des stations radars voisines",
};
Loading