translation.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. class translation {
  2. /**
  3. * @var {string}
  4. * This is translated content.
  5. */
  6. #content;
  7. /**
  8. * @var {bool}
  9. * This is true, when content is translated from dict, and false
  10. * when could not being found.
  11. */
  12. #translated;
  13. /**
  14. * This create new translation. Translation store content of the
  15. * translation, make avairable to format translated phrase and also
  16. * store that translation was found in the phrasebook.
  17. *
  18. * @param {string} content - Content of the translation.
  19. * @param {bool} translated - True when translation could be found.
  20. */
  21. constructor(content, translated = true) {
  22. if (typeof(content) !== "string") {
  23. throw new TypeError("Translated content must be string.");
  24. }
  25. if (typeof(translated) !== "boolean") {
  26. throw new TypeError("Result of translation must be boolean.");
  27. }
  28. this.#content = content;
  29. this.#translated = translated;
  30. Object.freeze(this);
  31. }
  32. /**
  33. * This convert transiation to string.
  34. *
  35. * @returns {string} - Content of the translation.
  36. */
  37. toString() {
  38. return this.#content;
  39. }
  40. /**
  41. * @returns {string} - Content of the translation.
  42. */
  43. get text() {
  44. return this.#content;
  45. }
  46. /**
  47. * @returns {bool} - True when translation was found, false when not.
  48. */
  49. get valid() {
  50. return this.translated;
  51. }
  52. /**
  53. * This would format ready translation, with numbers, dats, and
  54. * other content, which could not being statically places into
  55. * translation. To use it, place name of content object key into
  56. * "#{}" in translation.
  57. *
  58. * @example ```
  59. * Translation: "I have more than #{how_many} apples!"
  60. * Object: { how_many: 10 }
  61. * Result: "I have more than 10 apples!"
  62. * ```
  63. *
  64. * @param {string} content
  65. * @returns {string}
  66. */
  67. format(content) {
  68. if (typeof(content) !== "object") {
  69. throw new TypeError("Content to format from must be object.");
  70. }
  71. if (!this.#translated) {
  72. return this.#content;
  73. }
  74. return this.#parse_format(content);
  75. }
  76. /**
  77. * This infill prepared translation with data from content
  78. * object.
  79. *
  80. * @see format
  81. *
  82. * @param {object} content - Content to load data from.
  83. * @returns {string} - Formater translation.
  84. */
  85. #parse_format(content) {
  86. let parts = this.#content.split("#{");
  87. let result = parts[0];
  88. for (let count = 1; count < parts.length; ++count) {
  89. const part = parts[count];
  90. const splited = part.split("}");
  91. if (splited.length === 1) {
  92. return result + splited[0];
  93. }
  94. const name = splited.splice(0, 1)[0].trim();
  95. const rest = splited.join("}");
  96. if (!(name in content)) {
  97. DEBUG: throw new RangeError(
  98. "Could not find \"" + name + "\"."
  99. );
  100. result += rest;
  101. continue;
  102. }
  103. result += content[name] + rest;
  104. }
  105. return result;
  106. }
  107. }
  108. exports.translation = translation;