diff --git a/README.md b/README.md index 8504bc0..5cf9b92 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ npx @wp-blocks/make-pot src languages --charset='utf-8' --include="src/**/*.{ts, - `--version`: Displays the version number of `make-pot`. - `-h`, `--help`: Displays help information. - `--slug `: Specifies the plugin or theme slug. -- `--domain `: Specifies the text domain to look for in the source code. +- `--domain `: Specifies the text domain to look for in the source code, you can choose "plugin", "theme", "block", "theme-block", "generic". - `--skip-js`: Skips JavaScript files during processing. - `--skip-php`: Skips PHP files during processing. - `--skip-blade`: Skips Blade files during processing. @@ -78,6 +78,7 @@ npx @wp-blocks/make-pot src languages --charset='utf-8' --include="src/**/*.{ts, - `--silent`: Suppresses output to stdout. - `--json`: Outputs the JSON gettext data. - `--charset`: Defines the encoding charset of the pot file, you can choose "iso-8859-1" and "uft-8" (defaults to iso-8859-1) +- `--translation-domains`: Restrict to specific translation domains. - `--output`: Outputs the gettext data. ### Example usage diff --git a/src/cli/getArgs.ts b/src/cli/getArgs.ts index d4e14ec..74b2901 100644 --- a/src/cli/getArgs.ts +++ b/src/cli/getArgs.ts @@ -29,7 +29,8 @@ export function getArgs(userArgs = {}): Args | MakeJsonArgs { type: "string", }, domain: { - describe: "Text domain to look for in the source code", + describe: "Text domain to look for in the source code. Valid domains are: plugin, theme, block, theme-block, generic.", + choices: ["plugin", "theme", "block", "theme-block", "generic"], type: "string", }, "skip-js": { @@ -117,6 +118,10 @@ export function getArgs(userArgs = {}): Args | MakeJsonArgs { type: "string", default: "latin1", }, + "translation-domains": { + describe: "Restrict to specific translation domains", + type: "array", + }, debug: { describe: "Debug mode", type: "boolean", diff --git a/src/cli/parseCli.ts b/src/cli/parseCli.ts index e21ba6f..3f3e51c 100644 --- a/src/cli/parseCli.ts +++ b/src/cli/parseCli.ts @@ -132,6 +132,7 @@ export function parseCliArgs( themeJson: !!args.skipThemeJson, audit: !!args.skipAudit, }, + translationDomains: args.translationDomains ? Array.isArray(args.translationDomains) ? args.translationDomains.map(String) : [String(args.translationDomains)] : undefined, }, // Patterns patterns: { diff --git a/src/parser/process.ts b/src/parser/process.ts index 0c29ac4..bfa6308 100644 --- a/src/parser/process.ts +++ b/src/parser/process.ts @@ -48,7 +48,7 @@ export async function processFiles( ); } else if (allowedFormats.includes(ext)) { const fileTree = readFileAsync(fileRealPath).then((content) => - doTree(content, file, args.debug), + doTree(content, file, args.debug, args), ); if (fileTree) { tasks.push(fileTree as Promise); diff --git a/src/parser/tree.ts b/src/parser/tree.ts index 7c3a2c1..b52c56a 100644 --- a/src/parser/tree.ts +++ b/src/parser/tree.ts @@ -4,6 +4,7 @@ import { i18nFunctions } from "../const.js"; import { Block, SetOfBlocks } from "gettext-merger"; import { getParser } from "../fs/glob.js"; import { reverseSlashes, stripTranslationMarkup } from "../utils/common.js"; +import { Args } from "../types.js"; /** * Collect comments from the AST node and its preceding siblings. @@ -36,12 +37,14 @@ function collectComments(node: SyntaxNode): string | undefined { * @param {string} sourceCode - The source code to be parsed. * @param {string} filepath - The path to the file being parsed. * @param {boolean} debugEnabled - Whether debug mode is enabled. + * @param {Args} args - The command line arguments, optional. * @return {SetOfBlocks} An array of translation strings. */ export function doTree( sourceCode: string, filepath: string, debugEnabled?: boolean, + args?: Args, ): SetOfBlocks { // set up the parser const parser = new Parser(); @@ -112,8 +115,13 @@ export function doTree( msgctxt: string; msgid: string; msgid_plural: string; + number: string; msgstr: string; - }> = {}; + text_domain: string; + }> = { + // WordPress default text domain is 'default' + text_domain: 'default', + }; const translationKeys = i18nFunctions[functionName as keyof typeof i18nFunctions]; @@ -137,24 +145,25 @@ export function doTree( continue; } + // the translation key (eg. msgid) + const currentKey = translationKeys[ + translationKeyIndex + ] as keyof typeof translation; + if (node?.type && stringType.includes(node.type)) { // unquote the strings nodeValue = nodeValue.slice(1, -1); + } else if (currentKey === 'number'){ + // `number` accepts any value, this will not be provided in the POT file + nodeValue = node.text; } else { - if (debugEnabled) { - // Whenever we get an unexpected node type this string is not translatable and should be skipped - console.warn( - `Unexpected node type ${node?.type} identified as ${translationKeys[translationKeyIndex]} with value ${nodeValue} in ${filepath} at ${node.startPosition.row + 1} pos ${node.startPosition.column + 1}`, - ); - } - continue; + // Whenever we get an unexpected node type this string is not translatable and should be skipped + console.error( + `Unexpected node type ${node?.type} identified as ${translationKeys[translationKeyIndex]} with value ${nodeValue} in ${filepath} at ${node.startPosition.row + 1} pos ${node.startPosition.column + 1}`, + ); + return; // Parse error, skip this translation. } - // the translation key (eg. msgid) - const currentKey = translationKeys[ - translationKeyIndex - ] as keyof typeof translation; - // the value of that key translation[currentKey] = nodeValue; @@ -162,6 +171,10 @@ export function doTree( translationKeyIndex += 1; } + if (Array.isArray(args?.options?.translationDomains) && !args.options.translationDomains.includes(translation.text_domain as string)) { + return; + } + const comments = collectComments(argsNode); // Get the translation data diff --git a/src/types.ts b/src/types.ts index 4a73891..7796601 100644 --- a/src/types.ts +++ b/src/types.ts @@ -113,6 +113,7 @@ export interface Args { themeJson?: boolean; audit?: boolean; }; + translationDomains?: string[]; }; headers?: { [key in PotHeaders]: string }; patterns: Patterns; diff --git a/tests/tree.test.js b/tests/tree.test.js index f32413d..a38da79 100644 --- a/tests/tree.test.js +++ b/tests/tree.test.js @@ -177,3 +177,40 @@ describe("doTree large file", () => { assert.strictEqual(r.filter((block) => block.comments).length, 19); }); }); + +describe("doTree php filtered by translation domain", async () => { + it("should extract translations filtered by translation domain", () => { + const content = ` block).length, 1); + } + }); +}); + +describe("doTree php _n, _nx", async () => { + it("should extract translations and comments from code content", () => { + const content = ` block.msgctxt === 'context').length, 1); + }); +});