{"_id":"pseudo-l10n","name":"pseudo-l10n","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"pseudo-l10n","version":"1.0.0","description":"Easy-to-use pseudo-localization generator for testing i18n implementations. Adds accented characters, text expansion, and visual markers to help identify localization issues.","main":"index.js","bin":{"pseudo-l10n":"bin/cli.js"},"scripts":{"test":"node examples/demo.js"},"keywords":["i18n","l10n","pseudo-localization","pseudo-locale","internationalization","localization","testing","qa","i18next","translation"],"author":{"name":"Anton Antonov"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/AntonovAnton/pseudo-l10n.git"},"homepage":"https://github.com/AntonovAnton/pseudo-l10n#readme","bugs":{"url":"https://github.com/AntonovAnton/pseudo-l10n/issues"},"engines":{"node":">=12.0.0"},"gitHead":"bce590dea7007b511091a57ccaab8e4a5b0a3bff","_id":"pseudo-l10n@1.0.0","_nodeVersion":"22.21.1","_npmVersion":"11.6.3","dist":{"integrity":"sha512-EZ7dOBbORxzeKzyuDVWr4uptt3xuk99qcWPudhALZAPxmMeApQJ5WIeZz80KS+M8y6rv+Xgk7Dv5SGuTZH/XNw==","shasum":"7a3863eb14e5627099a82c88a83efe3ce64aa356","tarball":"https://registry.npmjs.org/pseudo-l10n/-/pseudo-l10n-1.0.0.tgz","fileCount":5,"unpackedSize":27494,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCAOn5SI5Z28UqY0UDys138A4gCPmkK9xGxJQvu4AyFdwIhAJPAGIVkKPAIAYxZ6iwRjN9p3gRE/gjdT7wa2WH7T8rO"}]},"_npmUser":{"name":"l10n.dev","email":"menantonov@gmail.com"},"directories":{},"maintainers":[{"name":"l10n.dev","email":"menantonov@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pseudo-l10n_1.0.0_1764796896583_0.5327858574216522"},"_hasShrinkwrap":false}},"time":{"created":"2025-12-03T21:21:36.582Z","1.0.0":"2025-12-03T21:21:36.769Z","modified":"2025-12-03T21:21:37.083Z"},"maintainers":[{"name":"l10n.dev","email":"menantonov@gmail.com"}],"description":"Easy-to-use pseudo-localization generator for testing i18n implementations. Adds accented characters, text expansion, and visual markers to help identify localization issues.","homepage":"https://github.com/AntonovAnton/pseudo-l10n#readme","keywords":["i18n","l10n","pseudo-localization","pseudo-locale","internationalization","localization","testing","qa","i18next","translation"],"repository":{"type":"git","url":"git+https://github.com/AntonovAnton/pseudo-l10n.git"},"author":{"name":"Anton Antonov"},"bugs":{"url":"https://github.com/AntonovAnton/pseudo-l10n/issues"},"license":"MIT","readme":"# pseudo-l10n\r\n\r\n[![npm version](https://img.shields.io/npm/v/pseudo-l10n.svg)](https://www.npmjs.com/package/pseudo-l10n)\r\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\r\n\r\n**Easy-to-use pseudo-localization generator for testing i18n implementations.**\r\n\r\nPseudo-localization helps QA engineers and developers identify internationalization (i18n) issues before actual translation. This package transforms your English JSON translation files into pseudo-localized versions that simulate real-world localization challenges.\r\n\r\n![Pseudo-localization example](https://raw.githubusercontent.com/AntonovAnton/pseudo-l10n/main/pseudo-localization-example.webp)\r\n\r\n## Why Pseudo-localization?\r\n\r\nPseudo-localization helps you catch i18n issues early:\r\n\r\n- 🔍 **Untranslated strings** - Visual markers make them obvious\r\n- 📏 **Layout problems** - Text expansion reveals truncation issues  \r\n- 🌍 **Encoding issues** - Accented characters test UTF-8 support\r\n- 🔄 **RTL problems** - Simulate right-to-left languages\r\n- 🎯 **Placeholder handling** - Verify dynamic content works correctly\r\n\r\n**Learn more:** Read the comprehensive guide on [i18n Testing: A Practical Guide for QA Engineers](https://medium.com/@AntonAntonov88/i18n-testing-a-practical-guide-for-qa-engineers-a92f7f4fc8b2)\r\n\r\n## Ready to Translate?\r\n\r\nOnce you've tested your i18n implementation with pseudo-localization, use [**l10n**](https://l10n.dev).dev service for AI-powered translation that preserves placeholders, respects formatting, and understands context—making professional localization effortless. [Try JSON Translation](https://l10n.dev/ws/translate-json) or even other formats [Translate i18n files](https://l10n.dev/ws/translate-i18n-files)\r\n\r\n## Installation\r\n\r\n```bash\r\nnpm install -g pseudo-l10n\r\n```\r\n\r\nOr as a development dependency:\r\n\r\n```bash\r\nnpm install --save-dev pseudo-l10n\r\n```\r\n\r\n## Quick Start\r\n\r\n### Command Line Usage\r\n\r\n```bash\r\n# Basic usage\r\npseudo-l10n input.json output.json\r\n\r\n# With custom options\r\npseudo-l10n en.json pseudo-en.json --expansion=30 --rtl\r\n```\r\n\r\n### Programmatic Usage\r\n\r\n```javascript\r\nconst { generatePseudoLocaleSync, pseudoLocalize } = require('pseudo-l10n');\r\n\r\n// Generate a pseudo-localized JSON file\r\ngeneratePseudoLocaleSync('en.json', 'pseudo-en.json', {\r\n  expansion: 40,\r\n  rtl: false\r\n});\r\n\r\n// Pseudo-localize a single string\r\nconst result = pseudoLocalize('Hello, {{name}}!');\r\nconsole.log(result);\r\n// Output: ⟦Ĥëļļõēēēēēēēēēēēēēē, {{name}}!ēēēēē⟧\r\n```\r\n\r\n## Features\r\n\r\n### 1. Text Expansion\r\n\r\nSimulates how translated text is often longer than English (typically 30-40% longer for European languages).\r\n\r\n**Example:**\r\n```\r\nInput:  \"Welcome\"\r\nOutput: \"⟦Ŵëļçõɱëēēē⟧\"\r\n```\r\n\r\n### 2. Accented Characters\r\n\r\nReplaces ASCII characters with accented equivalents to test UTF-8 encoding and font support.\r\n\r\n### 3. Visual Markers\r\n\r\nWraps all strings with configurable markers (default: `⟦...⟧`) to easily spot:\r\n- Untranslated strings (missing markers)\r\n- Truncated strings (cut-off markers)\r\n- Concatenated strings (markers in the middle)\r\n\r\n### 4. Placeholder Handling\r\n\r\nPreserves placeholders like `{{name}}`, `{count}`, `%key%`, etc. with configurable formats.\r\n\r\n### 5. RTL Simulation\r\n\r\nSimulates Right-to-Left languages (Arabic, Hebrew) using Unicode control characters.\r\n\r\n**Note on RTL:** By default, placeholders are reversed in RTL mode (e.g., `{{name}}` becomes `{{eman}}`). This helps detect placeholder issues when testing screenshots. For live HTML testing, you may want to disable this with `--no-reverse-placeholders`.\r\n\r\n## Configuration Options\r\n\r\n### CLI Options\r\n\r\n```bash\r\npseudo-l10n <input.json> <output.json> [options]\r\n\r\nOptions:\r\n  --expansion=<number>           Text expansion percentage (default: 40)\r\n  --placeholder-format=<format>  Placeholder format (default: \"{{key}}\")\r\n  --replace-placeholders         Replace placeholders with <UPPERCASE> format\r\n  --start-marker=<string>        Start marker (default: \"⟦\")\r\n  --end-marker=<string>          End marker (default: \"⟧\")\r\n  --rtl                          Enable RTL simulation\r\n  --no-reverse-placeholders      Don't reverse placeholders in RTL mode\r\n  --expansion-char=<char>        Character for expansion (default: \"ē\")\r\n  --help, -h                     Show help\r\n```\r\n\r\n### Programmatic API Options\r\n\r\n```javascript\r\n{\r\n  expansion: 40,                    // Text expansion percentage\r\n  placeholderFormat: \"{{key}}\",     // Placeholder format\r\n  replacePlaceholders: false,       // Replace with <UPPERCASE> format\r\n  startMarker: \"⟦\",               // Start marker\r\n  endMarker: \"⟧\",                 // End marker\r\n  rtl: false,                       // Enable RTL mode\r\n  reversePlaceholders: true,        // Reverse placeholder content in RTL\r\n  expansionChar: \"ē\",               // Character used for expansion\r\n  accentMap: { ... }                // Custom accent character mapping\r\n}\r\n```\r\n\r\n## Placeholder Formats\r\n\r\nThe package supports various placeholder formats used by different i18n libraries:\r\n\r\n| Framework      | Format              | Example                      |\r\n|----------------|---------------------|------------------------------|\r\n| i18next        | `{{key}}`          | `\"Hello {{name}}\"`           |\r\n| Angular        | `{key}`            | `\"Hello {name}\"`             |\r\n| React Intl     | `{key}`            | `\"Hello {name}\"`             |\r\n| sprintf        | `%key%`            | `\"Hello %name%\"`             |\r\n| ES6 Template   | `${key}`           | `\"Hello ${name}\"`            |\r\n\r\n### Configuring Placeholder Format\r\n\r\n#### CLI:\r\n```bash\r\n# For Angular/React Intl\r\npseudo-l10n en.json pseudo-en.json --placeholder-format=\"{key}\"\r\n\r\n# For sprintf style\r\npseudo-l10n en.json pseudo-en.json --placeholder-format=\"%key%\"\r\n```\r\n\r\n#### Programmatic:\r\n```javascript\r\ngeneratePseudoLocaleSync('en.json', 'pseudo-en.json', {\r\n  placeholderFormat: \"{key}\"  // or \"%key%\" or \"${key}\"\r\n});\r\n```\r\n\r\n## Examples\r\n\r\n### Example 1: Basic i18next JSON\r\n\r\n**Input** (`en.json`):\r\n```json\r\n{\r\n  \"welcome\": \"Welcome to our application\",\r\n  \"greeting\": \"Hello, {{name}}!\",\r\n  \"itemCount\": \"You have {{count}} items\"\r\n}\r\n```\r\n\r\n**Command:**\r\n```bash\r\npseudo-l10n en.json pseudo-en.json\r\n```\r\n\r\n**Output** (`pseudo-en.json`):\r\n```json\r\n{\r\n  \"welcome\": \"⟦Ŵëļçõɱë ţõ õür àƥƥļïçàţïõñēēēēēēēēēēēēēēēēēē⟧\",\r\n  \"greeting\": \"⟦Ĥëļļõēēēēēē, {{name}}!ēēēēē⟧\",\r\n  \"itemCount\": \"⟦Ŷõü ĥàṽë {{count}} ïţëɱšēēēēēēēēēēēēēēēē⟧\"\r\n}\r\n```\r\n\r\n### Example 2: RTL Simulation\r\n\r\n**Command:**\r\n```bash\r\npseudo-l10n en.json pseudo-ar.json --rtl\r\n```\r\n\r\n**Output:**\r\nAdds Unicode RTL control characters (`U+202E` ... `U+202C`) around text to simulate Arabic/Hebrew layout.\r\n\r\n### Example 3: Custom Markers and Expansion\r\n\r\n**Command:**\r\n```bash\r\npseudo-l10n en.json pseudo-en.json --expansion=30 --start-marker=\"[[ \" --end-marker=\" ]]\"\r\n```\r\n\r\n**Output:**\r\n```json\r\n{\r\n  \"welcome\": \"[[ Ŵëļçõɱë ţõ õür àƥƥļïçàţïõñēēēēēēēēēē ]]\"\r\n}\r\n```\r\n\r\n### Example 4: Replace Placeholders\r\n\r\n**Command:**\r\n```bash\r\npseudo-l10n en.json pseudo-en.json --replace-placeholders\r\n```\r\n\r\n**Input:**\r\n```json\r\n{\r\n  \"greeting\": \"Hello, {{name}}!\"\r\n}\r\n```\r\n\r\n**Output:**\r\n```json\r\n{\r\n  \"greeting\": \"⟦Ĥëļļõēēēēēē, <NAME>!ēēēēē⟧\"\r\n}\r\n```\r\n\r\n## Accented Character Map\r\n\r\nThe package uses the following character mappings by default:\r\n\r\n| Original | Accented | Original | Accented |\r\n|----------|----------|----------|----------|\r\n| a        | à        | A        | À        |\r\n| b        | ƀ        | B        | ß        |\r\n| c        | ç        | C        | Ç        |\r\n| d        | đ        | D        | Đ        |\r\n| e        | ë        | E        | Ë        |\r\n| f        | ƒ        | F        | Ƒ        |\r\n| g        | ğ        | G        | Ğ        |\r\n| h        | ĥ        | H        | Ħ        |\r\n| i        | ï        | I        | Ï        |\r\n| j        | ĵ        | J        | Ĵ        |\r\n| k        | ķ        | K        | Ķ        |\r\n| l        | ļ        | L        | Ļ        |\r\n| m        | ɱ        | M        | Ṁ        |\r\n| n        | ñ        | N        | Ñ        |\r\n| o        | õ        | O        | Õ        |\r\n| p        | ƥ        | P        | Ƥ        |\r\n| q        | ɋ        | Q        | Ɋ        |\r\n| r        | ř        | R        | Ř        |\r\n| s        | š        | S        | Š        |\r\n| t        | ţ        | T        | Ť        |\r\n| u        | ü        | U        | Ü        |\r\n| v        | ṽ        | V        | Ṽ        |\r\n| w        | ŵ        | W        | Ŵ        |\r\n| x        | ẋ        | X        | Ẍ        |\r\n| y        | ý        | Y        | Ŷ        |\r\n| z        | ž        | Z        | Ž        |\r\n\r\n### Custom Accent Map\r\n\r\nYou can provide your own accent map programmatically:\r\n\r\n```javascript\r\nconst { generatePseudoLocaleSync } = require('pseudo-l10n');\r\n\r\ngeneratePseudoLocaleSync('en.json', 'pseudo-en.json', {\r\n  accentMap: {\r\n    a: 'α', b: 'β', c: 'ς',\r\n    A: 'Α', B: 'Β', C: 'Σ',\r\n    // ... add more mappings\r\n  }\r\n});\r\n```\r\n\r\n## API Reference\r\n\r\n### `pseudoLocalize(str, options)`\r\n\r\nPseudo-localizes a single string.\r\n\r\n**Parameters:**\r\n- `str` (string): The string to pseudo-localize\r\n- `options` (object): Configuration options\r\n\r\n**Returns:** Pseudo-localized string\r\n\r\n**Example:**\r\n```javascript\r\nconst { pseudoLocalize } = require('pseudo-l10n');\r\n\r\nconst result = pseudoLocalize('Hello World', {\r\n  expansion: 30,\r\n  startMarker: '[[',\r\n  endMarker: ']]'\r\n});\r\n```\r\n\r\n### `processObject(obj, options)`\r\n\r\nRecursively processes an object/array structure, pseudo-localizing all strings.\r\n\r\n**Parameters:**\r\n- `obj` (any): Object, array, or primitive to process\r\n- `options` (object): Configuration options\r\n\r\n**Returns:** Processed structure with pseudo-localized strings\r\n\r\n### `generatePseudoLocale(inputPath, outputPath, options)`\r\n\r\nAsynchronously generates a pseudo-localized JSON file.\r\n\r\n**Parameters:**\r\n- `inputPath` (string): Path to input JSON file\r\n- `outputPath` (string): Path to output JSON file\r\n- `options` (object): Configuration options\r\n\r\n**Returns:** Promise<void>\r\n\r\n### `generatePseudoLocaleSync(inputPath, outputPath, options)`\r\n\r\nSynchronously generates a pseudo-localized JSON file.\r\n\r\n**Parameters:**\r\n- `inputPath` (string): Path to input JSON file\r\n- `outputPath` (string): Path to output JSON file\r\n- `options` (object): Configuration options\r\n\r\n## Integration Examples\r\n\r\n### npm scripts\r\n\r\nAdd to your `package.json`:\r\n\r\n```json\r\n{\r\n  \"scripts\": {\r\n    \"pseudo\": \"pseudo-l10n src/locales/en.json src/locales/pseudo-en.json\",\r\n    \"pseudo:rtl\": \"pseudo-l10n src/locales/en.json src/locales/pseudo-ar.json --rtl\"\r\n  }\r\n}\r\n```\r\n\r\n### Build Process\r\n\r\n```javascript\r\n// build.js\r\nconst { generatePseudoLocaleSync } = require('pseudo-l10n');\r\n\r\n// Generate pseudo-locales as part of build\r\ngeneratePseudoLocaleSync(\r\n  './src/locales/en.json',\r\n  './src/locales/pseudo-en.json',\r\n  { expansion: 40 }\r\n);\r\n\r\ngeneratePseudoLocaleSync(\r\n  './src/locales/en.json',\r\n  './src/locales/pseudo-ar.json',\r\n  { rtl: true }\r\n);\r\n```\r\n\r\n### CI/CD Pipeline\r\n\r\n```yaml\r\n# .github/workflows/test.yml\r\n- name: Generate pseudo-locales\r\n  run: |\r\n    npm install -g pseudo-l10n\r\n    pseudo-l10n src/locales/en.json src/locales/pseudo-en.json\r\n    \r\n- name: Run i18n tests\r\n  run: npm run test:i18n\r\n```\r\n\r\n## Testing Strategy\r\n\r\n1. **Generate pseudo-locale** during build\r\n2. **Add pseudo-locale to your app** (e.g., language selector)\r\n3. **Test your application** with pseudo-locale enabled\r\n4. **Look for issues:**\r\n   - Missing `⟦⟧` markers = untranslated strings\r\n   - Cut-off markers = text truncation\r\n   - Broken layout = insufficient space for expansion\r\n   - Garbled text = encoding issues\r\n   - Wrong text direction = RTL problems\r\n\r\n## FAQ\r\n\r\n**Q: Should I reverse placeholders in RTL mode?**  \r\nA: It depends on your testing approach:\r\n- **Testing screenshots:** Yes (default behavior). Helps detect placeholder issues visually.\r\n- **Testing live HTML:** No. Use `--no-reverse-placeholders` since the browser handles RTL.\r\n\r\n**Q: Why use accented characters instead of random text?**  \r\nA: Accented characters are still readable, making debugging easier while still testing encoding and font support.\r\n\r\n**Q: What expansion percentage should I use?**  \r\nA: 40% is a good default for European languages. German can be 50%+, Romance languages 30-40%.\r\n\r\n**Q: Can I use this with other i18n libraries?**  \r\nA: Yes! The package works with any JSON-based translation files. Just configure the placeholder format to match your library.\r\n\r\n## Contributing\r\n\r\nContributions are welcome! Please feel free to submit a Pull Request.\r\n\r\n## License\r\n\r\nMIT © Anton Antonov\r\n\r\n## Related Resources\r\n\r\n- [i18n Testing: A Practical Guide for QA Engineers](https://medium.com/@AntonAntonov88/i18n-testing-a-practical-guide-for-qa-engineers-a92f7f4fc8b2) - Comprehensive guide on pseudo-localization testing\r\n- [GitHub Repository](https://github.com/AntonovAnton/pseudo-l10n)\r\n\r\n## Support\r\n\r\nIf you encounter any issues or have questions, please [open an issue](https://github.com/AntonovAnton/pseudo-l10n/issues) on GitHub.\r\n","readmeFilename":"README.md","_rev":"1-793109cab0d77422c574a4e51d6b23c6"}