From b59785ef4e51156b69c0c1a8e6e0724dcadddb44 Mon Sep 17 00:00:00 2001 From: Florian Pelz Date: Wed, 7 Aug 2019 23:52:31 +0200 Subject: [PATCH 3/6] website: Use custom xgettext implementation. * website/po/POTFILES: New file; list apps/base/templates files here. * website/po/LINGUAS: New file. List en_US lingua. * website/apps/i18n.scm: New file. Add utility functions. * website/haunt.scm: Load linguas and call each builder with each. --- website/apps/i18n.scm | 105 ++++++++++++++++++++++++++++++++++++++++++ website/haunt.scm | 24 +++++++--- website/po/LINGUAS | 1 + website/po/POTFILES | 13 ++++++ 4 files changed, 137 insertions(+), 6 deletions(-) create mode 100644 website/apps/i18n.scm create mode 100644 website/po/LINGUAS create mode 100644 website/po/POTFILES diff --git a/website/apps/i18n.scm b/website/apps/i18n.scm new file mode 100644 index 0000000..fbbbd9f --- /dev/null +++ b/website/apps/i18n.scm @@ -0,0 +1,105 @@ +;;; GNU Guix web site +;;; Copyright © 2019 Florian Pelz +;;; +;;; This file is part of the GNU Guix web site. +;;; +;;; The GNU Guix web site is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU Affero General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; The GNU Guix web site is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU Affero General Public License for more details. +;;; +;;; You should have received a copy of the GNU Affero General Public License +;;; along with the GNU Guix web site. If not, see . + +(define-module (apps i18n) + #:use-module (haunt page) + #:use-module (haunt utils) + #:use-module (ice-9 match) + #:use-module (sexp-xgettext) + #:use-module (srfi srfi-1) + #:export (G_ + N_ + C_ + NC_ + %current-lingua + builder->localized-builder + builders->localized-builders)) + +(define %gettext-domain + "guix-website") + +(bindtextdomain %gettext-domain (getcwd)) +(bind-textdomain-codeset %gettext-domain "UTF-8") +(textdomain %gettext-domain) + +(define-syntax G_ + sgettext) + +(set-simple-keywords! '(G_)) + +(define-syntax N_ ;like ngettext + sngettext) + +(define-syntax C_ ;like pgettext + spgettext) + +(define-syntax NC_ ;like npgettext + snpgettext) + +(set-complex-keywords! '(N_ C_ NC_)) + +(define + (@@ (haunt page) )) + +(define %current-lingua + (make-parameter "en_US")) + +(define (first-value arg) + "For some reason the builder returned by static-directory returns +multiple values. This procedure is used to retain only the first +return value. TODO: This should not be necessary." + arg) + +(define (builder->localized-builder builder lingua) + "Returns a Haunt builder procedure generated from an existing +BUILDER with translations for LINGUA coming from sexp-xgettext." + (compose + (lambda (pages) + (map + (lambda (page) + (match page + (($ file-name contents writer) + (if (string-suffix? ".html" file-name) + (let* ((base (string-drop-right + file-name + (string-length ".html"))) + (new-name (string-append base + "." + lingua + ".html"))) + (make-page new-name contents writer)) + page)) + (else page))) + pages)) + (lambda (site posts) + (begin + (setlocale LC_ALL (string-append lingua ".utf8")) + (parameterize ((%current-lingua lingua)) + (first-value (builder site posts))))))) + +(define (builders->localized-builders builders linguas) + "Returns a list of new Haunt builder procedures generated from +BUILDERS and localized via sexp-xgettext for each of the LINGUAS." + (flatten + (map-in-order + (lambda (builder) + (map-in-order + (lambda (lingua) + (builder->localized-builder builder lingua)) + linguas)) + builders))) diff --git a/website/haunt.scm b/website/haunt.scm index d29c0d4..eb0eafe 100644 --- a/website/haunt.scm +++ b/website/haunt.scm @@ -5,13 +5,23 @@ (use-modules ((apps base builder) #:prefix base:) ((apps blog builder) #:prefix blog:) ((apps download builder) #:prefix download:) + (apps i18n) ((apps packages builder) #:prefix packages:) (haunt asset) (haunt builder assets) (haunt reader) (haunt reader commonmark) - (haunt site)) + (haunt site) + (ice-9 rdelim) + (srfi srfi-1)) +(define linguas + (with-input-from-file "po/LINGUAS" + (lambda _ + (let loop ((line (read-line))) + (if (eof-object? line) + '() + (cons line (loop (read-line)))))))) (site #:title "GNU Guix" #:domain (if (getenv "GUIX_WEB_SITE_INFO") @@ -19,8 +29,10 @@ "https://gnu.org/software/guix") #:build-directory "/tmp/gnu.org/software/guix" #:readers (list sxml-reader html-reader commonmark-reader) - #:builders (list base:builder - blog:builder - download:builder - packages:builder - (static-directory "static"))) + #:builders (builders->localized-builders + (list base:builder + blog:builder + download:builder + packages:builder + (static-directory "static")) + linguas)) diff --git a/website/po/LINGUAS b/website/po/LINGUAS new file mode 100644 index 0000000..7741b83 --- /dev/null +++ b/website/po/LINGUAS @@ -0,0 +1 @@ +en_US diff --git a/website/po/POTFILES b/website/po/POTFILES new file mode 100644 index 0000000..4013d52 --- /dev/null +++ b/website/po/POTFILES @@ -0,0 +1,13 @@ +apps/base/templates/about.scm +apps/base/templates/components.scm +apps/base/templates/contact.scm +apps/base/templates/contribute.scm +apps/base/templates/donate.scm +apps/base/templates/graphics.scm +apps/base/templates/help.scm +apps/base/templates/home.scm +apps/base/templates/irc.scm +apps/base/templates/menu.scm +apps/base/templates/screenshot.scm +apps/base/templates/security.scm +apps/base/templates/theme.scm -- 2.22.0