-*- 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 <> /++ module po4a_cfg;
- the po4a configuration for a document, generated from its manifest and the files its markup names
- 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__