diff options
| author | Florian Pelz <pelzflorian@pelzflorian.de> | 2025-09-01 13:51:04 +0200 |
|---|---|---|
| committer | Florian Pelz <pelzflorian@pelzflorian.de> | 2025-09-30 10:37:34 +0200 |
| commit | b5054a85c1bff91ca8a55b2ca218fb5f2b9518cd (patch) | |
| tree | 0ddaf3476c8d1e03805fbb57900b908431601ccd | |
| parent | 0509bc4cba554789ab91189c234ac8bd35be14cd (diff) | |
nls: Minify translation PO files.
To save a lot of disk space, keep only actually translated messages in
Gettext PO files. Ignore the guix domain, which is more complicated
and is tiny.
* build-aux/keep-only-translated.scm: New file.
* Makefile.am (download-po): Run it.
Change-Id: I6442ce0ef8d62f7e48e667c766b86d0ebf9c5415
| -rw-r--r-- | Makefile.am | 17 | ||||
| -rw-r--r-- | build-aux/keep-only-translated.scm | 78 |
2 files changed, 91 insertions, 4 deletions
diff --git a/Makefile.am b/Makefile.am index 19aad0042e3..b29f2dfa84a 100644 --- a/Makefile.am +++ b/Makefile.am | |||
| @@ -1299,8 +1299,10 @@ WEBLATE_REPO = https://codeberg.org/guix/translations | |||
| 1299 | # Shallow clone the Git repository behind Weblate and copy files from it if | 1299 | # Shallow clone the Git repository behind Weblate and copy files from it if |
| 1300 | # they contain at least one translation, and they are well-formed (Scheme | 1300 | # they contain at least one translation, and they are well-formed (Scheme |
| 1301 | # format only), warn otherwise. Copied files are converted to a canonical | 1301 | # format only), warn otherwise. Copied files are converted to a canonical |
| 1302 | # form. | 1302 | # form. Note: The files will be minified to reduce file size, except the |
| 1303 | download-po: | 1303 | # guix domain, because they are comparatively small and it would need more |
| 1304 | # comprehensive PO file parsing abilities for plural forms. | ||
| 1305 | download-po: guix/build/po.go | ||
| 1304 | dir=$$(mktemp -d); \ | 1306 | dir=$$(mktemp -d); \ |
| 1305 | git clone --depth 1 "$(WEBLATE_REPO)" "$$dir/translations" && \ | 1307 | git clone --depth 1 "$(WEBLATE_REPO)" "$$dir/translations" && \ |
| 1306 | for domain in po/doc po/guix po/packages; do \ | 1308 | for domain in po/doc po/guix po/packages; do \ |
| @@ -1313,8 +1315,15 @@ download-po: | |||
| 1313 | target="$$domain/$$target"; \ | 1315 | target="$$domain/$$target"; \ |
| 1314 | msgfmt -c "$$po"; \ | 1316 | msgfmt -c "$$po"; \ |
| 1315 | if msgfmt -c "$$po" && [ "$$translated" != "0" ] && ([ "$$domain" != "po/doc" ] || [ "$$translated" -gt $$(($$total/10)) ] || [ -f $$target ]); then \ | 1317 | if msgfmt -c "$$po" && [ "$$translated" != "0" ] && ([ "$$domain" != "po/doc" ] || [ "$$translated" -gt $$(($$total/10)) ] || [ -f $$target ]); then \ |
| 1316 | msgconv --no-wrap -o "$$po".tmp "$$po"; \ | 1318 | if [ "$$domain" != "po/guix" ]; then \ |
| 1317 | mv "$$po".tmp "$$target"; \ | 1319 | $(GUILE) -L "$(top_builddir)" -L "$(top_srcdir)" \ |
| 1320 | --no-auto-compile \ | ||
| 1321 | -s "$(top_srcdir)"/build-aux/keep-only-translated.scm \ | ||
| 1322 | "$$po" > "$$po".tmp; \ | ||
| 1323 | else ln -s "$$po" "$$po".tmp; fi; \ | ||
| 1324 | msgconv --no-wrap -o "$$po".tmp2 "$$po".tmp; \ | ||
| 1325 | rm "$$po".tmp; \ | ||
| 1326 | mv "$$po".tmp2 "$$target"; \ | ||
| 1318 | echo "copied $$target."; \ | 1327 | echo "copied $$target."; \ |
| 1319 | else \ | 1328 | else \ |
| 1320 | echo "WARN: $$target ($$translated translated messages ($$((translated/total*100))%)) was not added/updated."; \ | 1329 | echo "WARN: $$target ($$translated translated messages ($$((translated/total*100))%)) was not added/updated."; \ |
diff --git a/build-aux/keep-only-translated.scm b/build-aux/keep-only-translated.scm new file mode 100644 index 00000000000..c6b0905c4b4 --- /dev/null +++ b/build-aux/keep-only-translated.scm | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | ;;; GNU Guix --- Functional package management for GNU | ||
| 2 | ;;; Copyright © 2025 Florian Pelz <pelzflorian@pelzflorian.de> | ||
| 3 | ;;; | ||
| 4 | ;;; This file is part of GNU Guix. | ||
| 5 | ;;; | ||
| 6 | ;;; GNU Guix is free software; you can redistribute it and/or modify it | ||
| 7 | ;;; under the terms of the GNU General Public License as published by | ||
| 8 | ;;; the Free Software Foundation; either version 3 of the License, or (at | ||
| 9 | ;;; your option) any later version. | ||
| 10 | ;;; | ||
| 11 | ;;; GNU Guix is distributed in the hope that it will be useful, but | ||
| 12 | ;;; WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | ;;; GNU General Public License for more details. | ||
| 15 | ;;; | ||
| 16 | ;;; You should have received a copy of the GNU General Public License | ||
| 17 | ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. | ||
| 18 | |||
| 19 | ;; Minify Gettext PO files when synced from | ||
| 20 | ;; <https://codeberg.org/guix/translations/>, | ||
| 21 | ;; keeping only actually translated messages. | ||
| 22 | |||
| 23 | ;; Note: This does not work for PO files of the guix domain, which needed | ||
| 24 | ;; support for plural forms in (@ (guix build po) read-po-file). The guix | ||
| 25 | ;; domain's files are comparatively small and the read-po-file API would | ||
| 26 | ;; have to be expanded to use records or such; it is not worth it. | ||
| 27 | |||
| 28 | (use-modules (guix build po) | ||
| 29 | (ice-9 match) | ||
| 30 | (ice-9 textual-ports)) | ||
| 31 | |||
| 32 | (define (escape str) | ||
| 33 | "Escape msgid or msgstr. Replace by C-style escape sequences." | ||
| 34 | (let* ((in (open-input-string str)) | ||
| 35 | (text (get-string-all in)) | ||
| 36 | (escaped-text-as-list | ||
| 37 | (string-fold-right | ||
| 38 | (lambda (char result) | ||
| 39 | (cons (case char | ||
| 40 | ((#\") "\\\"") | ||
| 41 | ((#\\) "\\\\") | ||
| 42 | ((#\linefeed) "\\n") | ||
| 43 | ((#\return) "\\r") | ||
| 44 | ((#\tab) "\\t") | ||
| 45 | (else (string char))) | ||
| 46 | result)) | ||
| 47 | '() | ||
| 48 | text)) | ||
| 49 | (escaped-text (apply string-append escaped-text-as-list))) | ||
| 50 | (display escaped-text))) | ||
| 51 | |||
| 52 | (match (command-line) | ||
| 53 | ((program pofile) | ||
| 54 | (let ((input (open-input-file pofile))) | ||
| 55 | ;; Just copy until an empty line. | ||
| 56 | (letrec ((copy | ||
| 57 | (lambda () | ||
| 58 | (let ((next-line (get-line input))) | ||
| 59 | (display next-line) | ||
| 60 | (newline) | ||
| 61 | (when (> (string-length next-line) 0) | ||
| 62 | (copy)))))) | ||
| 63 | (copy)) | ||
| 64 | ;; Then print only translated messages. | ||
| 65 | (for-each | ||
| 66 | (lambda (msg) | ||
| 67 | (match msg | ||
| 68 | ((msgid . msgstr) | ||
| 69 | (display "msgid \"") | ||
| 70 | (escape msgid) | ||
| 71 | (display "\"") | ||
| 72 | (newline) | ||
| 73 | (display "msgstr \"") | ||
| 74 | (escape msgstr) | ||
| 75 | (display "\"") | ||
| 76 | (newline) | ||
| 77 | (newline)))) | ||
| 78 | (read-po-file input))))) | ||
