patternjavascriptMinor
Generating readable text in a human language from machine-readable data
Viewed 0 times
humanreadabletextlanguagegeneratingmachinefromdata
Problem
I have been generating English-language text from some machine-readable data, but now I want internationalization of my script to be relatively easy. The challenge is that some data might be missing and thus should be omitted from the output, possibly precluding any approach involving just "plugging in" numbers.
Currently, I have functions like these, the output concatenated together in the main program:
It is supposed to generate output like:
A reviewer and rollbacker, 2 years 9 months old, with 8,624 edits. Last edited 7 hours ago.
The age, edit count, date of last edit, or all of them could be missing. How could I improve my current design without resorting to a tabular display format? (All the information needs to nicely fit into a single status line.)
Currently, I have functions like these, the output concatenated together in the main program:
function UserinfoJsFormatQty(qty, singular, plural) {
return String(qty).replace(/\d{1,3}(?=(\d{3})+(?!\d))/g, "%%CODEBLOCK_0%%amp;,") + "\u00a0" + (qty == 1 ? singular : plural);
}
function UserinfoJsFormatDateRel(old) {
// The code below requires the computer's clock to be set correctly.
var age = new Date().getTime() - old.getTime();
var ageNumber, ageRemainder, ageWords;
if(age < 60000) {
// less than one minute old
ageNumber = Math.floor(age / 1000);
ageWords = UserinfoJsFormatQty(ageNumber, "second", "seconds");
} else if(age < 3600000) {
// less than one hour old
ageNumber = Math.floor(age / 60000);
ageWords = UserinfoJsFormatQty(ageNumber, "minute", "minutes");
} else if(age < 86400000) {
// less than one day old
ageNumber = Math.floor(age / 3600000);
ageWords = UserinfoJsFormatQty(ageNumber, "hour", "hours");
ageRemainder = Math.floor((age - ageNumber * 3600000) / 60000);
} else if(age < 604800000) {
// less than one week old
ageNumber = Math.floor(age / 86400000);
ageWords = UserinfoJsFormatQty(ageNumber, "day", "days");
} // ...
return ageWords;
}It is supposed to generate output like:
A reviewer and rollbacker, 2 years 9 months old, with 8,624 edits. Last edited 7 hours ago.
The age, edit count, date of last edit, or all of them could be missing. How could I improve my current design without resorting to a tabular display format? (All the information needs to nicely fit into a single status line.)
Solution
I see a couple of potential issues with regards to internationalization:
-
pluralization is more complex than
-
numbers should be formatted according to language, using appropriate separators
-
concatenation (that you mention is done in main program) must be avoided because the order of words and phrases will often vary in translations in different languages
I would advise to :
-
localize translations using named parameters to be replaced: this solves the ordering issue, and avoids concatenation.
-
format values, for number formatting and pluralization, using a separate function localized for each language
-
replace parameters with formatted values in parameterized translations using a template engine: this should keep some potentially buggy regular expressions out of your code :)
You may be interested in having a look at:
and last but not least, the i18n API part of the Scalable JavaScript Application framework, which I designed for Legal-Box :)
I may be able to provide more practical suggestions if you show more of your code, especially at the "top", part of the main program.
-
pluralization is more complex than
(qty == 1 ? singular : plural). What about the value 0? Also in some languages, different plural forms are in use depending on the number.-
numbers should be formatted according to language, using appropriate separators
-
concatenation (that you mention is done in main program) must be avoided because the order of words and phrases will often vary in translations in different languages
I would advise to :
-
localize translations using named parameters to be replaced: this solves the ordering issue, and avoids concatenation.
-
format values, for number formatting and pluralization, using a separate function localized for each language
-
replace parameters with formatted values in parameterized translations using a template engine: this should keep some potentially buggy regular expressions out of your code :)
You may be interested in having a look at:
- JavaScript Internationalisation, a post by Matthew Somerville on 24 Ways
- jQuery-global, "a jQuery plugin for the globalization of string, date, and number formatting and parsing"
and last but not least, the i18n API part of the Scalable JavaScript Application framework, which I designed for Legal-Box :)
- eric-brechemier/lb_js_scalableApp, the project home page on GitHub
- lb.core.Sandbox.js, check the i18n part of the API, methods starting with "i18n."
I may be able to provide more practical suggestions if you show more of your code, especially at the "top", part of the main program.
Context
StackExchange Code Review Q#917, answer score: 5
Revisions (0)
No revisions yet.