summaryrefslogtreecommitdiff
path: root/po4a
diff options
context:
space:
mode:
authorIan Jackson <ijackson@chiark.greenend.org.uk>2018-10-04 00:56:49 +0100
committerIan Jackson <ijackson@chiark.greenend.org.uk>2018-10-04 02:01:52 +0100
commit7f1dc1614817f52866af8d29684ea20cd2d2bcb7 (patch)
treed797b7612c9dc0248d740e301d64d8e76e36ec92 /po4a
parentb964365dad39ddbb8a48662b041f5cfb12c0af9c (diff)
i18n: po4a: Introduce machinery
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Diffstat (limited to 'po4a')
-rw-r--r--po4a/.gitignore5
-rw-r--r--po4a/Makefile131
-rwxr-xr-xpo4a/install-documents27
-rwxr-xr-xpo4a/list-documents45
4 files changed, 208 insertions, 0 deletions
diff --git a/po4a/.gitignore b/po4a/.gitignore
new file mode 100644
index 0000000..e640b7e
--- /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 0000000..3a3310d
--- /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 <http://www.gnu.org/licenses/>.
+
+# ----- 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 0000000..138c88e
--- /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 0000000..ca17ec5
--- /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 <<END
+[po4a_langs] $langs
+# ^ add your language here (separate with spaces)
+
+# Do not edit the rest of this file. It is automatically maintained.
+[options] opt:"-MUTF-8" opt:"-k50"
+[po4a_paths] \$master.pot \$lang:\$master.\$lang.po
+END
+
+for manpage in $(cd .. && env -u MAKELEVEL -u MAKEFLAGS make list-manpages); do
+ manpage_done=false
+
+ try_manpage () {
+ if $manpage_done; then return; fi
+
+ type=$1; ext=$2
+
+ src=../$manpage$ext
+ if ! [ -f $src ]; then return; fi
+
+ section=${manpage##*.}
+ base=${manpage%.*}
+ page=$base.$section
+
+ cat <<END
+[type: $type] $src \$lang:translated/man/\$lang/man$section/$page$ext master:file=${base}_${section}
+END
+
+ manpage_done=true
+ }
+
+ try_manpage pod .pod
+ try_manpage man ''
+ $manpage_done || fail "no source for $manpage"
+done