-
-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathmake-pot.js
More file actions
85 lines (70 loc) · 2.26 KB
/
make-pot.js
File metadata and controls
85 lines (70 loc) · 2.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/**
* Build Jed-compatible JSON from a `.pot` file.
*
* Why this exists:
* - The plugin ships/uses `languages/visual-portfolio.json` (Jed locale data) for Gutenberg/JS i18n.
* - `npm run build:prod` runs `make-pot` (generate `.pot`) and then `make-json` (convert `.pot` -> Jed JSON).
*
* Why we replaced `po2json` with this script:
* - `po2json` pulled in vulnerable/legacy transitive dependencies (surfaced by `npm audit`).
* - This script keeps the same output format needed by WordPress/Jed while using a smaller, maintained parser
* (`gettext-parser`) and avoiding that vulnerable dependency chain.
*/
const fs = require( 'fs' );
const gettextParser = require( 'gettext-parser' );
function getArgValue( args, name ) {
const prefix = `--${ name }=`;
const found = args.find( ( a ) => a.startsWith( prefix ) );
return found ? found.slice( prefix.length ) : null;
}
function hasFlag( args, flag ) {
return args.includes( `--${ flag }` );
}
function buildJedJsonFromPot( potBuffer, domain ) {
const po = gettextParser.po.parse( potBuffer );
const usedDomain = domain || po.headers?.domain || 'messages';
const localeData = {
[ usedDomain ]: {
'': {
domain: usedDomain,
},
},
};
for ( const [ context, messages ] of Object.entries(
po.translations || {}
) ) {
for ( const [ msgid, message ] of Object.entries( messages || {} ) ) {
if ( msgid === '' ) {
continue;
}
const key = context ? `${ context }\u0004${ msgid }` : msgid;
if ( Array.isArray( message.msgstr ) ) {
localeData[ usedDomain ][ key ] = message.msgstr;
} else {
localeData[ usedDomain ][ key ] = [ '' ];
}
}
}
return {
domain: usedDomain,
locale_data: localeData,
};
}
function main() {
const args = process.argv.slice( 2 );
const input = args[ 0 ];
const output = args[ 1 ];
if ( ! input || ! output ) {
process.stderr.write(
'Usage: node make-pot.js <input.pot> <output.json> --domain=visual-portfolio [--pretty]\n'
);
process.exit( 1 );
}
const domain = getArgValue( args, 'domain' );
const pretty = hasFlag( args, 'pretty' );
const pot = fs.readFileSync( input );
const result = buildJedJsonFromPot( pot, domain );
const json = JSON.stringify( result, null, pretty ? 3 : 0 );
fs.writeFileSync( output, `${ json }\n` );
}
main();