@katerynakhar/i18n-keeper 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +666 -0
  3. package/dist/apply.d.ts +66 -0
  4. package/dist/apply.js +254 -0
  5. package/dist/apply.js.map +1 -0
  6. package/dist/check.d.ts +5 -0
  7. package/dist/check.js +326 -0
  8. package/dist/check.js.map +1 -0
  9. package/dist/cli.d.ts +2 -0
  10. package/dist/cli.js +525 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/formats/error.d.ts +12 -0
  13. package/dist/formats/error.js +19 -0
  14. package/dist/formats/error.js.map +1 -0
  15. package/dist/formats/flatten.d.ts +6 -0
  16. package/dist/formats/flatten.js +26 -0
  17. package/dist/formats/flatten.js.map +1 -0
  18. package/dist/formats/json-write.d.ts +7 -0
  19. package/dist/formats/json-write.js +55 -0
  20. package/dist/formats/json-write.js.map +1 -0
  21. package/dist/formats/json.d.ts +6 -0
  22. package/dist/formats/json.js +21 -0
  23. package/dist/formats/json.js.map +1 -0
  24. package/dist/formats/php-write.d.ts +16 -0
  25. package/dist/formats/php-write.js +130 -0
  26. package/dist/formats/php-write.js.map +1 -0
  27. package/dist/formats/php.d.ts +44 -0
  28. package/dist/formats/php.js +356 -0
  29. package/dist/formats/php.js.map +1 -0
  30. package/dist/formats/po-write.d.ts +3 -0
  31. package/dist/formats/po-write.js +200 -0
  32. package/dist/formats/po-write.js.map +1 -0
  33. package/dist/formats/po.d.ts +30 -0
  34. package/dist/formats/po.js +202 -0
  35. package/dist/formats/po.js.map +1 -0
  36. package/dist/formats/write.d.ts +29 -0
  37. package/dist/formats/write.js +19 -0
  38. package/dist/formats/write.js.map +1 -0
  39. package/dist/formats/yaml-write.d.ts +12 -0
  40. package/dist/formats/yaml-write.js +42 -0
  41. package/dist/formats/yaml-write.js.map +1 -0
  42. package/dist/formats/yaml.d.ts +18 -0
  43. package/dist/formats/yaml.js +51 -0
  44. package/dist/formats/yaml.js.map +1 -0
  45. package/dist/glossary.d.ts +38 -0
  46. package/dist/glossary.js +140 -0
  47. package/dist/glossary.js.map +1 -0
  48. package/dist/lengths.d.ts +37 -0
  49. package/dist/lengths.js +195 -0
  50. package/dist/lengths.js.map +1 -0
  51. package/dist/mcp.d.ts +2 -0
  52. package/dist/mcp.js +374 -0
  53. package/dist/mcp.js.map +1 -0
  54. package/dist/memory.d.ts +72 -0
  55. package/dist/memory.js +162 -0
  56. package/dist/memory.js.map +1 -0
  57. package/dist/placeholders.d.ts +15 -0
  58. package/dist/placeholders.js +103 -0
  59. package/dist/placeholders.js.map +1 -0
  60. package/dist/plurals.d.ts +59 -0
  61. package/dist/plurals.js +280 -0
  62. package/dist/plurals.js.map +1 -0
  63. package/dist/report.d.ts +2 -0
  64. package/dist/report.js +126 -0
  65. package/dist/report.js.map +1 -0
  66. package/dist/scan.d.ts +23 -0
  67. package/dist/scan.js +250 -0
  68. package/dist/scan.js.map +1 -0
  69. package/dist/translate.d.ts +93 -0
  70. package/dist/translate.js +369 -0
  71. package/dist/translate.js.map +1 -0
  72. package/dist/types.d.ts +88 -0
  73. package/dist/types.js +50 -0
  74. package/dist/types.js.map +1 -0
  75. package/dist/version.d.ts +1 -0
  76. package/dist/version.js +28 -0
  77. package/dist/version.js.map +1 -0
  78. package/package.json +77 -0
  79. package/src/apply.ts +334 -0
  80. package/src/check.ts +468 -0
  81. package/src/cli.ts +637 -0
  82. package/src/formats/error.ts +19 -0
  83. package/src/formats/flatten.ts +38 -0
  84. package/src/formats/json-write.ts +66 -0
  85. package/src/formats/json.ts +27 -0
  86. package/src/formats/php-write.ts +146 -0
  87. package/src/formats/php.ts +414 -0
  88. package/src/formats/po-write.ts +230 -0
  89. package/src/formats/po.ts +233 -0
  90. package/src/formats/write.ts +41 -0
  91. package/src/formats/yaml-write.ts +53 -0
  92. package/src/formats/yaml.ts +62 -0
  93. package/src/glossary.ts +191 -0
  94. package/src/lengths.ts +214 -0
  95. package/src/mcp.ts +451 -0
  96. package/src/memory.ts +227 -0
  97. package/src/placeholders.ts +123 -0
  98. package/src/plurals.ts +320 -0
  99. package/src/report.ts +162 -0
  100. package/src/scan.ts +280 -0
  101. package/src/translate.ts +486 -0
  102. package/src/types.ts +136 -0
  103. package/src/version.ts +27 -0
@@ -0,0 +1,356 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { FormatError } from './error.js';
3
+ import { flattenValue } from './flatten.js';
4
+ /**
5
+ * Parses the `<?php return [...];` subset that Laravel language files use.
6
+ *
7
+ * Deliberately a parser and not an evaluator: locale files come from the
8
+ * repository being linted, so running them would mean executing untrusted code,
9
+ * and it would force PHP onto every machine running the linter. Anything
10
+ * outside the literal subset is a clear error rather than a guess.
11
+ */
12
+ export class PhpParseError extends FormatError {
13
+ constructor(file, line, message) {
14
+ super(file, message, line);
15
+ }
16
+ }
17
+ const IDENT_START = /[A-Za-z_\x80-￿]/;
18
+ class Parser {
19
+ text;
20
+ file;
21
+ pos = 0;
22
+ layout = { values: new Map(), arrays: new Map() };
23
+ constructor(text, file) {
24
+ this.text = text;
25
+ this.file = file;
26
+ }
27
+ /** The indentation of the line `at` sits on. */
28
+ indentAt(at) {
29
+ const lineStart = this.text.lastIndexOf('\n', at - 1) + 1;
30
+ const match = /^[ \t]*/.exec(this.text.slice(lineStart, at));
31
+ return match ? match[0] : '';
32
+ }
33
+ lineAt(pos) {
34
+ let line = 1;
35
+ for (let i = 0; i < pos && i < this.text.length; i++) {
36
+ if (this.text[i] === '\n')
37
+ line++;
38
+ }
39
+ return line;
40
+ }
41
+ error(message, pos = this.pos) {
42
+ throw new PhpParseError(this.file, this.lineAt(pos), message);
43
+ }
44
+ atEnd() {
45
+ return this.pos >= this.text.length;
46
+ }
47
+ /** Whitespace and all three PHP comment styles. */
48
+ skipTrivia() {
49
+ for (;;) {
50
+ while (!this.atEnd() && /\s/.test(this.text[this.pos]))
51
+ this.pos++;
52
+ if (this.text.startsWith('//', this.pos) || this.text.startsWith('#', this.pos)) {
53
+ const nl = this.text.indexOf('\n', this.pos);
54
+ this.pos = nl === -1 ? this.text.length : nl + 1;
55
+ continue;
56
+ }
57
+ if (this.text.startsWith('/*', this.pos)) {
58
+ const end = this.text.indexOf('*/', this.pos + 2);
59
+ if (end === -1)
60
+ this.error('Unterminated block comment');
61
+ this.pos = end + 2;
62
+ continue;
63
+ }
64
+ return;
65
+ }
66
+ }
67
+ eat(token) {
68
+ this.skipTrivia();
69
+ if (this.text.startsWith(token, this.pos)) {
70
+ this.pos += token.length;
71
+ return true;
72
+ }
73
+ return false;
74
+ }
75
+ eatKeyword(word) {
76
+ this.skipTrivia();
77
+ const slice = this.text.slice(this.pos, this.pos + word.length);
78
+ if (slice.toLowerCase() !== word)
79
+ return false;
80
+ const next = this.text[this.pos + word.length];
81
+ if (next !== undefined && /[\w]/.test(next))
82
+ return false;
83
+ this.pos += word.length;
84
+ return true;
85
+ }
86
+ expect(token, what = token) {
87
+ if (!this.eat(token))
88
+ this.error(`Expected ${what}`);
89
+ }
90
+ parseFile() {
91
+ const open = this.text.indexOf('<?php');
92
+ if (open === -1)
93
+ this.error('Missing <?php opening tag', 0);
94
+ this.pos = open + '<?php'.length;
95
+ // `declare(strict_types=1);` and similar preamble statements.
96
+ while (this.eatKeyword('declare')) {
97
+ const close = this.text.indexOf(')', this.pos);
98
+ if (close === -1)
99
+ this.error('Unterminated declare()');
100
+ this.pos = close + 1;
101
+ this.eat(';');
102
+ }
103
+ if (!this.eatKeyword('return')) {
104
+ this.error('Expected `return` — a language file must return an array');
105
+ }
106
+ const value = this.parseValue('');
107
+ this.expect(';');
108
+ this.skipTrivia();
109
+ if (this.eat('?>'))
110
+ this.skipTrivia();
111
+ if (!this.atEnd())
112
+ this.error('Unexpected content after the returned array');
113
+ return value;
114
+ }
115
+ parseValue(path) {
116
+ this.skipTrivia();
117
+ if (this.atEnd())
118
+ this.error('Unexpected end of file');
119
+ const ch = this.text[this.pos];
120
+ if (ch === '[') {
121
+ this.pos++;
122
+ return this.parseArrayBody(']', path);
123
+ }
124
+ if (this.eatKeyword('array')) {
125
+ this.expect('(', '( after array');
126
+ return this.parseArrayBody(')', path);
127
+ }
128
+ if (ch === "'")
129
+ return this.parseSingleQuoted();
130
+ if (ch === '"')
131
+ return this.parseDoubleQuoted();
132
+ if (this.eatKeyword('true'))
133
+ return true;
134
+ if (this.eatKeyword('false'))
135
+ return false;
136
+ if (this.eatKeyword('null'))
137
+ return null;
138
+ if (/[-+\d.]/.test(ch))
139
+ return this.parseNumber();
140
+ if (ch === '$')
141
+ this.error('Variables are not supported in language files');
142
+ if (this.text.startsWith('<<<', this.pos)) {
143
+ this.error('Heredoc/nowdoc strings are not supported');
144
+ }
145
+ if (IDENT_START.test(ch))
146
+ this.error('Constants and function calls are not supported');
147
+ this.error(`Unexpected character ${JSON.stringify(ch)}`);
148
+ }
149
+ parseArrayBody(closing, path) {
150
+ const entries = [];
151
+ let nextIndex = 0;
152
+ let sawStringKey = false;
153
+ const afterOpen = this.pos;
154
+ let indent = '';
155
+ let lastValueEnd = afterOpen;
156
+ let hasTrailingComma = false;
157
+ for (;;) {
158
+ this.skipTrivia();
159
+ if (this.eat(closing))
160
+ break;
161
+ if (this.atEnd())
162
+ this.error(`Unterminated array, expected ${closing}`);
163
+ const start = this.pos;
164
+ if (indent === '')
165
+ indent = this.indentAt(start);
166
+ const first = this.parseValue(path);
167
+ if (this.eat('=>')) {
168
+ let key;
169
+ if (typeof first === 'string') {
170
+ sawStringKey = true;
171
+ key = first;
172
+ }
173
+ else if (typeof first === 'number' && Number.isInteger(first)) {
174
+ nextIndex = Math.max(nextIndex, first + 1);
175
+ key = first;
176
+ }
177
+ else {
178
+ this.error('Array keys must be strings or integers', start);
179
+ }
180
+ entries.push([key, this.recordValue(path, String(key))]);
181
+ }
182
+ else {
183
+ const key = nextIndex++;
184
+ // A list entry's value was already consumed as `first`; its span runs
185
+ // from where the entry started to where parsing left off.
186
+ this.layout.values.set(join(path, String(key)), { start, end: this.pos });
187
+ entries.push([key, first]);
188
+ }
189
+ lastValueEnd = this.pos;
190
+ this.skipTrivia();
191
+ if (this.eat(',')) {
192
+ hasTrailingComma = true;
193
+ // Past the comma, so an inserted entry lands after it rather than
194
+ // between the value and its separator.
195
+ lastValueEnd = this.pos;
196
+ continue;
197
+ }
198
+ hasTrailingComma = false;
199
+ this.expect(closing, `, or ${closing}`);
200
+ break;
201
+ }
202
+ this.layout.arrays.set(path, {
203
+ style: closing === ')' ? 'array' : 'bracket',
204
+ insertAt: entries.length === 0 ? afterOpen : lastValueEnd,
205
+ indent: indent || ' ',
206
+ hasTrailingComma,
207
+ empty: entries.length === 0,
208
+ });
209
+ // PHP arrays are ordered maps; a purely sequential one is a JS array.
210
+ const sequential = !sawStringKey && entries.every(([key], i) => typeof key === 'number' && key === i);
211
+ if (sequential)
212
+ return entries.map(([, value]) => value);
213
+ const object = {};
214
+ for (const [key, value] of entries)
215
+ object[String(key)] = value;
216
+ return object;
217
+ }
218
+ recordValue(path, key) {
219
+ this.skipTrivia();
220
+ const start = this.pos;
221
+ const value = this.parseValue(join(path, key));
222
+ this.layout.values.set(join(path, key), { start, end: this.pos });
223
+ return value;
224
+ }
225
+ parseNumber() {
226
+ this.skipTrivia();
227
+ const match = /^[-+]?(?:\d[\d_]*\.?[\d_]*|\.\d[\d_]*)(?:[eE][-+]?\d+)?/.exec(this.text.slice(this.pos));
228
+ if (!match || match[0] === '')
229
+ this.error('Malformed number');
230
+ this.pos += match[0].length;
231
+ return Number(match[0].replace(/_/g, ''));
232
+ }
233
+ /** Single quotes escape only \' and \\; everything else is literal. */
234
+ parseSingleQuoted() {
235
+ const start = this.pos;
236
+ this.pos++;
237
+ let out = '';
238
+ while (!this.atEnd()) {
239
+ const ch = this.text[this.pos];
240
+ if (ch === '\\') {
241
+ const next = this.text[this.pos + 1];
242
+ if (next === "'" || next === '\\') {
243
+ out += next;
244
+ this.pos += 2;
245
+ continue;
246
+ }
247
+ out += ch;
248
+ this.pos++;
249
+ continue;
250
+ }
251
+ if (ch === "'") {
252
+ this.pos++;
253
+ return out;
254
+ }
255
+ out += ch;
256
+ this.pos++;
257
+ }
258
+ this.error('Unterminated string', start);
259
+ }
260
+ parseDoubleQuoted() {
261
+ const start = this.pos;
262
+ this.pos++;
263
+ let out = '';
264
+ while (!this.atEnd()) {
265
+ const ch = this.text[this.pos];
266
+ if (ch === '"') {
267
+ this.pos++;
268
+ return out;
269
+ }
270
+ if (ch === '$') {
271
+ const next = this.text[this.pos + 1];
272
+ if (next !== undefined && (IDENT_START.test(next) || next === '{')) {
273
+ this.error('Variable interpolation is not supported in language files');
274
+ }
275
+ out += ch;
276
+ this.pos++;
277
+ continue;
278
+ }
279
+ if (ch === '{' && this.text[this.pos + 1] === '$') {
280
+ this.error('Variable interpolation is not supported in language files');
281
+ }
282
+ if (ch === '\\') {
283
+ out += this.readEscape();
284
+ continue;
285
+ }
286
+ out += ch;
287
+ this.pos++;
288
+ }
289
+ this.error('Unterminated string', start);
290
+ }
291
+ readEscape() {
292
+ const next = this.text[this.pos + 1];
293
+ if (next === undefined)
294
+ this.error('Unterminated escape sequence');
295
+ const simple = {
296
+ n: '\n',
297
+ r: '\r',
298
+ t: '\t',
299
+ v: '\v',
300
+ f: '\f',
301
+ e: '\x1b',
302
+ '\\': '\\',
303
+ $: '$',
304
+ '"': '"',
305
+ };
306
+ if (next in simple) {
307
+ this.pos += 2;
308
+ return simple[next];
309
+ }
310
+ if (next === 'x') {
311
+ const match = /^[0-9A-Fa-f]{1,2}/.exec(this.text.slice(this.pos + 2));
312
+ if (match) {
313
+ this.pos += 2 + match[0].length;
314
+ return String.fromCharCode(Number.parseInt(match[0], 16));
315
+ }
316
+ }
317
+ if (next === 'u' && this.text[this.pos + 2] === '{') {
318
+ const close = this.text.indexOf('}', this.pos + 3);
319
+ const hex = close === -1 ? '' : this.text.slice(this.pos + 3, close);
320
+ if (close !== -1 && /^[0-9A-Fa-f]+$/.test(hex)) {
321
+ this.pos = close + 1;
322
+ return String.fromCodePoint(Number.parseInt(hex, 16));
323
+ }
324
+ this.error('Malformed \\u{...} escape');
325
+ }
326
+ const octal = /^[0-7]{1,3}/.exec(this.text.slice(this.pos + 1));
327
+ if (octal) {
328
+ this.pos += 1 + octal[0].length;
329
+ return String.fromCharCode(Number.parseInt(octal[0], 8) & 0xff);
330
+ }
331
+ // PHP keeps an unrecognised escape as a literal backslash plus the character.
332
+ this.pos += 1;
333
+ return '\\';
334
+ }
335
+ }
336
+ function join(path, key) {
337
+ return path ? `${path}.${key}` : key;
338
+ }
339
+ export function parsePhp(text, file) {
340
+ return new Parser(text, file).parseFile();
341
+ }
342
+ /** Parses and also reports where every value and array sits in the text. */
343
+ export function parsePhpLayout(text, file) {
344
+ const parser = new Parser(text, file);
345
+ const value = parser.parseFile();
346
+ return { value, layout: parser.layout };
347
+ }
348
+ export function readPhpLocale(file, namespace, _locale, _isSource, target) {
349
+ const parsed = parsePhp(readFileSync(file, 'utf8'), file);
350
+ if (Array.isArray(parsed)) {
351
+ target.skipped.push({ file, reason: 'the file holds a list, not keyed translations' });
352
+ return;
353
+ }
354
+ flattenValue(parsed, namespace, file, target.leaves, target.containers);
355
+ }
356
+ //# sourceMappingURL=php.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"php.js","sourceRoot":"","sources":["../../src/formats/php.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Edit, WriteOutcome } from './write.js';
2
+ export declare function poString(value: string): string;
3
+ export declare function writePoLocale(content: string, file: string, _locale: string, edits: Edit[]): WriteOutcome;
@@ -0,0 +1,200 @@
1
+ import { poKey, parsePo } from './po.js';
2
+ /**
3
+ * gettext catalogues, edited line by line.
4
+ *
5
+ * One deliberate choice beyond preserving the file: a translation written here
6
+ * is marked `#, fuzzy`. That flag is gettext's own word for "not reviewed by a
7
+ * person yet", which is exactly what this tool records as `reviewed: false` in
8
+ * the memory. Leaving it off would claim a human had approved the string.
9
+ * It does mean `check` then reports those entries as stale — correctly.
10
+ */
11
+ const ESCAPES = new Map([
12
+ [0x0a, '\\n'],
13
+ [0x0d, '\\r'],
14
+ [0x09, '\\t'],
15
+ ]);
16
+ export function poString(value) {
17
+ let out = '';
18
+ for (const ch of value) {
19
+ const cp = ch.codePointAt(0);
20
+ if (ch === '\\' || ch === '"')
21
+ out += `\\${ch}`;
22
+ else if (cp < 0x20)
23
+ out += ESCAPES.get(cp) ?? `\\x${cp.toString(16).padStart(2, '0')}`;
24
+ else
25
+ out += ch;
26
+ }
27
+ return `"${out}"`;
28
+ }
29
+ const KEYWORD = /^(msgctxt|msgid_plural|msgid|msgstr)(?:\[(\d+)\])?(.*)$/;
30
+ const EMPTY_STRING = /^\s*""\s*$/;
31
+ /**
32
+ * Lines up each entry in the text with the key the parser resolved for it.
33
+ *
34
+ * The parser drops the header entry, so the scanner has to drop it too or every
35
+ * key lands one entry early — which is exactly the bug this shape prevents.
36
+ */
37
+ function scan(content, file) {
38
+ const lines = content.split(/\r?\n/);
39
+ const keysInOrder = parsePo(content, file).entries.map(poKey);
40
+ const blocks = new Map();
41
+ let current = null;
42
+ let msgidEmpty = true;
43
+ let inMsgid = false;
44
+ let lastMsgstr = null;
45
+ let obsolete = false;
46
+ let entryIndex = 0;
47
+ const close = () => {
48
+ if (current && current.msgstr.size > 0 && !obsolete) {
49
+ current.headerLike = msgidEmpty;
50
+ if (!msgidEmpty) {
51
+ const key = keysInOrder[entryIndex];
52
+ if (key !== undefined)
53
+ blocks.set(key, current);
54
+ entryIndex++;
55
+ }
56
+ }
57
+ current = null;
58
+ msgidEmpty = true;
59
+ inMsgid = false;
60
+ lastMsgstr = null;
61
+ obsolete = false;
62
+ };
63
+ for (const [index, raw] of lines.entries()) {
64
+ const line = raw.trim();
65
+ if (line === '') {
66
+ close();
67
+ continue;
68
+ }
69
+ if (line.startsWith('#~')) {
70
+ obsolete = true;
71
+ continue;
72
+ }
73
+ if (line.startsWith('#')) {
74
+ if (line.startsWith('#,')) {
75
+ current ??= { flagLine: null, headLine: index, msgstr: new Map(), headerLike: false };
76
+ current.flagLine = index;
77
+ }
78
+ continue;
79
+ }
80
+ const match = KEYWORD.exec(line);
81
+ if (match) {
82
+ if (!current)
83
+ current = { flagLine: null, headLine: index, msgstr: new Map(), headerLike: false };
84
+ else if (current.msgstr.size === 0 && current.flagLine === null) {
85
+ current.headLine = Math.min(current.headLine, index);
86
+ }
87
+ if (match[1] === 'msgstr') {
88
+ const at = match[2] === undefined ? 0 : Number.parseInt(match[2], 10);
89
+ current.msgstr.set(at, { start: index, end: index + 1 });
90
+ lastMsgstr = at;
91
+ inMsgid = false;
92
+ }
93
+ else {
94
+ if (match[1] === 'msgid') {
95
+ inMsgid = true;
96
+ msgidEmpty = EMPTY_STRING.test(match[3] ?? '');
97
+ }
98
+ else {
99
+ inMsgid = false;
100
+ }
101
+ lastMsgstr = null;
102
+ }
103
+ continue;
104
+ }
105
+ if (line.startsWith('"') && current) {
106
+ if (lastMsgstr !== null) {
107
+ current.msgstr.get(lastMsgstr).end = index + 1;
108
+ }
109
+ else if (inMsgid && !EMPTY_STRING.test(line)) {
110
+ // A msgid spelled across continuation lines is not the empty header.
111
+ msgidEmpty = false;
112
+ }
113
+ }
114
+ }
115
+ close();
116
+ return { lines, blocks };
117
+ }
118
+ function splitForm(key) {
119
+ const match = /^(.*)\.(\d+)$/.exec(key);
120
+ return match
121
+ ? { base: match[1], form: Number.parseInt(match[2], 10) }
122
+ : { base: key, form: null };
123
+ }
124
+ /**
125
+ * A new entry has to be spelled back out as msgctxt + msgid. The key format
126
+ * joins them with `|`, which a msgid could itself contain; splitting at the
127
+ * first one matches how the key was built and is wrong only for a contextless
128
+ * msgid that happens to contain a pipe.
129
+ */
130
+ function appendEntry(key, value) {
131
+ const pipe = key.indexOf('|');
132
+ const head = pipe > 0
133
+ ? [`msgctxt ${poString(key.slice(0, pipe))}`, `msgid ${poString(key.slice(pipe + 1))}`]
134
+ : [`msgid ${poString(key)}`];
135
+ return ['', '#, fuzzy', ...head, `msgstr ${poString(value)}`];
136
+ }
137
+ export function writePoLocale(content, file, _locale, edits) {
138
+ const { lines, blocks } = scan(content, file);
139
+ const skipped = [];
140
+ // line index -> replacement lines, or null to drop the line.
141
+ const replaced = new Map();
142
+ const needFuzzy = new Set();
143
+ const appended = [];
144
+ for (const edit of edits) {
145
+ let block = blocks.get(edit.key);
146
+ let form = 0;
147
+ if (!block) {
148
+ const split = splitForm(edit.key);
149
+ if (split.form !== null) {
150
+ const candidate = blocks.get(split.base);
151
+ if (candidate) {
152
+ block = candidate;
153
+ form = split.form;
154
+ }
155
+ }
156
+ }
157
+ if (!block) {
158
+ appended.push(...appendEntry(edit.key, edit.value));
159
+ continue;
160
+ }
161
+ const span = block.msgstr.get(form);
162
+ if (!span) {
163
+ skipped.push({ key: edit.key, reason: `the entry has no msgstr[${form}]` });
164
+ continue;
165
+ }
166
+ const label = block.msgstr.size > 1 ? `msgstr[${form}]` : 'msgstr';
167
+ replaced.set(span.start, [`${label} ${poString(edit.value)}`]);
168
+ for (let line = span.start + 1; line < span.end; line++)
169
+ replaced.set(line, null);
170
+ needFuzzy.add(block);
171
+ }
172
+ for (const block of needFuzzy) {
173
+ if (block.flagLine !== null) {
174
+ const flags = lines[block.flagLine];
175
+ if (!/\bfuzzy\b/.test(flags))
176
+ replaced.set(block.flagLine, [`${flags}, fuzzy`]);
177
+ continue;
178
+ }
179
+ const head = replaced.get(block.headLine) ?? [lines[block.headLine]];
180
+ replaced.set(block.headLine, ['#, fuzzy', ...head]);
181
+ }
182
+ const out = [];
183
+ for (const [index, line] of lines.entries()) {
184
+ const replacement = replaced.get(index);
185
+ if (replacement === undefined)
186
+ out.push(line);
187
+ else if (replacement !== null)
188
+ out.push(...replacement);
189
+ }
190
+ if (appended.length > 0) {
191
+ while (out.length > 0 && out[out.length - 1] === '')
192
+ out.pop();
193
+ out.push(...appended, '');
194
+ }
195
+ // A catalogue checked out on Windows may use CRLF; writing back with bare
196
+ // newlines would leave the file mixed.
197
+ const newline = content.includes('\r\n') ? '\r\n' : '\n';
198
+ return { content: out.join(newline), skipped };
199
+ }
200
+ //# sourceMappingURL=po-write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"po-write.js","sourceRoot":"","sources":["../../src/formats/po-write.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { ReadTarget } from '../types.js';
2
+ import { FormatError } from './error.js';
3
+ /**
4
+ * gettext .po / .pot.
5
+ *
6
+ * Two things make this format different from the others: the msgid *is* the
7
+ * source text, so a .pot with empty translations is a usable source locale; and
8
+ * the format already has a notion of an outdated translation — the fuzzy flag —
9
+ * which maps onto the same rule the translation memory feeds.
10
+ */
11
+ export declare class PoParseError extends FormatError {
12
+ constructor(file: string, line: number, message: string);
13
+ }
14
+ export interface PoEntry {
15
+ context: string | null;
16
+ msgid: string;
17
+ msgidPlural: string | null;
18
+ msgstr: string[];
19
+ fuzzy: boolean;
20
+ line: number;
21
+ }
22
+ export interface PoFile {
23
+ entries: PoEntry[];
24
+ /** From the header's Plural-Forms, when present. */
25
+ nplurals: number | null;
26
+ }
27
+ export declare function parsePo(text: string, file: string): PoFile;
28
+ /** msgctxt disambiguates an otherwise identical msgid. */
29
+ export declare function poKey(entry: PoEntry): string;
30
+ export declare function readPoLocale(file: string, namespace: string, _locale: string, isSource: boolean, target: ReadTarget): void;