From 7f1dc1614817f52866af8d29684ea20cd2d2bcb7 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Thu, 4 Oct 2018 00:56:49 +0100 Subject: [PATCH] i18n: po4a: Introduce machinery Signed-off-by: Ian Jackson --- po4a/.gitignore | 5 ++ po4a/Makefile | 131 +++++++++++++++++++++++++++++++++++++++++ po4a/install-documents | 27 +++++++++ po4a/list-documents | 45 ++++++++++++++ 4 files changed, 208 insertions(+) create mode 100644 po4a/.gitignore create mode 100644 po4a/Makefile create mode 100755 po4a/install-documents create mode 100755 po4a/list-documents diff --git a/po4a/.gitignore b/po4a/.gitignore new file mode 100644 index 00000000..e640b7ec --- /dev/null +++ b/po4a/.gitignore @@ -0,0 +1,5 @@ +translated +preview.* +.*.po4a.cfg +.*.translated +*.tmp diff --git a/po4a/Makefile b/po4a/Makefile new file mode 100644 index 00000000..3a3310db --- /dev/null +++ b/po4a/Makefile @@ -0,0 +1,131 @@ +# dgit document translation machinery +# +# Translators: there is no need to look at this file. It contains +# complicated machinery which you do not need to understand :-). +# See po/README instead. + +# Copyright (C)2018 Ian Jackson +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# ----- devel docs (translators, pleaee ignore all this) ----- +# +# We use po4a for everything. +# +# po4a is nicely automatic for all the po handling, and the config +# file makes nice documentation, but it really really likes to dirty +# the tree. And we want to automatically list the documents and the +# translation languages which it doesn't make easy. +# +# The approach I have chosen is as follows: +# +# po4a.cfg +# +# This is autogenerated. But also, we invite translators to add +# their own language to it. The resulting merge +# conflict/discrepancy will be just an alphabetical ordering +# discrepancy, since our generation script scans the available po +# files. +# +# Generation is done by a shell script, ./list-documents. +# +# make targets: po4a.cfg # many others imply this +# po4a.cfg.check # fails if out of date +# +# *.pot, *.po +# +# As far as translators are concerned, generated and maintained by +# po4a and committed to git. As for the developers, we update this +# occasionally just by running po4a. +# +# make targets: default } mean +# pofiles } the same +# +# Translations for translators: +# +# make targets: preview.LANG +# translated +# +# Translated document source-language files (eg, translated pod): +# +# Like with normal po things, the tools don't like to generate +# output without updating (dirtying) the .po files. But with po4a +# this is really hard to avoid. So we use a linkfarming technique. +# +# make targets: translated-only +# +# Translated output files (roff format, from pod2man): +# +# We have sort of lost the usual make rule information by now +# about targets and what to build. Only po4a knows which +# translated files are supposed to exist. So we have a shell +# script which reuses the top-level Makefile to run pod2man +# where appropriate, and generate a further even-more-output-ish +# tree. +# +# make targets: install + + +default: pofiles + +all: translated-always + +pofiles: po4a.cfg + po4a --no-translations $< + +e=set -e; exec >$@.tmp +f=mv -f $@.tmp $@ +o= >$@.tmp && $f + +S=@ +# Set S='' to see commands being run + +translated: po4a.cfg + po4a $< + +po4a.cfg: list-documents + ./$< $o + +po4a.cfg.check: list-documents + ./$< >$@.tmp + diff po4a.cfg $@.tmp + +t = ../.po4a.translated-only +p = ../po4a + +translated-only: po4a.cfg + rm -rf $t && mkdir $t + cd $t && ln -s $p/*.po $p/*.pot $p/po4a.cfg . + cd $t && po4a po4a.cfg + ! test -d $t/translated || \ + cp -al --remove-destination $t/translated . + +.po4a.%.cfg: po4a.cfg Makefile + $S perl -p -e 's{^(\[po4a_langs\]).*}{$$1 $*};' \ + -e 's{:translated/man}{:.$*.translated/man}' \ + $< $o + +.PRECIOUS: .po4a.%.cfg + +preview.%: .po4a.%.cfg + $S po4a $< + $S ./install-documents >/dev/null .$*.translated $@ + @ echo '# runes to preview the various final tranlated manpages:' + $S find $@ -type f -printf 'man -l %p\n' + +# We can't really use timestamps to drive po4a +.PHONY: preview.% translated + +install: translated-only + ./install-documents translated $(DESTDIR) diff --git a/po4a/install-documents b/po4a/install-documents new file mode 100755 index 00000000..138c88e9 --- /dev/null +++ b/po4a/install-documents @@ -0,0 +1,27 @@ +#!/bin/bash +set -e + +srcdir=$1; shift +destdir=$1; shift + +mkdir -p "$srcdir" + +docs=( $( ( cd "$srcdir" && find man -type f ) | sed 's#\.pod$##' ) ) + +echo ${docs[*]} + +x () { + echo "+ $*"; + "$@" +} + +if [ "${#docs}" = 0 ]; then exit 0; fi + +x ${MAKE-make} -s -C "$srcdir" -f ../../Makefile ${docs[@]} + +mandest=$destdir/usr/share + +for f in "${docs[@]}"; do + mkdir -p "$mandest/${f%/*}" + x cp "$srcdir/$f" "$mandest/$f" +done diff --git a/po4a/list-documents b/po4a/list-documents new file mode 100755 index 00000000..ca17ec5f --- /dev/null +++ b/po4a/list-documents @@ -0,0 +1,45 @@ +#!/bin/bash +set -e +set -o pipefail + +fail () { "echo >&2 $0: $*"; exit 1; } + +langs=( $( { ! test -f *.po || ls *.po; } \ + | sed 's#\.po$##; s#.*\.##' \ + | LC_COLLATE=C.UTF-8 sort -u) ) + +cat <