aboutsummaryrefslogtreecommitdiffhomepage
path: root/org/translation_po4a.org
diff options
context:
space:
mode:
Diffstat (limited to 'org/translation_po4a.org')
-rw-r--r--org/translation_po4a.org178
1 files changed, 178 insertions, 0 deletions
diff --git a/org/translation_po4a.org b/org/translation_po4a.org
new file mode 100644
index 0000000..27c3362
--- /dev/null
+++ b/org/translation_po4a.org
@@ -0,0 +1,178 @@
+-*- mode: org -*-
+#+TITLE: sisudoc spine (doc_reform) object-centric document abstraction
+#+DESCRIPTION: documents - structuring, publishing in multiple formats & search
+#+SUMMARY: process markup document, create document abstraction
+#+FILETAGS: :spine:abstraction:
+#+AUTHOR: Ralph Amissah
+#+EMAIL: [[mailto:ralph.amissah@gmail.com][ralph.amissah@gmail.com]]
+#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah
+#+LANGUAGE: en
+#+STARTUP: content hideblocks hidestars noindent entitiespretty
+#+PROPERTY: header-args+ :eval never-export :exports code
+#+PROPERTY: header-args+ :noweb yes :padline no
+#+PROPERTY: header-args+ :results silent :cache no
+#+PROPERTY: header-args+ :mkdirp yes
+#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t
+- magic single double-quote → " ← FIX changes hilighting behavior (occuring
+ after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX
+
+- [[./doc-reform.org][doc-reform.org]] [[./][org/]]
+
+* (translation) po4a setup
+
+#+HEADER: :tangle "../src/sisudoc/outputs/io_out/po4a_cfg.d"
+#+HEADER: :noweb yes
+#+BEGIN_SRC d
+<<doc_header_including_copyright_and_license>>
+/++
+ module po4a_cfg;<BR>
+ - the po4a configuration for a document, generated from its manifest and
+ the files its markup names<BR>
+ - written for tools/po4a/po4a.cfg, so its paths are relative to there
++/
+module sisudoc.outputs.io_out.po4a_cfg;
+@system:
+/+ ↓ po4a's configuration, derived rather than kept
+
+ The sample this replaces kept a Makefile that built po4a.cfg by globbing
+ a language directory and listing what it found. Spine already knows both
+ halves without looking: the manifest says which languages a document
+ has, and the markup says which files it is made of, through the << lines
+ the parser follows. Deriving the configuration from those two means it
+ cannot disagree with the document, which a hand-kept file eventually
+ does: a language added to the manifest and forgotten in the Makefile
+ produces a translation nobody updates.
+ .
+ It is derived, so it is not kept in git. The sample repository's
+ whitelist admits pot/ and po/ and not this.
+ .
+ neverwrap is deliberately NOT set, and the reason is worth keeping.
+ .
+ Without it po4a rewraps its output at about 75 columns, so a document
+ whose markup keeps one paragraph on one long line comes back reflowed.
+ That is untidy: it changes no object, since sisu delimits on blank
+ lines, but it churns every translated file in a diff and leaves the
+ source language and its translations formatted unlike each other. The
+ obvious thing is to turn wrapping off.
+ .
+ Measured on live-manual, same catalogues and same English, the option
+ the only difference:
+ .
+ fuzzy before with neverwrap without
+ ca 1 889 5
+ de 8 103 10
+ it 149 804 152
+ .
+ of 1126 strings. po4a will not use a fuzzy translation, so each one
+ renders as the source language: Catalan's coverage would fall from about
+ 46% to about 12%, and Spanish, French and Japanese with it. Setting the
+ option re-extracts the strings in a form the existing catalogues do not
+ match, and four fifths of nine languages' work stops being used.
+ .
+ Tidy formatting is not worth that. The wrapping stays.
++/
+template spinePo4aConfig() {
+ string po4aConfig(M)(M doc_matters) {
+ import std.algorithm : sort;
+ import std.array : array, join;
+ import std.conv : to;
+ import std.file : exists;
+ import std.path : baseName;
+ string _src_lang = doc_matters.src.language;
+ /+ ↓ the languages po4a is to produce, which is every language the
+ manifest lists except the one being translated from
+ +/
+ string[] _targets;
+ foreach (_lang; doc_matters.pod.manifest_list_of_languages) {
+ if (_lang != _src_lang) {
+ _targets ~= _lang;
+ }
+ }
+ /+ ↓ the files the document is made of: its master, and every insert the
+ markup names. In manifest order rather than directory order, so the
+ configuration is the same however a filesystem chooses to list a
+ directory.
+ +/
+ string[] _files;
+ _files ~= doc_matters.src.filename;
+ string[] _inserts;
+ foreach (_insert; doc_matters.srcs.file_insert_list) {
+ _inserts ~= _insert.baseName;
+ }
+ _inserts = _inserts.sort.array;
+ _files ~= _inserts;
+ /+ ↓ paths are relative to tools/po4a/, where this file belongs +/
+ enum string _to_text = "../../media/text";
+ string _o;
+ _o ~= "# po4a configuration for " ~ doc_matters.src.filename_base ~ "\n";
+ _o ~= "# generated by spine from pod.manifest and the markup; not kept in git\n";
+ _o ~= "# run from the directory this file is in\n";
+ _o ~= "\n";
+ /+ ↓ --keep 0 is not optional here, it is the difference between
+ regenerating a document and destroying it.
+ .
+ po4a will not write a translated file that falls below a
+ completeness threshold, and that threshold defaults to 80%. A
+ partially translated document is the normal state of one being
+ worked on, and sisu's own behaviour covers it: an untranslated
+ string falls back to the source text, so a file at 3% is mostly the
+ source language and entirely readable. (Measured on live-manual at
+ the default: 181 of its 189 translated files would be discarded, and
+ nine languages would collapse to eight surviving files. It would not
+ look like a failure either, because what remains reads as the
+ document reverting to its source language.)
+ .
+ The Makefile this replaces passed --keep 0 for exactly this reason.
+ +/
+ _o ~= "[options] --keep 0 --package-name " ~ doc_matters.src.filename_base ~ "\n";
+ _o ~= "\n";
+ _o ~= "[po4a_langs] " ~ _targets.join(" ") ~ "\n";
+ _o ~= "[po4a_paths] pot/$master.pot $lang:po/$lang/$master.po\n";
+ _o ~= "\n";
+ foreach (_f; _files) {
+ _o ~= "[type: text] " ~ _to_text ~ "/" ~ _src_lang ~ "/" ~ _f
+ ~ " $lang:" ~ _to_text ~ "/$lang/" ~ _f ~ "\n";
+ }
+ /+ ↓ index.html.in is not markup and no << line names it, so it is found
+ by asking whether the source language has one. live-manual does, the
+ Makefile it replaces carried it as xhtml, and the sample
+ repository's whitelist admits index.html.in.pot and .po by name.
+ Left out, regenerating would quietly drop those catalogue entries.
+ +/
+ string _index_in = doc_matters.pod.manifest_path
+ ~ "/media/text/" ~ _src_lang ~ "/index.html.in";
+ if (_index_in.exists) {
+ _o ~= "[type: xhtml] " ~ _to_text ~ "/" ~ _src_lang ~ "/index.html.in"
+ ~ " $lang:" ~ _to_text ~ "/$lang/index.html.in\n";
+ }
+ return _o;
+ }
+}
+#+END_SRC
+
+* org includes
+** project version
+
+#+NAME: spine_version
+#+HEADER: :noweb yes
+#+BEGIN_SRC emacs-lisp
+<<./sisudoc_spine_version_info_and_doc_header_including_copyright_and_license.org:spine_project_version()>>
+#+END_SRC
+
+** year
+
+#+NAME: year
+#+HEADER: :noweb yes
+#+BEGIN_SRC emacs-lisp
+<<./sisudoc_spine_version_info_and_doc_header_including_copyright_and_license.org:year()>>
+#+END_SRC
+
+** document header including copyright & license
+
+#+NAME: doc_header_including_copyright_and_license
+#+HEADER: :noweb yes
+#+BEGIN_SRC emacs-lisp
+<<./sisudoc_spine_version_info_and_doc_header_including_copyright_and_license.org:spine_doc_header_including_copyright_and_license()>>
+#+END_SRC
+
+* __END__