kde-l10n/sr@latin/scripts/kdelibs/kdelibs4/kdelibs4.js

613 lines
20 KiB
JavaScript

// kdelibs4.js of Serbian KDE translation
// ------------------------------
// Property getter object contains the following data attributes:
// - callname: the name of the getter call as exposed to PO files
// - propkey: the key of the property as used in pmap files
// - overrides: dictionary of values of this property for certain phrases,
// which were manually set in the PO file
function Propgetter (callname, propkey)
{
this.callname = callname;
this.propkey = propkey;
this.overrides = {};
this.getbase = Propgetter_getbase;
this.getprop = Propgetter_getprop;
this.getprop_uc = Propgetter_getprop_uc;
this.getform = Propgetter_getform;
this.getform_uc = Propgetter_getform_uc;
}
// Base of property/form getter methods attached to getter objects.
// First the property for the given phrase is looked up in overrides,
// and then in Transcript property map (read from pmap files).
// If the property is not found, fallback is signalled if retself is false,
// otherwise the phrase itself is returned.
function Propgetter_getbase (phrase, retself)
{
if (phrase in this.overrides) {
return this.overrides[phrase];
}
else {
var prop = Ts.getProp(phrase, this.propkey)
if (prop != undefined)
return prop;
}
if (retself) {
return phrase;
}
throw Ts.fallback();
}
// Property getter method attached to getter objects.
function Propgetter_getprop (phrase)
{
return this.getbase(phrase, false);
}
// As previous, but returns the property with the first letter upcased.
function Propgetter_getprop_uc (phrase)
{
var val = this.getprop(phrase);
// The second argument is indicating the number of alternatives per
// alternatives directive -- in case the first letter is within
// an alternatives directive, all alternatives in that directive
// should be processed.
return Ts.toUpperFirst(val, 2);
}
// Form getter method attached to getter objects.
function Propgetter_getform (phrase)
{
return this.getbase(phrase, true);
}
// As previous, but returns the form with the first letter upcased.
function Propgetter_getform_uc (phrase)
{
var val = this.getform(phrase);
// See the comment in Propgetter_getprop_uc().
return Ts.toUpperFirst(val, 2);
}
// ------------------------------
// Exposing property getters to PO.
// Contains all global property getters.
var _propgetters_ = {};
// Set PO calls for given property getter object.
function setcalls_prop (pgetr)
{
// Default call.
Ts.setcall(pgetr.callname, pgetr.getprop, pgetr);
// "Open with $[callname %1]"
// Form call.
Ts.setcall(pgetr.callname + "/f", pgetr.getform, pgetr);
// "Open with $[callname/f %1]"
// The calls which capitalize the first letter of the value,
// named as the default calls but with the first letter capitalized.
// Only set if the first letter of the call name is actually lowercase.
callname_uc = Ts.toUpperFirst(pgetr.callname);
if (callname_uc != pgetr.callname) {
Ts.setcall(callname_uc, pgetr.getprop_uc, pgetr);
// "$[Callname %1] starting..."
Ts.setcall(callname_uc + "/f", pgetr.getform_uc, pgetr);
// "$[Callname/f %1] starting..."
}
// Record getter objects globally.
// Only for the original name, since the uppercase/form variants are not
// used when properties are being set (when the global store is needed).
_propgetters_[pgetr.callname] = pgetr;
}
// Set property value of phrase.
function setprop (phrase, pkey, pval)
{
// Either create new, or select existing getter.
var pgetr;
if (!_propgetters_[pkey]) {
// Populate new getter if not already defined.
pgetr = new Propgetter(pkey, pkey);
// Expose calls to PO.
setcalls_prop(pgetr);
}
else {
// Get previously defined getter.
pgetr = _propgetters_[pkey];
}
// Add the property into overrides of selected getter.
pgetr.overrides[phrase] = pval;
}
// Get property value of phrase.
// Signals fallback if the property/phrase combination is not defined.
function getprop (phrase, pkey)
{
if (_propgetters_[pkey]) {
return _propgetters_[pkey].getprop(phrase);
}
throw Ts.fallback();
}
// Get form of the phrase, or phrase itself if no such form.
function getform (phrase, fkey)
{
if (_propgetters_[fkey]) {
return _propgetters_[fkey].getform(phrase);
}
return phrase;
}
// Returns true if the phrase has the property.
function hasprop (phrase, pkey)
{
pg = _propgetters_[pkey];
if (!pg) {
return false;
}
if (!pg.overrides[phrase] && !Ts.getProp(phrase, pg.propkey)) {
return false;
}
return true;
}
// ------------------------------
// Predefined property getters.
// Call names and corresponding keys in pmap for predefined getters.
// The first letter in a call name should be lowercase; for each call
// another call with the first letter in uppercase will be defined,
// which will upcase the first letter in the property value before
// returning it.
var call_name_to_prop = {
// Nouns.
"_izv" : "_izvor", // english original
"_rod" : "_rod", // gender
"_broj" : "_broj", // number
"nom" : "n", // nominative case
"gen" : "g", // genitive case
"dat" : "d", // dative case
"aku" : "a", // accusative case
"ins" : "i", // instrumental case
"lok" : "l", // locative case
// Expressive variants.
"naredbeno" : "_narb", // command
"spiskovno" : "_spis", // listed
// Adjectives.
"nom-m" : "nm", // nominative, masculine
"gen-m" : "gm", // genitive, masculine
"dat-m" : "dm", // dative, masculine
"aku-m" : "am", // accusative, masculine
"ins-m" : "im", // instrumental, masculine
"lok-m" : "lm", // locative, masculine
"nom-ž" : "nz", // nominative, feminine
"gen-ž" : "gz", // genitive, feminine
"dat-ž" : "dz", // dative, feminine
"aku-ž" : "az", // accusative, feminine
"ins-ž" : "iz", // instrumental, feminine
"lok-ž" : "lz", // locative, feminine
"nom-s" : "ns", // nominative, neuter
"gen-s" : "gs", // genitive, neuter
"dat-s" : "ds", // dative, neuter
"aku-s" : "as", // accusative, neuter
"ins-s" : "is", // instrumental, neuter
"lok-s" : "ls", // locative, neuter
"nom-mk" : "nmk", // nominative, masculine, plural
"gen-mk" : "gmk", // genitive, masculine, plural
"dat-mk" : "dmk", // dative, masculine, plural
"aku-mk" : "amk", // accusative, masculine, plural
"ins-mk" : "imk", // instrumental, masculine, plural
"lok-mk" : "lmk", // locative, masculine, plural
"nom-žk" : "nzk", // nominative, feminine, plural
"gen-žk" : "gzk", // genitive, feminine, plural
"dat-žk" : "dzk", // dative, feminine, plural
"aku-žk" : "azk", // accusative, feminine, plural
"ins-žk" : "izk", // instrumental, feminine, plural
"lok-žk" : "lzk", // locative, feminine, plural
"nom-sk" : "nsk", // nominative, neuter, plural
"gen-sk" : "gsk", // genitive, neuter, plural
"dat-sk" : "dsk", // dative, neuter, plural
"aku-sk" : "ask", // accusative, neuter, plural
"ins-sk" : "isk", // instrumental, neuter, plural
"lok-sk" : "lsk", // locative, neuter, plural
};
// Create getter objects for predefined getters.
for (cname in call_name_to_prop) {
// Create getter object as defined above.
var pgetr = new Propgetter(cname, call_name_to_prop[cname]);
// Expose calls to PO.
setcalls_prop(pgetr);
}
// Special handling for instrumental case, when used for tool application:
// don't pass it along as-is if same as nominative case of the phrase,
// since the sentence can get very different, yet semantically correct meaning.
// Instead, pass genitive case with the preposition "by the help of".
{
var pgetr = new Propgetter("ins-p", "i");
// Replace default getter method.
pgetr.getprop = function (phrase)
{
var prop_ins = _propgetters_["ins"].getprop(phrase);
var prop_nom = _propgetters_["nom"].getprop(phrase);
if (prop_ins == prop_nom) {
var prop_gen = _propgetters_["gen"].getprop(phrase);
return "pomoću " + prop_gen;
}
else {
return prop_ins;
}
}
setcalls_prop(pgetr);
}
// ------------------------------
// Set properties of the given phrase.
// The arguments to the call are the phrase, and a list of as many keys
// followed by their value as desired (i.e. number of elements must be even).
// Keys may also be comma-separated lists instead of a single key, in order
// not to have to repeat the same value when it corresponds to several keys.
//
// The property keys become property getters which can be used to retrive
// the value at a later point. If the getter for a given key already exists,
// the new value is added into its overrides.
//
// Returns undefined.
//
function setprops (phrase, keyvals)
{
if (keyvals.length % 2 != 0)
throw Error("Property setter given odd number of key/value elements.");
for (var i = 0; i < keyvals.length; i += 2) {
// Several keys may be given for a single prop, comma-separated.
var pkeys = keyvals[i].split(",");
var pval = keyvals[i + 1];
// Set the value to each property key.
for (var j = 0; j < pkeys.length; j += 1) {
setprop(phrase, pkeys[j], pval);
}
}
}
// Manually set properties of the phrase given by the finalized msgstr
// in the PO file and signal fallback.
// For the rest of the behavior, see setprops()
function setprops_msgstrf (/*...*/)
{
if (arguments.length % 2 != 0)
throw Error("Msgstr property setter given odd number of arguments.");
setprops(Ts.msgstrf(), arguments);
throw Ts.fallback();
}
Ts.setcall("svojstva", setprops_msgstrf);
// "$[callname prop1 value1 prop2 value2 ...]"
// Manually set properties of the phrase given by the finalized msgstr
// in the PO file and return empty string.
// For the rest of the behavior, see setprops()
function setprops_msgstrf_e (/*...*/)
{
if (arguments.length % 2 != 0)
throw Error("Msgstr property setter given odd number of arguments.");
setprops(Ts.msgstrf(), arguments);
return "";
}
Ts.setcall("svojstva/p", setprops_msgstrf_e);
// "$[callname prop1 value1 prop2 value2 ...]"
// ------------------------------
// Manual plural handling.
// Only first three forms, as the fourth form is most likely not needed
// when the plural needs to be scripted.
// The first argument should be the proper value, not the substitution string
// (i.e. do not call as $[~ %1 ...] but as $[~ ^1 ...]).
function plural3 (n, form0, form1, form2)
{
if (n % 10 == 1 && n % 100 != 11)
return form0;
else if (n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20))
return form1;
else
return form2;
}
Ts.setcall("množ", plural3);
// "...and %2 $[callname ^2 file fila files]"
// ------------------------------
// General choice-by-case.
function select_by_case (/* test, case1, choice1, ..., [default_choice] */)
{
if (arguments.length < 1)
throw Error("Choice by case takes at least the test value.");
for (var i = 1; i < arguments.length - 1; i += 2) {
if (arguments[0] == arguments[i]) {
return arguments[i + 1];
}
}
// No case matched, see if we have a default.
if ((arguments.length - 1) % 2 != 0) {
return arguments[arguments.length - 1];
} else {
throw Ts.fallback();
}
}
Ts.setcall("kada", select_by_case);
// "Do you want to %1 $[callname %1 open 'this bar' access 'thisu baru']"
// ------------------------------
// Select one of three forms according to the gender of the phrase.
function select_by_gender (phrase, form_m, form_f, form_n)
{
// Select gender (throws fallback if phrase not found).
var gender = getprop(phrase, "_rod");
if (gender == "m") {
return form_m;
}
else if (gender == "ž") {
return form_f;
}
else if (gender == "s") {
return form_n;
}
else {
throw Ts.fallback();
}
}
Ts.setcall("po-rodu", select_by_gender);
// "Delete $[callname %1 this thisa thiso] %1?"
// ------------------------------
// Select one of two forms according to the number of the phrase.
function select_by_number (phrase, form_s, form_p)
{
// Select number (default to singular if not found).
var number = "j";
if (hasprop(phrase, "_broj")) {
number = getprop(phrase, "_broj");
}
if (number == "k") { // plural
return form_p;
} else {
return form_s;
}
}
Ts.setcall("po-broju", select_by_number);
// "%1 $[callname %1 waalks waalk] by the river."
// ------------------------------
// Select one of six forms according to the gender and number of the phrase.
function select_by_number_gender (phrase,
form_ms, form_fs, form_ns, // singulars
form_mp, form_fp, form_np) // plurals
{
// Select number (default to singular if not found).
var number = "j";
if (hasprop(phrase, "_broj")) {
number = getprop(phrase, "_broj");
}
if (number == "k") { // plural
return select_by_gender(phrase, form_mp, form_fp, form_np);
} else {
return select_by_gender(phrase, form_ms, form_fs, form_ns);
}
}
Ts.setcall("po-rodu-broju", select_by_number_gender);
// "Delete $[callname %1 this thisa thiso thees theesa theeso] %1?"
// ------------------------------
// Select one the form according to the case and gender of another argument.
function select_by_case_gender (gcase, gphrase, phrase) // plurals
{
var gender = getprop(gphrase, "_rod");
return getprop(phrase, gcase + "-" + gender);
}
Ts.setcall("po-padežu-rodu", select_by_case_gender);
// "Delete $[callname case %2 %1] [case %2]?"
// ------------------------------
// Object to query whether a character is one of expected letters.
letter_arr = (""
+ "abvgdđežzijklljmnnjoprstćufhcčdžšABVGDĐEŽZIJKLLJMNNJOPRSTĆUFHCČDŽŠ"
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
).split("");
letter = {};
for (var i = 0; i < letter_arr.length; ++i) {
letter[letter_arr[i]] = 1;
}
// ------------------------------
// Split phrase into words and intersections,
// where words are taken as contiguous segments of letters.
// The return value is a tuple of arrays of words and intersections.
// There is always one more of intersections than words, so that
// the original phrase can be reassembled as
// intrs[0] + words[0] + ... + intrs[n - 2] + words[n - 2] + intrs[n - 1].
function split_phrase (phrase)
{
intrs = [];
words = [];
var i = 0;
while (i < phrase.length) {
var i1 = i;
while (i1 < phrase.length && !letter[phrase[i1]]) {
++i1;
}
intrs.push(phrase.substring(i, i1));
var i2 = i1;
while (i2 < phrase.length && letter[phrase[i2]]) {
++i2;
}
if (i2 > i1) {
words.push(phrase.substring(i1, i2));
if (i2 == phrase.length) {
intrs.push("");
}
}
i = i2;
}
return [words, intrs];
}
// ------------------------------
// Apply call to each word in the phrase.
// The call must accept the word as the last argument.
function apply_to_word (/* phrase, callname, ...args before word... */)
{
if (arguments.length < 2)
throw Error("Applicator takes at least the phrase and the call name.");
phrase = arguments[0];
calln = arguments[1];
cargs = [calln];
for (var i = 2; i < arguments.length; ++i) {
cargs.push(arguments[i]);
}
lst = split_phrase(phrase);
words = lst[0];
intrs = lst[1];
nwords = [];
for (var i = 0; i < words.length; ++i) {
cargs.push(words[i]);
nwords.push(Ts.acall.apply(Ts, cargs));
cargs.pop();
}
str = ""
for (var i = 0; i < nwords.length; ++i) {
str += intrs[i] + nwords[i];
}
str += intrs[nwords.length];
return str;
}
Ts.setcall("na-reč", apply_to_word);
// "Repeat until $[callname casecall %1], and on this date..."
// ------------------------------
// Decline person's name into given case.
// Parse name into first and last name, determine gender according to
// first name, decline according to gender and assemble.
// If name cannot be fully declined, returns original name if retself is true,
// otherwise signals fallback.
// TODO: Just delegates to ordinary getters for the time being.
function decline_person_name_base (gcase, fullname, retself)
{
if (retself) {
return getform(fullname, gcase);
}
else {
return getprop(fullname, gcase);
}
}
// Decline person's name, signal fallback if not possible.
function decline_person_name (gcase, fullname)
{
return decline_person_name_base(gcase, fullname, false);
}
Ts.setcall("imenski", decline_person_name);
// "You have invited $[callname case %1] to the party."
// Decline person's name, return as-is if not possible.
function decline_person_name_nf (gcase, fullname)
{
return decline_person_name_base(gcase, fullname, true);
}
Ts.setcall("imenski/f", decline_person_name_nf);
// "You have invited $[callname case %1] to the party."
// ------------------------------
// Match style attributes to gender of the font family name,
// for the requested grammatical case.
// The message must have dynamic context 'family' equal to the family name,
// so that its gender can be obtained.
// Style string may be composed of several space-separated attributes.
// Family name and style attributes are expected in the nominative case.
// Returns composed style string in the proper gender/case.
function match_style_to_font (compstyle, gcase)
{
var family = Ts.dynctxt("family");
if (!family) {
throw Ts.fallback();
}
var gender = getprop(family, "_rod");
var number = ""
if (hasprop(family, "_broj")) {
number = getprop(family, "_broj");
}
var styles = compstyle.split(" ");
var final = "";
for (var i = 0; i < styles.length; i += 1) {
final += " " + getprop(styles[i], gcase + "-" + gender + number);
}
return final.substr(1); // to remove initial space
}
Ts.setcall("stil-prema-fontu", match_style_to_font);
// ------------------------------
// Pick a phrase depending on a dynamic context field.
// Input is the keyword of the context field, followed by pairs of
// regex matcher on context value and corresponding phrase,
// and optionally followed by default phrase in case the value does not match.
// If the value does not match and default phrase is not given,
// fallback is signaled.
// If requested dynamic context field does not exist, fallback is signaled.
function select_by_context (/* ctxt_key,
valrx_1, phrase_1, ..., valrx_N, phrase_N
[, default_phrase]*/)
{
if (arguments.length < 1)
throw Error("Selector by context takes at least the context keyword.");
var ctxtkey = arguments[0];
var ctxtval = Ts.dynctxt(ctxtkey);
var phrase;
for (var i = 1; i < arguments.length; i += 2) {
if (ctxtval.match(RegExp(arguments[i]))) {
phrase = arguments[i + 1];
break;
}
}
if (phrase == undefined) {
if (arguments.length % 2 == 0) {
phrase = arguments[arguments.length - 1];
} else {
throw Ts.fallback();
}
}
return phrase;
}
Ts.setcall("po-kontekstu", select_by_context);
// ------------------------------
// Load property maps.
Ts.loadProps("trapnakron");
// // Do not load fonts pmap if the user requested so.
// if (!Ts.getConfBool("translate-fonts", true)) {
// }