Skip to main content

Linter for localization files (.po, .ts)

Project description

l10n-lint

🔍 Linter for localization files (.po, .ts) — CLI and GTK interfaces

Check your translation files for common issues like missing translations, fuzzy entries, placeholder mismatches, and more.

Version: 1.14.9 (CLI) / 1.2.9 (GTK)

Features

Core checks

  • Missing translations – Find empty msgstr entries
  • Fuzzy entries – Flag translations needing review
  • Placeholder mismatches – Detect %s, {0}, %1 inconsistencies
  • Duplicate entries – Find repeated msgid entries

Typography & formatting

  • Inconsistent punctuation – Missing or mismatched ending punctuation
  • Inconsistent capitalization – First letter case mismatch
  • Whitespace issues – Trailing spaces, double spaces
  • Mixed quotes – Inconsistent quote styles (" vs " vs )

Technical

  • HTML tag mismatch<b>, <a href> tags don't match
  • Escaped chars mismatch\n, \t, \\ inconsistencies
  • Keyboard accelerators – Missing or mismatched & shortcuts
  • Numeric mismatch – Numbers from source missing in translation

Quality

  • Untranslated words – Common English words left in translation
  • Repeated words – "and and", "the the"
  • Source equals translation – Possibly forgotten to translate
  • Suspicious length – Translation too short or too long

Additional features

  • GitHub support – Lint repos directly without cloning
  • Localized output – Available in 45+ languages
  • CI mode – Exit code only with --check
  • Quiet mode – Summary only with -q

GTK Interface (l10n-lint-gtk)

Modern GTK4/libadwaita graphical interface with:

  • 🎛️ Lint rule preferences – Enable/disable individual checks
  • 📋 File metadata panel – Language, translator, revision date, project info
  • 📊 Statistics – Entries, translated, untranslated, fuzzy counts
  • 🔍 Filter & search – By severity, rule type, or text
  • 🖱️ Drag & drop – Drop files to lint automatically
  • 📤 Export reports – HTML, JSON, or plain text
  • ⌨️ Keyboard shortcuts – Ctrl+O, Ctrl+Return, Ctrl+E
  • 🌍 Localized – 45+ languages

l10n-lint-gtk screenshot

Installation

Debian/Ubuntu (APT)

# Add GPG key
curl -fsSL https://yeager.github.io/debian-repo/yeager.gpg | sudo gpg --dearmor -o /usr/share/keyrings/yeager.gpg

# Add repository
echo 'deb [signed-by=/usr/share/keyrings/yeager.gpg] https://yeager.github.io/debian-repo stable main' | sudo tee /etc/apt/sources.list.d/yeager.list

# Install
sudo apt update
sudo apt install l10n-lint        # CLI only
sudo apt install l10n-lint-gtk    # GTK interface (includes CLI)

Fedora/RHEL (DNF)

sudo tee /etc/yum.repos.d/yeager.repo << 'EOF'
[yeager]
name=Yeager's Translation Tools
baseurl=https://yeager.github.io/rpm-repo
enabled=1
gpgcheck=0
EOF
sudo dnf install l10n-lint

From source

git clone https://github.com/yeager/l10n-lint.git
cd l10n-lint
chmod +x l10n_lint.py l10n_lint_gtk.py

# CLI
ln -s $(pwd)/l10n_lint.py ~/.local/bin/l10n-lint

# GTK (requires: python3-gi, gir1.2-gtk-4.0, gir1.2-adw-1)
ln -s $(pwd)/l10n_lint_gtk.py ~/.local/bin/l10n-lint-gtk

Usage

CLI

# Lint a directory
l10n-lint ./translations/

# Lint a single file
l10n-lint messages.po

# GitHub repository
l10n-lint --github owner/repo

# JSON output
l10n-lint --format json ./translations/

# GitHub Actions annotations
l10n-lint --format github --strict ./translations/

GTK

l10n-lint-gtk                    # Launch GUI
l10n-lint-gtk messages.po        # Open file directly

Or drag and drop files onto the window!

Options

Option Description
--github, -g GitHub repository (owner/repo or URL)
--path, -p Path filter for GitHub repos
--format, -f Output format: text, json, github
--max-length Max translation length (default: 500)
--no-recursive Don't search subdirectories
--strict Treat warnings as errors
-q, --quiet Summary only

Supported formats

Format Extension Description
gettext .po GNU gettext translation files
Qt .ts Qt Linguist translation files

Lint rules

Rule Severity Description
missing-translation ❌ Error Empty msgstr / unfinished translation
fuzzy ⚠️ Warning Translation flagged as fuzzy
placeholder ❌ Error Placeholder mismatch (%s, {0}, etc.)
duplicate ⚠️ Warning Duplicate msgid entry
length ⚠️ Warning Translation length ratio too high
punctuation ℹ️ Info Ending punctuation mismatch
capitalization ℹ️ Info Initial letter case mismatch
whitespace ⚠️ Warning Leading/trailing whitespace issues
html-tags ❌ Error HTML tags don't match
escapes ❌ Error Escape sequences mismatch
accelerators ⚠️ Warning Keyboard accelerator issues
numerics ℹ️ Info Numbers not preserved
untranslated ℹ️ Info English words in translation
repeated-words ℹ️ Info Duplicated words
source-equals-translation ℹ️ Info Translation same as source

Examples

CI/CD Integration

# GitHub Actions
- name: Lint translations
  run: |
    pip install l10n-lint
    l10n-lint --format github --strict ./translations/

Find specific issues

# Missing translations only
l10n-lint ./po/ | grep missing-translation

# JSON for scripting
l10n-lint --format json ./po/ | jq '.issues[] | select(.severity == "error")'

Exit codes

Code Meaning
0 No errors (warnings allowed)
1 Errors found (or warnings with --strict)

Requirements

CLI:

  • Python 3.8+
  • No external dependencies (stdlib only)

GTK:

  • Python 3.8+
  • GTK 4.0, libadwaita 1.0
  • PyGObject (python3-gi)

License

GPL-3.0-or-later

Author

Daniel Nylander (@yeager)


Part of Yeager's Translation Tools

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

l10n_lint-1.15.0.tar.gz (31.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

l10n_lint-1.15.0-py3-none-any.whl (32.8 kB view details)

Uploaded Python 3

File details

Details for the file l10n_lint-1.15.0.tar.gz.

File metadata

  • Download URL: l10n_lint-1.15.0.tar.gz
  • Upload date:
  • Size: 31.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for l10n_lint-1.15.0.tar.gz
Algorithm Hash digest
SHA256 c0b3f3fa8f7b268abc5e2f9323dbefff507d1a738419bea9d00e4c18170797d2
MD5 4e06d34fef83ce9c2325274a6c3e8d7b
BLAKE2b-256 3f3713c52182c6b1b8cc128c1a3836526c8282fc22b6f1b0ec4b476c9d0b8cf9

See more details on using hashes here.

File details

Details for the file l10n_lint-1.15.0-py3-none-any.whl.

File metadata

  • Download URL: l10n_lint-1.15.0-py3-none-any.whl
  • Upload date:
  • Size: 32.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for l10n_lint-1.15.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2cfcb7d308f7493b72f254f121523181ffa421e4351ee8f86db730026cf307e6
MD5 1eb574df819ee7f804716bb5f6b1dd5e
BLAKE2b-256 a8df9ca3bf06817e62d9249a13d49ac24e989b9adc98d74b89195dbc0b3caca2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page