locales-coverage-description.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. const fs = require("fs");
  2. const THRESSHOLD = 85;
  3. // we're using BCP 47 language tags as keys
  4. // e.g. https://gist.github.com/typpo/b2b828a35e683b9bf8db91b5404f1bd1
  5. const crowdinMap = {
  6. "ar-SA": "en-ar",
  7. "bg-BG": "en-bg",
  8. "bn-BD": "en-bn",
  9. "ca-ES": "en-ca",
  10. "da-DK": "en-da",
  11. "de-DE": "en-de",
  12. "el-GR": "en-el",
  13. "es-ES": "en-es",
  14. "eu-ES": "en-eu",
  15. "fa-IR": "en-fa",
  16. "fi-FI": "en-fi",
  17. "fr-FR": "en-fr",
  18. "gl-ES": "en-gl",
  19. "he-IL": "en-he",
  20. "hi-IN": "en-hi",
  21. "hu-HU": "en-hu",
  22. "id-ID": "en-id",
  23. "it-IT": "en-it",
  24. "ja-JP": "en-ja",
  25. "kab-KAB": "en-kab",
  26. "ko-KR": "en-ko",
  27. "ku-TR": "en-ku",
  28. "my-MM": "en-my",
  29. "nb-NO": "en-nb",
  30. "nl-NL": "en-nl",
  31. "nn-NO": "en-nnno",
  32. "oc-FR": "en-oc",
  33. "pa-IN": "en-pain",
  34. "pl-PL": "en-pl",
  35. "pt-BR": "en-ptbr",
  36. "pt-PT": "en-pt",
  37. "ro-RO": "en-ro",
  38. "ru-RU": "en-ru",
  39. "si-LK": "en-silk",
  40. "sk-SK": "en-sk",
  41. "sl-SI": "en-sl",
  42. "sv-SE": "en-sv",
  43. "ta-IN": "en-ta",
  44. "tr-TR": "en-tr",
  45. "uk-UA": "en-uk",
  46. "zh-CN": "en-zhcn",
  47. "zh-HK": "en-zhhk",
  48. "zh-TW": "en-zhtw",
  49. "lt-LT": "en-lt",
  50. "lv-LV": "en-lv",
  51. "cs-CZ": "en-cs",
  52. "kk-KZ": "en-kk",
  53. "vi-VN": "en-vi",
  54. "mr-IN": "en-mr",
  55. "th-TH": "en-th",
  56. };
  57. const flags = {
  58. "ar-SA": "🇸🇦",
  59. "bg-BG": "🇧🇬",
  60. "bn-BD": "🇧🇩",
  61. "ca-ES": "🏳",
  62. "cs-CZ": "🇨🇿",
  63. "da-DK": "🇩🇰",
  64. "de-DE": "🇩🇪",
  65. "el-GR": "🇬🇷",
  66. "es-ES": "🇪🇸",
  67. "fa-IR": "🇮🇷",
  68. "fi-FI": "🇫🇮",
  69. "fr-FR": "🇫🇷",
  70. "gl-ES": "🇪🇸",
  71. "he-IL": "🇮🇱",
  72. "hi-IN": "🇮🇳",
  73. "hu-HU": "🇭🇺",
  74. "id-ID": "🇮🇩",
  75. "it-IT": "🇮🇹",
  76. "ja-JP": "🇯🇵",
  77. "kab-KAB": "🏳",
  78. "kk-KZ": "🇰🇿",
  79. "ko-KR": "🇰🇷",
  80. "ku-TR": "🏳",
  81. "lt-LT": "🇱🇹",
  82. "lv-LV": "🇱🇻",
  83. "my-MM": "🇲🇲",
  84. "nb-NO": "🇳🇴",
  85. "nl-NL": "🇳🇱",
  86. "nn-NO": "🇳🇴",
  87. "oc-FR": "🏳",
  88. "pa-IN": "🇮🇳",
  89. "pl-PL": "🇵🇱",
  90. "pt-BR": "🇧🇷",
  91. "pt-PT": "🇵🇹",
  92. "ro-RO": "🇷🇴",
  93. "ru-RU": "🇷🇺",
  94. "si-LK": "🇱🇰",
  95. "sk-SK": "🇸🇰",
  96. "sl-SI": "🇸🇮",
  97. "sv-SE": "🇸🇪",
  98. "ta-IN": "🇮🇳",
  99. "tr-TR": "🇹🇷",
  100. "uk-UA": "🇺🇦",
  101. "zh-CN": "🇨🇳",
  102. "zh-HK": "🇭🇰",
  103. "zh-TW": "🇹🇼",
  104. "eu-ES": "🇪🇦",
  105. "vi-VN": "🇻🇳",
  106. "mr-IN": "🇮🇳",
  107. "th-TH": "🇹🇭",
  108. };
  109. const languages = {
  110. "ar-SA": "العربية",
  111. "bg-BG": "Български",
  112. "bn-BD": "Bengali",
  113. "ca-ES": "Català",
  114. "cs-CZ": "Česky",
  115. "da-DK": "Dansk",
  116. "de-DE": "Deutsch",
  117. "el-GR": "Ελληνικά",
  118. "es-ES": "Español",
  119. "eu-ES": "Euskara",
  120. "fa-IR": "فارسی",
  121. "fi-FI": "Suomi",
  122. "fr-FR": "Français",
  123. "gl-ES": "Galego",
  124. "he-IL": "עברית",
  125. "hi-IN": "हिन्दी",
  126. "hu-HU": "Magyar",
  127. "id-ID": "Bahasa Indonesia",
  128. "it-IT": "Italiano",
  129. "ja-JP": "日本語",
  130. "kab-KAB": "Taqbaylit",
  131. "kk-KZ": "Қазақ тілі",
  132. "ko-KR": "한국어",
  133. "ku-TR": "Kurdî",
  134. "lt-LT": "Lietuvių",
  135. "lv-LV": "Latviešu",
  136. "my-MM": "Burmese",
  137. "nb-NO": "Norsk bokmål",
  138. "nl-NL": "Nederlands",
  139. "nn-NO": "Norsk nynorsk",
  140. "oc-FR": "Occitan",
  141. "pa-IN": "ਪੰਜਾਬੀ",
  142. "pl-PL": "Polski",
  143. "pt-BR": "Português Brasileiro",
  144. "pt-PT": "Português",
  145. "ro-RO": "Română",
  146. "ru-RU": "Русский",
  147. "si-LK": "සිංහල",
  148. "sk-SK": "Slovenčina",
  149. "sl-SI": "Slovenščina",
  150. "sv-SE": "Svenska",
  151. "ta-IN": "Tamil",
  152. "tr-TR": "Türkçe",
  153. "uk-UA": "Українська",
  154. "zh-CN": "简体中文",
  155. "zh-HK": "繁體中文 (香港)",
  156. "zh-TW": "繁體中文",
  157. "vi-VN": "Tiếng Việt",
  158. "mr-IN": "मराठी",
  159. "th-TH": "ภาษาไทย",
  160. };
  161. const percentages = fs.readFileSync(
  162. `${__dirname}/../src/locales/percentages.json`,
  163. );
  164. const rowData = JSON.parse(percentages);
  165. const coverages = Object.entries(rowData)
  166. .sort(([, a], [, b]) => b - a)
  167. .reduce((r, [k, v]) => ({ ...r, [k]: v }), {});
  168. const boldIf = (text, condition) => (condition ? `**${text}**` : text);
  169. const printHeader = () => {
  170. let result = "| | Flag | Locale | % |\n";
  171. result += "| :--: | :--: | -- | :--: |";
  172. return result;
  173. };
  174. const printRow = (id, locale, coverage) => {
  175. const isOver = coverage >= THRESSHOLD;
  176. let result = `| ${isOver ? id : "..."} | `;
  177. result += `${locale in flags ? flags[locale] : ""} | `;
  178. const language = locale in languages ? languages[locale] : locale;
  179. if (locale in crowdinMap && crowdinMap[locale]) {
  180. result += `[${boldIf(
  181. language,
  182. isOver,
  183. )}](https://crowdin.com/translate/excalidraw/10/${crowdinMap[locale]}) | `;
  184. } else {
  185. result += `${boldIf(language, isOver)} | `;
  186. }
  187. result += `${coverage === 100 ? "💯" : boldIf(coverage, isOver)} |`;
  188. return result;
  189. };
  190. console.info(
  191. `Each language must be at least **${THRESSHOLD}%** translated in order to appear on Excalidraw. Join us on [Crowdin](https://crowdin.com/project/excalidraw) and help us translate your own language. **Can't find yours yet?** Open an [issue](https://github.com/excalidraw/excalidraw/issues/new) and we'll add it to the list.`,
  192. );
  193. console.info("\n\r");
  194. console.info(printHeader());
  195. let index = 1;
  196. for (const coverage in coverages) {
  197. if (coverage === "en") {
  198. continue;
  199. }
  200. console.info(printRow(index, coverage, coverages[coverage]));
  201. index++;
  202. }
  203. console.info("\n\r");
  204. console.info("\\* Languages in **bold** are going to appear on production.");