Warning, /sdk/pology/doc/user/ascription.docbook is written in an unsupported language. File is not indexed.

0001 <?xml version="1.0" encoding="UTF-8"?>
0002 <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
0003  "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
0004 
0005 <chapter id="ch-ascript">
0006 <title>Ascribing Modifications and Reviews</title>
0007 
0008 <para>It may not be obvious, especially to new translators, to which extent the translation needs to be reviewed. If the translator has exercised due diligence, how "wrong" can the translation be? Even if the translator has good command of the source language -- typically English in context of PO files -- the answer is "very wrong", all aspects considered.</para>
0009 
0010 <para>With comparatively simple grammar of English, the meaning of a short English sentence (as typically encountered in program user interfaces) may vary much depend on the surrounding context. This context may not be obvious when the translator is going through isolated messages in the PO file, so he may commit the worst of errors from the reader's viewpoint: the senseless translation. An experienced reviewer will have developed sense for troublesome contexts, and will have at disposal several means to conclusively determine the context (including, for example, running the development version of the program).</para>
0011 
0012 <para>Even if the context is correctly established, the translator may use "wrong" terminology, which is the next worse thing for the reader. A term used in translation does not need to be wrong by itself, in fact it may be exactly the correct term -- in another translation project. The reviewer will have more experience with terminology of the present project, and be able to bring the translation in line with it.</para>
0013 
0014 <para>Style in the technical sense is a consistent choice between several perfectly valid constructs in target language when applied to text in the given technical context. For example, how to translate menu titles and items, button labels, or tooltips in user interface. Choices may include noun or verb forms, particular grammar categories, tone of address, and so on. There may be a style guide to the project which details such choices, and the reviewer will know it well.</para>
0015 
0016 <para>Style in the linguistic sense is especially applicable to longer texts, such as tooltips in user interface or paragraphs in documentation. A typical error of a new translator is to closely adhere to English style and grammar. This may produce translation which is semantically and grammatically valid in the target language, but very out of style. Reviewer then steps in to naturalize such constructs.</para>
0017 
0018 <para>Finally, while the reviewer may be an experienced translator, that does not mean that his own translations need no review. Immersion into the source language, distraction, and fatigue, will lead the reviewer into any of the above errors in translation, only with lesser frequency. This means that reviewers should also mutually review their own translations.</para>
0019 
0020 <para>This calls for a systematic approach to review in translation workflow.</para>
0021 
0022 <!-- ======================================== -->
0023 <sect1 id="sec-ascrevcomp">
0024 <title>Review Stages vs. Ascription</title>
0025 
0026 <para>Classical review workflow, <emphasis>by stages</emphasis>, seems simple enough. Translator translates a new PO file or updates an existing translation, and declares it ready to review. A reviewer reviews it, and declares it ready to commit into the pool from which PO files are periodically released. A committer finally commits the file. The process is iterative: the reviewer may return the file to the translator, and translator later again declare it as ready for review. There may be several stages of review (such as <emphasis>proof-reading</emphasis>, <emphasis>approving</emphasis>), each of which may return the translation to a previous stage, or forward it to some special stage. The process may also be implemented on the subfile level, where each PO message can go through stages separately.</para>
0027 
0028 <para>Regardless of the technical details, review workflows of this kind all have the following in common. Members of the translation team are assigned <emphasis>roles</emphasis> (such as <emphasis>translator</emphasis>, <emphasis>reviewer</emphasis>, <emphasis>committer</emphasis>) by which they step into the workflow. A single person can have more roles. Later review stages must wait for the earlier stages to complete, and the translation cannot be updated again before the current version clears the review pipeline (or the pipeline is aborted). Once the translation is committed, it becomes a part of simply "admitted" translations, with no further qualifiers.</para>
0029 
0030 <para>The system of prescribed roles requires that team members assign the roles between themselves, stick to them, and shuffle them along the way. The prescribed review pipeline requires a tool to keep track of the current review stage of translation. This makes the review workflow rigid, with probable bottlenecks. Distribution of roles may become disbalanced by people coming into and leaving the team, or the tracking tool may be prohibitive to some scenarios (e.g. single translator making small adjustments in dozens of files across the project, but having to upload each manually through a web interface).</para>
0031 
0032 <para>"Rigid" and "inefficient" are comparative qualifications, so what is it that review by stages can be compared to in this way?</para>
0033 
0034 <para>Review <emphasis>by ascriptions</emphasis> is even simpler conceptually, and yet less rigid and more efficient than the review by stages. It obligatory works on the PO message level, rather than PO file level. Anyone can simply translate some PO messages and directly commit modified PO files, without any review, but <emphasis>ascribing</emphasis> modifications to own name. Anyone can review any PO message at any moment, commit modifications made during the review, and ascribe the review to own name (and possibly to a certain class -- review of context, of terminology, style, etc). When the time comes to release the translation, <emphasis>insufficiently</emphasis> reviewed messages are automatically omitted, by evaluating the <emphasis>ascription history</emphasis> of each message.</para>
0035 
0036 <para>Based on the ascription history, the reviewer can select a subset of PO messages, and review only the difference between their historical and current versions. For example, Alice can select to review only messages modified since she or Bob had last reviewed them for style. She could see the difference from that last review to current version, e.g. if in the whole paragraph only a single word was changed by Charlie when he reviewed the terminology. Ascription history also propagate through merging of PO files with templates, so the reviewer can compare the change in original to the change in translation since the last review and judge if one fits the other.</para>
0037 
0038 <para>Since everyone just commits, translations can be efficiently kept in a version control repository, with the ascription system added on top. After having done some translating, the translator simply substitutes commit command of the version control system (VCS) with "ascribe modifications" command of the ascription system (AS, which calls the underlying VCS internally). After reviewing, the reviewer uses "ascribe reviews" command of the AS to commit reviews to ascription history (as well as any modifications made during the review). To select messages for review, the reviewer issues "diff for review" command of the AS, with suitable parameters to narrow the message set; selected messages are marked in-place in PO files and equipped with <link linkend="ch-diffpatch">embedded differences</link>, and possibly directly opened in a PO editor.</para>
0039 
0040 <para id="p-asrel">When the translations are to be released, the release person issues "filter for release" command of the AS, which takes the working PO files and creates final PO files, in which the insufficiently reviewed messages are removed. Here "release time" can be understood figuratively: since filtering for release should be a fully automatic process, it can be performed at any interval of convenience.</para>
0041 
0042 <para>What constitutes "sufficient review" can be defined in fine detail. It could be specified that messages modified by Alice need to have only review for terminology, but not necessarily for style; Charlie may belong to the group which needs to be reviewed on style, but not necessarily on context; Bob's reviews for style may be nice to have, but never blocking the release if missing. These decisions do not preclude released messages to be reviewed later on missing points, after higher priority reviews have been completed. The definition of sufficiency may be changed at any point, e.g. as team members get more experienced and require less review, without interfering with direct translation and review activities.</para>
0043 
0044 <para>In summary, an AS preserves the operational efficiency of VCS, while at the same time providing great flexibility of review. All team members can be given commit access, no web or email detours are needed. There are no prescribed roles, but a functional equivalent of role assignment happens at the last possible moment (release time), can take into account both translators' and reviewers' abilities, and changing estimates of those over time. There is no staging between completing and committing the translation, which enables a translator to continue polishing the translation undisturbed until a reviewer comes around. There are no bottlenecks when performing small changes in many files, since a single AS command commits all changes just as a single VCS command would. On commit operations, the AS can also apply various checks (e.g. decline to commit syntactically invalid PO files) and modifications (e.g. update translator's data in the PO header).</para>
0045 
0046 </sect1>
0047 
0048 <!-- ======================================== -->
0049 <sect1 id="sec-ascsetup">
0050 <title>Setting up Ascription with <command>poascribe</command></title>
0051 
0052 <para>Pology provides an ascription system in the form of the <command>poascribe</command> command.</para>
0053 
0054 <para>Let the organization of PO files for the language <literal>nn</literal> in the version control repository be such:
0055 <programlisting>
0056 l10n-nn/
0057     po/
0058         ui/
0059             alpha.po
0060             bravo.po
0061             ...
0062         doc/
0063             alpha.po
0064             bravo.po
0065             ...
0066         ...
0067 </programlisting>
0068 Having PO files grouped by language can be taken as a hard prerequisite<footnote>
0069 <para><emphasis>Technically</emphasis>, PO files could also be grouped by PO domain:
0070 <programlisting>
0071 po/
0072     ui/
0073         alpha/
0074             ...
0075             nn.po
0076             mm.po
0077             ...
0078 </programlisting>
0079 but this would lead to a host of strange sharings of ascription settings and auxiliary file locations between different languages. In general, it is assumed that each translation team manages its own separate ascription.</para>
0080 </footnote>. Also necessary is a single top subdirectory for the whole PO file tree (here <filename>po/</filename>), rather than having several PO subdirectories directly in the language directory.</para>
0081 
0082 <para>Setting up ascription is now simple. Create the ascription configuration file named exactly <filename>ascription-config</filename> (<command>poascribe</command> expects this name), on the same level as the top PO directory:
0083 <programlisting>
0084 l10n-nn/
0085     ascription-config
0086     po/
0087         ui/
0088             ...
0089         doc/
0090             ...
0091 </programlisting>
0092 and set in it a few global configuration fields, and data for each known translator:
0093 <programlisting language="ini">
0094 # ---------------------------
0095 # Global ascription settings.
0096 
0097 [global]
0098 
0099 # Roots of the original and ascription trees.
0100 catalog-root = po
0101 ascript-root = po-ascript
0102 
0103 # The underlying version control system.
0104 version-control = svn
0105 
0106 # Data for updating PO headers on request.
0107 language = nn
0108 language-team = Nevernissian
0109 team-email = l10n-nn@neverwhere.org
0110 
0111 # Default commit message.
0112 commit-message = Translation updates.
0113 
0114 # -----------------------
0115 # Registered translators.
0116 
0117 [user-alice]
0118 name = Alice Akmalryn
0119 original-name = Алиса Акмалрин
0120 email = alice.akmalryn@someplacenice.org
0121 
0122 [user-bob]
0123 name = Bob Bromkin
0124 original-name = Бобан Бромкин
0125 email = bob.byomkin@otherplacenice.org
0126 
0127 # ...and so on.
0128 </programlisting>
0129 The configuration fields used in this example, and other possible configuration fields, are listed and described below.</para>
0130 
0131 <para>Global settings in the configuration file:
0132 <variablelist>
0133 
0134 <varlistentry>
0135 <term><literal>catalog-root</literal></term>
0136 <listitem>
0137 <para>The path to top PO subdirectory. This should be a relative path, and relative to the location of the configuration file.</para>
0138 </listitem>
0139 </varlistentry>
0140 
0141 <varlistentry>
0142 <term><literal>ascript-root</literal></term>
0143 <listitem>
0144 <para>Relative path to the top directory of <link linkend="p-ascftree">the ascription file tree</link>, which will be created and updated by <command>poascribe</command>.</para>
0145 </listitem>
0146 </varlistentry>
0147 
0148 <varlistentry>
0149 <term><literal>version-control</literal></term>
0150 <listitem>
0151 <para>The underlying version control system of the repository. The value is a keyword, see <xref linkend="sec-cmsuppvcs"/> for a list of VCS supported by Pology.</para>
0152 </listitem>
0153 </varlistentry>
0154 
0155 <varlistentry>
0156 <term><literal>language</literal></term> <term><literal>language-team</literal></term> <term><literal>team-email</literal></term> <term><literal>plural-header</literal></term>
0157 <listitem>
0158 <para>These fields provide information about the language and the translation team, which <command>poascribe</command> uses to update header fields in modified PO files. <literal>language</literal> is the language code, while <literal>language-team</literal> is usually just the human-readable language name in English. <literal>plural-header</literal> is the exact contents of <literal>Plural-Forms:</literal> PO header field (if it contains a <literal>%</literal> character, you need to escape it as <literal>%%</literal>). For any of these fields that is not set, <command>poascribe</command> will remove the corresponding header field when updating the PO header.</para>
0159 </listitem>
0160 </varlistentry>
0161 
0162 <varlistentry>
0163 <term><literal>title</literal></term>
0164 <listitem>
0165 <para>The first comment line in the PO header, set when <command>poascribe</command> updates the header. It can contain the following placeholders for inserting file-dependent information: <literal>%basename</literal> is the base PO file name (e.g. <literal>alpha.po</literal>), <literal>%poname</literal> the PO domain name (e.g. <literal>alpha</literal>), <literal>%langname</literal> the human-readable language name (supplied by the <literal>language-team</literal> field), and <literal>%langcode</literal> the language code (supplied by the <literal>language</literal> field). Note that these placeholders actually must be written as <literal>%%<replaceable>name</replaceable></literal>, to escape the special meaning of single <literal>%</literal> character. If <literal>title</literal> field is not set, <command>poascribe</command> will leave the title comment as it is in the PO file.</para>
0166 </listitem>
0167 </varlistentry>
0168 
0169 <varlistentry>
0170 <term><literal>commit-message</literal></term>
0171 <listitem>
0172 <para>The default commit message for the underlying VCS, when <command>poascribe</command> calls upon it to commit modified PO files. If this field is not set, an editor window will pop up to input the commit message, or the <option>-m</option>/<option>--message</option> option can be used to set the message through the command line. If the field is set, <option>-m</option> can still be used to override the default commit message.</para>
0173 </listitem>
0174 </varlistentry>
0175 
0176 <varlistentry>
0177 <term><literal>review-tags</literal></term>
0178 <listitem>
0179 <para>The set of accepted <link linkend="sec-ascfgrev">review tags</link>, given as whitespace-separated list of tags. If set, <command>poascribe</command> will abort when trying to use an unknown tag, otherwise it will accept any tag.</para>
0180 </listitem>
0181 </varlistentry>
0182 
0183 </variablelist>
0184 </para>
0185 
0186 <para>Each known translator is represented by a <literal>[user-<replaceable>name</replaceable>]</literal> configuration section. Translator's user name in the ascription system has no direct relation with the underlying VCS account name (if VCS uses them), but it makes sense for them to be equal. This also means that a translator does not even have to have VCS account (repository commit access), though this is expected for the sake of efficiency. Translator configuration sections can contain the following fields:
0187 <variablelist>
0188 
0189 <varlistentry>
0190 <term><literal>name</literal></term>
0191 <listitem>
0192 <para>Translator's name, in the form supposed to be readable in English. This means that if the name is not originally written in Latin script, some romanized form should be given.</para>
0193 </listitem>
0194 </varlistentry>
0195 
0196 <varlistentry>
0197 <term><literal>original-name</literal></term>
0198 <listitem>
0199 <para>Translator's name in its original form, if it differs from the romanized form given by the <literal>name</literal> field.</para>
0200 </listitem>
0201 </varlistentry>
0202 
0203 <varlistentry>
0204 <term><literal>email</literal></term>
0205 <listitem>
0206 <para>The email address at which the translator may be contacted.</para>
0207 </listitem>
0208 </varlistentry>
0209 
0210 </variablelist>
0211 </para>
0212 
0213 <para>As soon as <filename>ascription-config</filename> file is committed to the repository, the ascription system through <command>poascribe</command> is ready for use. The only expected regular modifications to the configuration file are those of adding new translators. On the other hand, translators should never be removed, because even after they go away, their ascription records remain in the system.</para>
0214 
0215 <sect2 id="sec-ascinit">
0216 <title>Initial Ascription</title>
0217 
0218 <para>The most common situation at the start of ascription workflow is that there already exists a considerable amount of translations, contributed by many different people over time. These existing translations should be ascribed as initial modifications -- but ascribed to whom? If it is not precisely known who translated what, the solution is to introduce a generic user in the configuration file, appropriately named "Unknown Hero" (or "Lost Translator", you can be inventive):
0219 <programlisting language="ini">
0220 [user-uhero]
0221 name = Unknown Hero
0222 original-name = Незнани јунак
0223 </programlisting>
0224 You should then ascribe all existing translations as modified and reviewed by this dummy translator:
0225 <programlisting language="bash">
0226 $ cd $LANGDIR
0227 $ poascribe commit -u uhero --all-reviewed -C  po/
0228 </programlisting>
0229 The <literal>commit</literal> argument is the ascription mode, and the <option>-u</option> option provides the user name to which ascriptions are made. This is an important point: ascriptions are made to a user defined in ascription configuration, and have nothing to do with VCS itself. It is the <option>--all-reviewed</option> option that declares all messages to be reviewed as well (this option is normally used only this once, and not in day to day operation). The <option>-C</option> option prevents automatic VCS adding and committing, which is useful for this initial step.</para>
0230 
0231 <para>When this command line is executed, a progress bar will appear and the following output will start to unfold:
0232 <programlisting>
0233 doc/alpha.po  (43/43)
0234 doc/bravo.po  (81/81)
0235 ...
0236 ui/alpha.po  (582/582)
0237 ui/bravo.po  (931/931)
0238 ...
0239 ===== Ascription summary:
0240 -           modified  reviewed
0241 translated     11775     11775
0242 fuzzy           2943      2943
0243 obsolete/t       365       365
0244 obsolete/f        26        26
0245 </programlisting>
0246 The number in parenthesis indicates how many messages have been ascribed in the given PO file (modified/reviewed), and at the end the totals are given.</para>
0247 
0248 <para>If, on the contrary, it is known who translated and reviewed what up to that point, ascription can be performed piece-wise with user names of real translators:
0249 <programlisting language="bash">
0250 $ cd $LANGDIR
0251 $ poascribe commit -u alice --all-reviewed -C  po/ui/
0252 $ poascribe commit -u bob --all-reviewed -C  po/doc/
0253 $ ...
0254 </programlisting>
0255 </para>
0256 
0257 <para id="p-ascftree">After the initial ascription has been made, the <emphasis>ascription file tree</emphasis> will appear next to the original file tree. There will be one ascription PO file for each summit PO file, with the same name and relative location within the tree:
0258 <programlisting>
0259 l10n-nn/
0260     po/
0261         ui/
0262             alpha.po
0263             bravo.po
0264             ...
0265         ...
0266     po-ascript/
0267         ui/
0268             alpha.po
0269             bravo.po
0270             ...
0271         ...
0272 </programlisting>
0273 Ascription PO files are used by <command>poascribe</command> to store the ascription history, rather than e.g. a database of some sort. This has the disadvantage in performance, but advantage in simplicity and robustness. For example, ascription files will be under version control as well.</para>
0274 
0275 <para><command>poascribe</command> may also modify original PO files during this run, by removing any previous field comments (<literal>#| ...</literal>) on translated messages. These comments are sometimes erroneously left in when the PO file is translated with an older or less capable PO editor, and leaving them would result in unnecessary additions to ascription PO files.</para>
0276 
0277 <para>The newly created ascription tree, any modifications to the original tree, and the ascription configuration file, can now be committed as usual. With Subversion as the VCS:
0278 <programlisting language="bash">
0279 $ cd $LANGDIR
0280 $ svn add ascription-config po-ascript
0281 $ svn commit ascription-config po po-ascript -m "Initial ascription."
0282 </programlisting>
0283 </para>
0284 
0285 </sect2>
0286 
0287 </sect1>
0288 
0289 <!-- ======================================== -->
0290 <sect1 id="sec-ascdailytr">
0291 <title>Daily Use for Translators</title>
0292 
0293 <para>While this is generally a good idea, with ascription in place translators must always update the complete language directory by VCS, rather than just one particular PO file or subdirectory, so that the original and the ascription PO file trees are kept in sync.<footnote>
0294 <para>There should be no technical problem here, since VCS updates are inexpensive in terms of network traffic, but there may be a problem of changing one's habits.</para>
0295 </footnote></para>
0296 
0297 <para>In order not to have to report their user name to <command>poascribe</command> all the time (by the <option>-u</option> option), translators can set it in <link linkend="sec-cmconfig">Pology user configuration</link>, the <literal>[poascribe]</literal> section:
0298 <programlisting language="ini">
0299 [poascribe]
0300 user = alice
0301 </programlisting>
0302 With this in place, translators can submit updated PO files simply by substituting VCS commit command with <literal>poascribe commit</literal> (or shortened: <literal>co</literal> or <literal>ci</literal>). With Subversion, this would look like:
0303 <programlisting language="bash">
0304 $ cd $LANGDIR
0305 $ poascribe co po/ui/*alpha*.po
0306 po/ui/alpha.po  (44)
0307 po/ui/libalpha.po  (15)
0308 ===== Ascription summary:
0309 -           modified
0310 translated       169
0311 >>>>> VCS is committing catalogs:
0312 Sending      ui/alpha.po
0313 Sending      ui/libalpha.po
0314 Sending      summit-ascript/messages/kdefoo/fooapp.po
0315 Sending      LANG/summit-ascript/messages/kdefoo/libfooapp.po
0316 Transmitting file data ....
0317 Committed revision 1267069.
0318 $ 
0319 </programlisting>
0320 The lines after <literal>>>>>> VCS...</literal> are produce by the underlying VCS, which is Subversion in this example.<footnote>
0321 <para>If the underlying VCS would a distributed one, such Git, and the push to a designated central repository is expected afterward, it must be performed manually.</para>
0322 </footnote></para>
0323 
0324 <para>As can be seen from the example output, <command>poascribe</command> will add ascription records into ascription PO files corresponding to original PO files, and commit them all. Like a VCS command, <command>poascribe co</command> can take any number of PO file or directory paths. For a directory path, only files with <filename>.po</filename> extension in it will be processed, and any other ignored. <command>poascribe</command> can be run from any working directory with appropriate paths as arguments, and it will always find the associated ascription configuration and files. If a default commit message has not been set in the ascription configuration, <command>poascribe</command> will ask for it; or it can be given in command line through <option>-m</option> option.</para>
0325 
0326 <sect2 id="sec-asctrnocomm">
0327 <title>Translators Without Commit Access</title>
0328 
0329 <para>With the ascription system in place, every regular translator should have the commit access to the repository. But, there may be some period of time before new translators are given commit access, or revision control may be too technical for some, and even those who have access may not be able to commit temporarily for some reason.</para>
0330 
0331 <para>These translators may send in their work by email or any other informal channel, to <emphasis>any</emphasis> member of the team how does have commit access. This team member can then commit received files without any review, as review can be conducted at any later time. If Bob sends some files to Alice, she can commit them immediately by stating Bob's user name:
0332 <programlisting language="bash">
0333 $ poascribe co -u bob <replaceable>files...</replaceable>
0334 </programlisting>
0335 For this to work, the translator who sent in the files has to be defined in the ascription configuration. There are no hidden costs or security issues to this (as opposed to giving VCS commit access), so every new translator should be defined there before any work of that person is committed.</para>
0336 
0337 </sect2>
0338 
0339 </sect1>
0340 
0341 <!-- ======================================== -->
0342 <sect1 id="sec-ascdailyrev">
0343 <title>Daily Use for Reviewers</title>
0344 
0345 <para>An ascription system opens up all sorts of possibilities for review patterns. Reviewers should keep in mind that for each message the full modification and review history is available, so that the translation team can think about how to make good use of it. What follows are some examples to illustrate the review functionality provided by <command>poascribe</command>.</para>
0346 
0347 <sect2 id="sec-ascbaserev">
0348 <title>Basic Reviewing</title>
0349 
0350 <para>At the very basic level (which is the only level in <link linkend="sec-ascrevcomp">review by stages</link>), messages can be classified as simply unreviewed or reviewed. Alice now wants to review all unreviewed messages in a subset of PO files, say the <filename>ui/</filename> subdirectory. She issues the following command (<literal>di</literal> is short for <literal>diff</literal>):
0351 <programlisting language="bash">
0352 $ poascribe di po/ui/
0353 po/ui/alpha.po  (2)
0354 po/ui/foxtrot.po  (7)
0355 po/ui/november.po  (12)
0356 ===== Diffed for review: 21
0357 $ 
0358 </programlisting>
0359 With this, all unreviewed messages in listed PO files have been marked, and <emphasis>diffed</emphasis>. If these PO files had already been reviewed before, some of the messages modified since then (those now marked for review) may have changed very little. For example, a few changed words in a paragraph-length message, or even just some punctuation. Therefore, for each message marked for review, Alice also wants to see the difference since the last review to current version. Here are two messages with typical review elements added by <literal>poascribe di</literal>:
0360 <programlisting language="po">
0361 #. ~ascto: charlie:m
0362 #: gui/mainwindow.cc:372
0363 #, ediff
0364 msgid "GAME OVER. {-You won-}{+Tie+}!"
0365 msgstr "KRAJ IGRE. {-Pobeda-}{+Nerešeno+}!"
0366 
0367 #. ~ascto: bob:m charlie:m
0368 #: game-state.cpp:117
0369 #, ediff-total
0370 msgid "Click the pause button again to resume the game."
0371 msgstr "Kliknite ponovo na dugme pauze da nastavite igru."
0372 </programlisting>
0373 </para>
0374 
0375 <para>In the first message, the first thing to note is the <literal>#. ~ascto:</literal> comment. This comment succinctly lists who did what with the message since the last review; here <literal>charlie:m</literal> means that Charlie is the one who modified it. Then there is the <literal>ediff</literal> flag, which Alice can search for in the editor to jump through messages marked for review. Finally, the original and translation have been diffed; here they show that, since the last review, the message was fuzzied by changing "You won" to "Tie", and what Charlie did in translation to unfuzzy it. Even on a message as short as this, the difference tells something useful to Alice: the phrase "Game over" likely has a formulaic translation, and the fact that it is not part of the difference means that the earlier reviewer had made sure it is consistent, so Alice does not have to check that.</para>
0376 
0377 <para>The <literal>#. ~ascto:</literal> comment of the second message reveals that both Charlie and Bob had been modifying it. The <literal>ediff-total</literal> flag instead of plain <literal>ediff</literal> means that this message had no reviews until now, so there are no embedded differences in text fields.</para>
0378 
0379 <para>Alice can now go through marked messages in listed PO files, review translations, and possibly make modifications. When making changes in a message with embedded differences, she can freely edit the text outside of difference segments and within <literal>{+...+}</literal> segments (as these are the ones which belong to current version of the text). While reviewing, Alice does <emphasis>not</emphasis> remove any of the added message elements (except for an occasional difference segment, if she modifies a translation), as these elements are needed for a subsequent invocation of <command>poascribe</command>. If a message is particularly hard to translate and Alice wants to defer reviewing it for some later time, she can add to it the <literal>unreviewed</literal> flag (or <literal>nrev</literal> for short).</para>
0380 
0381 <para>Once the review is complete, Alice simply commits the reviewed files:
0382 <programlisting language="bash">
0383 $ poascribe co po/ui/
0384 po/ui/alpha.po  (0/2)
0385 po/ui/foxtrot.po  (0/7)
0386 po/ui/november.po  (3/12)
0387 ===== Ascription summary:
0388 -           modified  reviewed
0389 translated         3        21
0390 >>>>> VCS is committing catalogs:
0391 Sending      po/ui/november.po
0392 Sending      po-ascript/ui/alpha.po
0393 Sending      po-ascript/ui/foxtrot.po
0394 Sending      po-ascript/ui/november.po
0395 Transmitting file data ....
0396 Committed revision 1284220.
0397 $ 
0398 </programlisting>
0399 Three things have happened here. First, all review states (flags, embedded differences, etc.) have been removed, restoring diffed PO files to original state. Then, any modifications that Alice has made during review are ascribed to her (here 3 out of 21 messages). Finally, all marked messages are ascribed as reviewed by Alice (any with <literal>unreviewed</literal> or <literal>nrev</literal> flags would have been omitted here). When committing, the only original PO file that got committed is the one with modifications made during review, and all the ascription PO files were committed because of the reviews recorded in them.</para>
0400 
0401 <para>When many PO files with few changes per file should be reviewed, it becomes burdensome to manually open each and every diffed file for review, and then to make sure that all are committed with <command>poascribe co</command>. To make this easier, <literal>-w toreview.out</literal> option can be added to the <literal>poascribe di</literal> command line, which requests that paths of all diffed PO files be written into <filename>toreview.out</filename> file. This file can then be used to batch-open diffed PO files in an editor, as well as to commit them later by adding <literal>-f toreview.out</literal> to <literal>poascribe co</literal>. There is also <option>-o</option> option, which tells <command>poascribe</command> to directly open PO files in one of the supported PO editors (see <xref linkend="sec-cmsupped"/>). Putting it together, to efficiently review a whole bunch of small changes throughout many PO files, with Lokalize as the PO editor, you can execute:
0402 <programlisting language="bash">
0403 $ poascribe di <replaceable>paths...</replaceable> -w toreview.out -o lokalize
0404 $ # ...only marked messages opened in Lokalize, review them...
0405 $ poascribe co -f toreview.out
0406 </programlisting>
0407 </para>
0408 
0409 <para>If for whatever reason you want to simply remove the review elements from messages without committing the PO files (effectively discarding the review), you can use the <literal>purge</literal> mode (short <literal>pu</literal>) of <command>poascribe</command>:
0410 <programlisting language="bash">
0411 $ poascribe pu <replaceable>paths...</replaceable>
0412 </programlisting>
0413 If <option>-k</option>/<option>--keep-flags</option> option is added to this command line, the flags which mark the messages as reviewed get preserved; more precisely, every <literal>ediff*</literal> flag is replaced with <literal>reviewed</literal> flag, and every <literal>unreviewed</literal> flag is left in, so that subsequent invocation of <literal>poascribe co</literal> can record reviews. You will want this limited purging if you have some automatic validation tools to run before committing, and these tools would be thrown off by review elements (most likely by embedded differences).</para>
0414 
0415 </sect2>
0416 
0417 <sect2 id="sec-ascselrev">
0418 <title>Selecting Messages for Review</title>
0419 
0420 <para>Invocations of <command>poascribe di</command> without any options, as in the previous section, are equivalent to this:
0421 <programlisting language="bash">
0422 $ poascribe di -s modar <replaceable>paths...</replaceable>
0423 </programlisting>
0424 The <option>-s</option> option serves to issue a message <emphasis>selector</emphasis>. <literal>modar</literal> is the default selector for the <literal>diff</literal> operation mode, and stands for "MODified-After-Review": it selects the earliest historical modification of the message after the last (or no) review of that message, if there is any such. By selecting a historical modification of the message, the difference from it to current version can be computed and embedded into the PO file, as seen in earlier examples.</para>
0425 
0426 <para id="p-seltypes">There are various specialized selectors, and they fall into two groups: <emphasis>shallow selectors</emphasis> and <emphasis>history selectors</emphasis>. Shallow selectors look only into the current version of the message, and cannot select historical versions, which means that they cannot provide embedded differences. History selectors (<literal>modar</literal> is of this type) can select messages from history and provide differences. Several selectors can be issued on the command line, and the message is selected only if all selectors select it (boolean AND-linking). Shallow selectors are thus normally used as a pre-filters for history selectors. For example, to select messages modified after the last review, but only those <link linkend="ch-summit">found in the stable branch</link>, <literal>branch</literal> and <literal>modar</literal> selectors are chained like this:
0427 <programlisting language="bash">
0428 $ poascribe di -s branch:stable -s modar <replaceable>paths...</replaceable>
0429 </programlisting>
0430 It is important that the history selector is given last, because the last selector determines which historical message is selected for diffing. If the ordering had been reversed in this example, same messages would get selected, but they would not have embedded differences, because <literal>branch</literal> is a shallow selector.</para>
0431 
0432 <para>Selectors can take parameters themselves, like <literal>branch:stable</literal> in the previous example. Parameters are separated from the selector name by any non-alphanumeric character; this is colon by convention, but if a parameter contains a colon, something else, like slash, tilde, etc. can be used. Number of parameters can vary, and <literal>modar</literal> in particular can take from none to three. If Alice wants to review only those messages modified <emphasis>by Charlie</emphasis> since the last review, she states this by first argument to <literal>modar</literal>:
0433 <programlisting language="bash">
0434 $ poascribe di -s modar:charlie <replaceable>paths...</replaceable>
0435 </programlisting>
0436 If Alice does not give much credit to other reviewers, she can request selection of messages modified after <emphasis>her own</emphasis> last review with second parameter to <literal>modar</literal>:
0437 <programlisting language="bash">
0438 $ poascribe di -s modar::alice <replaceable>paths...</replaceable>
0439 </programlisting>
0440 Here the first parameter ("modified by..."), which is not needed, must be explicitly skipped, before proceeding to the second parameter ("reviewed by..."). (The third optional parameter to <literal>modar</literal> will be demonstrated later on.)</para>
0441 
0442 <para>When a selector parameter is a user name, normally it can also be a comma-separated list of user names (<literal>modar:bob,charlie</literal>) or prefixed with tilde to negate, i.e. to select all users other than those listed (<literal>modar:~alice</literal>).</para>
0443 
0444 <para>Any selector can be negated by prepending <literal>n</literal> to its name. For example, the history selector <literal>modafter:<replaceable>date</replaceable></literal> selects first modification after the given date; to select messages modified after the last review, but only if modified during June 2010:
0445 <programlisting language="bash">
0446 $ poascribe di -s modafter:2010-06 -s nmodafter:2010-07 -s modar <replaceable>paths...</replaceable>
0447 </programlisting>
0448 Negating a history selector produces a shallow selector: while <literal>modafter</literal> is a history selector, <literal>nmodafter</literal> is shallow. But the mutual ordering of the two in this example is not important, since the last selector in the chain is the usual <literal>modar</literal>.</para>
0449 
0450 <para>Selectors can be issued in other modes too. If the PO file is big, and Alice has reviewed messages up to and including the message with entry number 246 when she has to pause until another day, she can commit reviews only up to this entry by issuing the <literal>espan</literal> selector:
0451 <programlisting language="bash">
0452 $ poascribe co -s espan::246 <replaceable>paths...</replaceable>
0453 </programlisting>
0454 The first parameter to <literal>espan</literal>, here omitted, would be the entry number of the first message to select, in case messages should not be selected starting from the first in the file. There is also the counterpart <literal>lspan</literal> selector, which works with referent line numbers (those of <varname>msgid</varname> keywords) instead of entry numbers.</para>
0455 
0456 <para>If you do not want to immediately diff for review, but to see first how many messages would be selected by the selector chain that you assembled, you can use the <literal>status</literal> operation mode (<literal>st</literal> for short) instead of <literal>diff</literal>. It takes selectors in the same way as <literal>diff</literal>, and shows counts of selected messages by category. You can also add the <option>-b</option> option to have counts reported by PO file (where non-zero).</para>
0457 
0458 <para>You may also want to observe the complete recorded ascription history of a message, all its modifications and reviews, with differences between each two modifications. For this you can use the <literal>history</literal> operation mode (<literal>hi</literal> for short), typically with one of <literal>l</literal> or <literal>e</literal> selectors to single out a particular message. The history will be written out to terminal, starting from the newest to the oldest version of the message, with highlighted embedded differences.</para>
0459 
0460 </sect2>
0461 
0462 <sect2 id="sec-ascfgrev">
0463 <title>Fine-Grained Reviews</title>
0464 
0465 <para>In the introduction of this chapter, several distinct things that can go wrong in translation were described. Not all reviewers may be able to check translation against all those problems. Here is a typical scenario of this kind:</para>
0466 
0467 <para>Alice is computer-savvy and knows the translation project inside and out, which means that she can review well for context, terminology, and technical style. But, her language style leaves something to be desired, which shows in longer sentences and passages. Dan, on the other hand, is a very literary person, but not that much into the technical aspects. Dan's style reviews would thus be a perfect complement to Alice's general reviews.</para>
0468 
0469 <para><command>poascribe</command> can support this scenario in the following way. A <emphasis>review type</emphasis> tag <literal>lstyle</literal> for language style is defined in the ascription configuration, using the <literal>review-tags</literal> field:
0470 <programlisting language="ini">
0471 [global]
0472 # ...
0473 review-tags = lstyle
0474 </programlisting>
0475 With this addition to configuration, Alice can continue to review as she did before, without any changes in her workflow.</para>
0476 
0477 <para>Dan selects messages for review similarly to Alice, but additionally giving the <literal>lstyle</literal> tag as the <emphasis>third</emphasis> parameter of <literal>modar</literal>, and indicating that reviews should be tagged as <literal>lstyle</literal> using the <option>-t</option> option:
0478 <programlisting language="bash">
0479 $ poascribe di -s modar:::lstyle -t lstyle <replaceable>paths...</replaceable>
0480 </programlisting>
0481 After finishing the review, Dan commits as usual:
0482 <programlisting language="bash">
0483 $ poascribe co PATHS...
0484 </programlisting>
0485 </para>
0486 
0487 <para>If Dan is always going to review the language style, in order not to have to issue the selector and the tag in command line all the time, he can make them default for the <literal>diff</literal> mode in Pology user configuration:
0488 <programlisting language="ini">
0489 [poascribe]
0490 user = dan
0491 selectors/diff = modar:::lstyle
0492 tags/diff = lstyle
0493 </programlisting>
0494 With this, Dan can use plain <literal>poascribe di</literal> just like Alice does.</para>
0495 
0496 <para>The important point of review tags is that they make reviews by types independent. For example, Dan may come around to review the language style of the given message after several modifications and general reviews have been ascribed to it -- <literal>modar:::lstyle</literal> will simply ignore all reviews other than <literal>lstyle</literal> reviews. This is going to be reflected in the <literal>~ascto:</literal> comment of diffed messages:
0497 <programlisting language="po">
0498 #...
0499 #. ~ascto: charlie:m alice:r bob:m
0500 #...
0501 msgid "..."
0502 msgstr "..."
0503 </programlisting>
0504 Here Alice has made one review between Charlie's and Bob's modifications, and that review, being general instead of <literal>lstyle</literal>, did not cause <literal>modar</literal> to stop at it. After Dan reviews this message for language style, Alice runs selection for review and gets this:
0505 <programlisting language="po">
0506 #...
0507 #. ascto: bob:m dan:r(lstyle)
0508 #...
0509 msgid "..."
0510 msgstr "..."
0511 </programlisting>
0512 Again, since <literal>lstyle</literal> reviews do not mix with general reviews<footnote>
0513 <para>General review too has a tag assigned, the empty string, in case the reviewer needs to explicitly issue it in some context.</para>
0514 </footnote>, Dan's review did not hide Bob's modification that Alice did not check so far.</para>
0515 
0516 </sect2>
0517 
0518 </sect1>
0519 
0520 <!-- ======================================== -->
0521 <sect1 id="sec-ascmaint">
0522 <title>General Maintenance Procedures</title>
0523 
0524 <para>After the ascription system is set up, there should be very little to do to maintain it. The details depend on the established translation workflow, and this section describes some of the procedures which may apply.</para>
0525 
0526 <sect2 id="sec-ascmerge">
0527 <title>Ascribing Merges</title>
0528 
0529 <para>If PO files are periodically merged with templates in a centralized manner, by one designated person or repository automation, these modifications must also be ascribed. This is done as any other ascription, by substituting the VCS commit command with <literal>poascribe co</literal>. For example:
0530 <programlisting language="bash">
0531 $ svn commit $LANGDIR -m "Everything merged."
0532 </programlisting>
0533 may be substituted with:
0534 <programlisting language="bash">
0535 $ poascribe commit $LANGDIR -m "Everything merged."
0536 </programlisting>
0537 Since the user is not explicitly given by the <option>-u</option> option, this will ascribe modifications due to merging to the person set in Pology user configuration on the system where the command is executed. This is just fine. It is also possible to define a dummy user to which modifications due to merging are ascribed, though there is no known advantage to that at present.</para>
0538 
0539 <para>Note that you can issue the <option>-C</option> option to prevent <command>poascribe</command> from automatically committing merged files, in case are some automatic post-merge operations that you would like to perform on merged PO files beforehand. Afterward, standalone VCS commit command can be issued, but do not forget to include the ascription file tree in it as well.</para>
0540 
0541 </sect2>
0542 
0543 <sect2 id="sec-ascshuffle">
0544 <title>Shuffling Ascription PO Files</title>
0545 
0546 <para>Sometimes PO files are "shuffled" in the repository: renamed, moved to another subdirectory, etc. Such shuffling should be exactly mirrored in the ascription tree:
0547 <itemizedlist>
0548 
0549 <listitem>
0550 <para>If a PO file is moved or renamed, its counterpart ascription PO file should also be moved or renamed in the same way within the ascription tree.</para>
0551 </listitem>
0552 
0553 <listitem>
0554 <para>If a PO file is split into two, then it depends on how you handle the splitting. A good way would be to copy the old PO file to two new names, and then merge them with new templates. In this way as much of existing translation as possible will be preserved. If this is done, then the ascription PO files should be copied to new names, but then there is nothing to merge them with. This is just right, since message ascription histories generally interleave across the split (but also see <xref linkend="sec-asctrim"/>).</para>
0555 </listitem>
0556 
0557 <listitem>
0558 <para>If two PO files are merged into one, you should probably handle that by using <command>msgcat</command> to properly concatenate them into the new PO file, and then merge the new PO file with its template. Then, the old ascription PO files should be concatenated with <command>msgcat</command> as well, and nothing more. But, <emphasis>make sure</emphasis> that you issue the <option>--use-first</option> to <command>msgcat</command>, for both concatenations. This is because when in the two concatenated PO files there are two messages with same <varname>msgctxt</varname>+<varname>msgid</varname> but different <varname>msgstr</varname>, <command>msgcat</command> will by default make a free-form composition of <varname>msgstr</varname> texts, for translator to manually disentangle later. This would ruin the ascription entry of such a message in the concatenated ascription PO file.</para>
0559 </listitem>
0560 
0561 </itemizedlist>
0562 After the shuffling is performed in both file trees, <literal>poascribe co</literal> is executed to smooth out and commit modifications.</para>
0563 
0564 </sect2>
0565 
0566 <sect2 id="sec-ascfltrel">
0567 <title>Filtering for Release</title>
0568 
0569 <para>At the moment of this writing, <link linkend="p-asrel">filtering for release</link> has not been implemented yet in <command>poascribe</command>, but it is planned.</para>
0570 
0571 <para>However, if you <link linkend="ch-summit">translate in summit</link>, it is possible to configure the summit to skip insufficiently reviewed messages when scattering to branches. See <xref linkend="sec-sucfgascf"/> for details.</para>
0572 
0573 </sect2>
0574 
0575 <sect2 id="sec-asctrim">
0576 <title>Trimming Ascription History</title>
0577 
0578 <para>At the moment of this writing, trimming the ascription history has not been implemented yet in <command>poascribe</command>, but it is planned.</para>
0579 
0580 </sect2>
0581 
0582 </sect1>
0583 
0584 <!-- ======================================== -->
0585 <sect1 id="sec-ascoptions">
0586 <title>Command Line Options</title>
0587 
0588 <para>Overview of operation modes:
0589 <variablelist>
0590 
0591 <varlistentry>
0592 <term><literal>commit</literal>, <literal>co</literal></term>
0593 <listitem>
0594 <para>Commits modifications and reviews to PO files. Default selector: <literal>any</literal>.</para>
0595 </listitem>
0596 </varlistentry>
0597 
0598 <varlistentry>
0599 <term><literal>diff</literal>, <literal>di</literal></term>
0600 <listitem>
0601 <para>Adds embedded differences and other review elements to selected messages in PO files. Default selector: <literal>modar</literal>.</para>
0602 </listitem>
0603 </varlistentry>
0604 
0605 <varlistentry>
0606 <term><literal>history</literal>, <literal>hi</literal></term>
0607 <listitem>
0608 <para>Outputs to terminal the complete history of modifications and reviews for selected messages. Default selector: <literal>any</literal>.</para>
0609 </listitem>
0610 </varlistentry>
0611 
0612 <varlistentry>
0613 <term><literal>purge</literal>, <literal>pu</literal></term>
0614 <listitem>
0615 <para>Removes all review elements from PO files (unless <option>-k</option>/<option>--keep-flags</option> option is added, when only review flags are kept). Default selector: <literal>any</literal>.</para>
0616 </listitem>
0617 </varlistentry>
0618 
0619 <varlistentry>
0620 <term><literal>release</literal>, <literal>re</literal></term>
0621 <listitem>
0622 <para><emphasis>Not implemented yet.</emphasis></para>
0623 </listitem>
0624 </varlistentry>
0625 
0626 <varlistentry>
0627 <term><literal>status</literal>, <literal>st</literal></term>
0628 <listitem>
0629 <para>Shows ascription counts per message category (total for all selected messages, and also per PO file if <option>-b</option>/<option>--show-by-file</option> option is added). Default selector: <literal>any</literal>.</para>
0630 </listitem>
0631 </varlistentry>
0632 
0633 <varlistentry>
0634 <term><literal>trim</literal>, <literal>tr</literal></term>
0635 <listitem>
0636 <para><emphasis>Not implemented yet.</emphasis></para>
0637 </listitem>
0638 </varlistentry>
0639 
0640 </variablelist>
0641 </para>
0642 
0643 <para>Options specific to <command>poascribe</command>:
0644 <variablelist>
0645 
0646 <varlistentry>
0647 <term><option>-a <replaceable>SELECTOR[:ARGS]</replaceable></option>, <option>--select-ascription=<replaceable>SELECTOR[:ARGS]</replaceable></option></term>
0648 <listitem>
0649 <para>By default, a historical message is selected for diffing with current message based on the last history selector given by <option>-s</option>/<option>--selector</option> option (if any). Instead, with this option you can explicitly set the selector for historical messages. It will be applied after the message has been selected by the primary selector chain. The option can be repeated, in which case a historical message is selected if all selectors match it.</para>
0650 </listitem>
0651 </varlistentry>
0652 
0653 <varlistentry>
0654 <term><option>-A <replaceable>RATIO</replaceable></option>, <option>--min-adjsim-diff=<replaceable>RATIO</replaceable></option></term>
0655 <listitem>
0656 <para>The minimum adjusted similarity between the current and the historical message at which embedded differences will be shown.<footnote>
0657 <para>Unlike for example in fuzzy messages, the similarity between the current and the earlier message from the ascription history may be exactly zero, it the PO file has undergone several merges in between. For example, in a two-word message, the first merge could have replaced the first word, and the second merge the second word.</para>
0658 </footnote> This is a number in range from 0.0 (always show) to 1.0 (never show). If the difference is not shown due to this limit, the message will get the flag <literal>ediff-ignored</literal> instead of the usual <literal>ediff</literal>. A reasonable value may be 0.6 to 0.8.</para>
0659 </listitem>
0660 </varlistentry>
0661 
0662 <varlistentry>
0663 <term><option>-b</option>, <option>--show-by-file</option></term>
0664 <listitem>
0665 <para>Some operation modes show summary at the end of the run, which is based on all processed PO files taken together. With this option you can request some of the summary elements to be shown per processed file.</para>
0666 </listitem>
0667 </varlistentry>
0668 
0669 <varlistentry>
0670 <term><option>-C</option>, <option>--no-vcs-commit</option></term>
0671 <listitem>
0672 <para>Issue this option if you want <command>poascribe</command> not to commit modifications to version control itself. This may be useful if you want to examine raw modifications it made, to perform some checks, etc, and commit manually later. But <emphasis>do not</emphasis> modify any messages in between, as that would defeat the purpose of ascription.</para>
0673 </listitem>
0674 </varlistentry>
0675 
0676 <varlistentry>
0677 <term><option>-d <replaceable>LEVEL</replaceable></option>, <option>--depth=<replaceable>LEVEL</replaceable></option></term>
0678 <listitem>
0679 <para>Operation modes normally consider ascription history of a message starting from the newest and going down to the earliest ascription. With this option you can set the depth to which history is examined, where 0 is the newest ascription only, 1 the current and first previous ascription, etc.</para>
0680 </listitem>
0681 </varlistentry>
0682 
0683 <varlistentry>
0684 <term><option>-D <replaceable>SPEC</replaceable></option>, <option>--diff-reduce-history=<replaceable>SPEC</replaceable></option></term>
0685 <listitem>
0686 <para>Some special (possibly custom) selectors may need to examine only differences or commonalities between each two adjacent messages. In order not to have to build this functionality into each such selector, you can issue this option to preprocess ascription history such that each historical message is reduced based on the difference with the next earlier message. The message can be reduced to the parts equal, added or removed as compared to the earlier message. This is controlled by the <literal><replaceable>SPEC</replaceable></literal> value, which must start with one of the letters <literal>e</literal> (equal), <literal>a</literal> (added), or <literal>r</literal> (removed). This letter may be followed with an arbitrary sequence of characters, which will be used to separate the remaining parts of the text in the message; if there are no additional characters, space is used as the separator.</para>
0687 </listitem>
0688 </varlistentry>
0689 
0690 <varlistentry>
0691 <term><option>-F <replaceable>HOOKSPEC</replaceable></option>, <option>--filter=<replaceable>HOOKSPEC</replaceable></option></term>
0692 <listitem>
0693 <para>Sometimes it may be necessary to apply selectors not to the ascription history as it is, but to a suitably filtered version of the history. This option can be used to set a Pology F1A hook as filter, see <xref linkend="sec-cmhooks"/> for details. It can be repeated to set several filters.</para>
0694 </listitem>
0695 </varlistentry>
0696 
0697 <varlistentry>
0698 <term><option>-G</option>, <option>--show-filtered</option></term>
0699 <listitem>
0700 <para>When setting a filter on ascription history by the <option>-F</option>/<option>--filter</option> option in the <literal>diff</literal> mode, it may be good to see also the difference in filtered messages, those on which the selectors were actually applied. By issuing this option, every message field with an embedded difference will get added a visually conspicuous separator, followed by the filtered version of the text with difference as well. When you commit or purge the PO file diffed in this way, the separators and the filtered text are removed together with all other review elements.</para>
0701 </listitem>
0702 </varlistentry>
0703 
0704 <varlistentry>
0705 <term><option>-k</option>, <option>--keep-flags</option></term>
0706 <listitem>
0707 <para>When the diffed PO file is purged of review elements, by default all review elements are removed, so that on subsequent commit only modifications would be ascribed, if there were any. Issuing this option on purge causes that all review elements except for flags are removed. More precisely, <literal>ediff*</literal> flags are replaced with <literal>reviewed</literal>, and <literal>unreviewed</literal> flags are simply kept. This makes the subsequent commit also ascribe reviews. You need this if you want to apply some automatic checks to the PO file after the review and before the commit, where more intrusive review elements (like embedded differences) would interfere.</para>
0708 </listitem>
0709 </varlistentry>
0710 
0711 <varlistentry>
0712 <term><option>-m <replaceable>TEXT</replaceable></option>, <option>--message=<replaceable>TEXT</replaceable></option></term>
0713 <listitem>
0714 <para>The text of the commit message. If default commit message is set in the ascription configuration, this text overrides it. If default commit message is not set and this option is not issued, and editor window is opened to enter the commit message.</para>
0715 </listitem>
0716 </varlistentry>
0717 
0718 <varlistentry>
0719 <term><option>-o <replaceable>EDITOR</replaceable></option>, <option>--open-in-editor=<replaceable>EDITOR</replaceable></option></term>
0720 <listitem>
0721 <para>When diffing for review, instead of manually opening diffed PO files and searching for messages by flags, this option can be issued to have <command>poascribe</command> automatically open PO files in a PO editor (and possibly have the editor filter the message list to only selected messages). This work only with PO editors explicitly supported by Pology; the <replaceable>EDITOR</replaceable> value is an editor keyword rather than an arbitrary editor command. See <xref linkend="sec-cmsupped"/> for the list of supported editors.</para>
0722 </listitem>
0723 </varlistentry>
0724 
0725 <varlistentry>
0726 <term><option>-L <replaceable>RATIO</replaceable></option>, <option>--max-fraction-select=<replaceable>RATIO</replaceable></option></term>
0727 <listitem>
0728 <para>In <literal>diff</literal> mode, this option sets the ratio of selected messages to total messages in a given PO file, above which no message in that file will be selected although the selector chain matched them. The value is the number between 0.0 and 1.0; for example, 0.2 means to accept selection if the number of selected messages is at most 20% of the total number of messages. This can be used to discern between reviewing updated PO files and newly translated PO files, as the latter take much more time to review and hence may be of lesser priority.</para>
0729 </listitem>
0730 </varlistentry>
0731 
0732 <varlistentry>
0733 <term><option>-s <replaceable>SELECTOR[:ARGS]</replaceable></option>, <option>--selector <replaceable>SELECTOR[:ARGS]</replaceable></option></term>
0734 <listitem>
0735 <para>The option to set a selector, in various modes. Can be repeated to create selector chains, in which case a message must match all selectors to be selected. In <literal>diff</literal> mode, if the last selector in the chain is not a <link linkend="p-seltypes">history selector</link>, selected messages will have no embedded differences (unless an ascription selector is explicitly given by the <option>-A</option>/<option>--select-ascription</option> option).</para>
0736 </listitem>
0737 </varlistentry>
0738 
0739 <varlistentry>
0740 <term><option>-t <replaceable>TAG</replaceable></option>, <option>--tag=<replaceable>TAG</replaceable></option></term>
0741 <listitem>
0742 <para>The review tag, denoting the type of the review. If <literal>review-tags</literal> field in ascription configuration set, this must be one of the tags defined there (general review has an empty string as tag, which is the default). The tag is normally issued in <literal>diff</literal> mode: it will be appended to review flags on diffed messages (e.g. <literal>ediff/<replaceable>tag</replaceable></literal>), which will cause on commit that the review of this type is ascribed. In <literal>commit</literal> mode, this option has effect only if <option>--all-reviewed</option> is issued as well, in which case this tag will override any from the PO file. Several tags may be given as comma-separated list.</para>
0743 </listitem>
0744 </varlistentry>
0745 
0746 <varlistentry>
0747 <term><option>-u <replaceable>NAME</replaceable></option>, <option>--user=<replaceable>NAME</replaceable></option></term>
0748 <listitem>
0749 <para>The user, one of those defined in ascription configuration, to whom modifications and reviews are ascribed on commit.</para>
0750 </listitem>
0751 </varlistentry>
0752 
0753 <varlistentry>
0754 <term><option>-U</option>, <option>--update-headers</option></term>
0755 <listitem>
0756 <para>If you work on PO files with a general text editor, you can issue this option on commit to have the header data in modified PO files automatically updated. The necessary information is fetched from the ascription configuration.</para>
0757 </listitem>
0758 </varlistentry>
0759 
0760 <varlistentry>
0761 <term><option>-v</option>, <option>--verbose</option></term>
0762 <listitem>
0763 <para>More detailed information on progress of the operation.</para>
0764 </listitem>
0765 </varlistentry>
0766 
0767 <varlistentry>
0768 <term><option>-w <replaceable>FILE</replaceable></option>, <option>--write-modified=<replaceable>FILE</replaceable></option></term>
0769 <listitem>
0770 <para>This option specifies the file into which to write the path of every PO file modified during the operation, one per line. This file can later be fed back to <command>poascribe</command> (and other Pology commands) with the <option>-f</option>/<option>--files-from</option> option.</para>
0771 </listitem>
0772 </varlistentry>
0773 
0774 <varlistentry>
0775 <term><option>-x <replaceable>FILE</replaceable></option>, <option>--externals=<replaceable>FILE</replaceable></option></term>
0776 <listitem>
0777 <para>If you have <link linkend="sec-prascsel">written some custom selectors</link>, with this option you specify the path to the file containing them. It can be repeated to load several files with custom selectors.</para>
0778 </listitem>
0779 </varlistentry>
0780 
0781 <varlistentry>
0782 <term><option>--all-reviewed</option></term>
0783 <listitem>
0784 <para>On commit, normally only messages having <literal>ediff*</literal> or <literal>reviewed</literal> flags will be ascribed as reviewed. If this option is used, instead all messages will be ascribed as reviewed (except for those having <literal>unreviewed</literal> flag).</para>
0785 </listitem>
0786 </varlistentry>
0787 
0788 </variablelist>
0789 </para>
0790 
0791 <para>Options common with other Pology tools:
0792 <variablelist>
0793 
0794 <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
0795             href="stdopt-filesfrom.docbook"/>
0796 
0797 <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
0798             href="stdopt-incexc.docbook"/>
0799 
0800 </variablelist>
0801 </para>
0802 
0803 </sect1>
0804 
0805 <!-- ======================================== -->
0806 <sect1 id="sec-ascconfig">
0807 <title>User Configuration</title>
0808 
0809 <para>The following <link linkend="sec-cmconfig">configuration</link> fields can be used to modify general behavior of <command>poascribe</command>:
0810 <variablelist>
0811 
0812 <varlistentry>
0813 <term><literal>[poascribe]/aselectors</literal></term>
0814 <listitem>
0815 <para>The list of explicit selectors of historical messages, as if they were issued with multiple <option>-a</option>/<option>--aselector</option> options. The first character in the value must be non-alphanumeric (e.g. <literal>/</literal>), and that character is then used to separate selector specifications; the value must also end with this character.</para>
0816 </listitem>
0817 </varlistentry>
0818 
0819 <varlistentry>
0820 <term><literal>[poascribe]/diff-reduce-history</literal></term>
0821 <listitem>
0822 <para>Counterpart to <option>-D</option>/<option>diff-reduce-history</option> command line option.</para>
0823 </listitem>
0824 </varlistentry>
0825 
0826 <varlistentry>
0827 <term><literal>[poascribe]/filters</literal></term>
0828 <listitem>
0829 <para>Comma-separated list of history filters, as if they were issued with multiple <option>-F</option>/<option>--filter</option> options.</para>
0830 </listitem>
0831 </varlistentry>
0832 
0833 <varlistentry>
0834 <term><literal>[poascribe]/max-fraction-select</literal></term>
0835 <listitem>
0836 <para>Counterpart to <option>-L</option>/<option>max-fraction-select</option> command line option.</para>
0837 </listitem>
0838 </varlistentry>
0839 
0840 <varlistentry>
0841 <term><literal>[poascribe]/min-adjsim-diff</literal></term>
0842 <listitem>
0843 <para>Counterpart to <option>-A</option>/<option>--min-adjsim-diff</option> command line option.</para>
0844 </listitem>
0845 </varlistentry>
0846 
0847 <varlistentry>
0848 <term><literal>[poascribe]/po-editor</literal></term>
0849 <listitem>
0850 <para>Counterpart to <option>-o</option>/<option>--open-in-editor</option> command line option.</para>
0851 </listitem>
0852 </varlistentry>
0853 
0854 <varlistentry>
0855 <term><literal>[poascribe]/selectors</literal></term>
0856 <listitem>
0857 <para>List of message selectors, as if they were issued with multiple <option>-s</option>/<option>--selector</option> options. The first character in the value must be non-alphanumeric (e.g. <literal>/</literal>), and that character is then used to separate selector specifications; the value must also end with this character.</para>
0858 </listitem>
0859 </varlistentry>
0860 
0861 <varlistentry>
0862 <term><literal>[poascribe]/tags</literal></term>
0863 <listitem>
0864 <para>Counterpart to <option>-t</option>/<option>--tag</option> command line option.</para>
0865 </listitem>
0866 </varlistentry>
0867 
0868 <varlistentry>
0869 <term><literal>[poascribe]/update-headers=[yes|*no]</literal></term>
0870 <listitem>
0871 <para>Setting to <literal>yes</literal> is counterpart to <option>-U</option>/<option>--update-headers</option> command line option.</para>
0872 </listitem>
0873 </varlistentry>
0874 
0875 <varlistentry>
0876 <term><literal>[poascribe]/user</literal></term>
0877 <listitem>
0878 <para>Counterpart to <option>-u</option>/<option>--user</option> command line option.</para>
0879 </listitem>
0880 </varlistentry>
0881 
0882 <varlistentry>
0883 <term><literal>[poascribe]vcs-commit/=[*yes|no]</literal></term>
0884 <listitem>
0885 <para>Setting to <literal>no</literal> is counterpart to <option>-C</option>/<option>--no-vcs-commit</option> command line option.</para>
0886 </listitem>
0887 </varlistentry>
0888 
0889 </variablelist>
0890 </para>
0891 
0892 </sect1>
0893 
0894 <!-- ======================================== -->
0895 <sect1 id="sec-ascsels">
0896 <title>Review Selectors</title>
0897 
0898 <para><command>poascribe</command> provides a variety of internal selectors, and new selectors are added as general need for them is observed in practice. Selectors come in two types: history and shallow; the former also select a historical message from which to show the differences to the current message, while the latter do not. Arguments to selectors are added consistently separated with any non-alphanumeric character, customarily colon (<literal>:</literal>) when possible. If less arguments are given than the selector can take, all remaining arguments are set to empty (the selector may or may not accept this).</para>
0899 
0900 <para>Available internal selectors are as follows:
0901 <variablelist>
0902 
0903 <varlistentry>
0904 <term><literal>any</literal> (shallow)</term>
0905 <listitem>
0906 <para>Selects any message.</para>
0907 </listitem>
0908 </varlistentry>
0909 
0910 <varlistentry>
0911 <term><literal>active</literal> (shallow)</term>
0912 <listitem>
0913 <para>Selects active messages, i.e. those translated and not obsolete.</para>
0914 </listitem>
0915 </varlistentry>
0916 
0917 <varlistentry>
0918 <term><literal>asc:<replaceable>USER</replaceable></literal> (history)</term>
0919 <listitem>
0920 <para>Selects latest historical message ascribed (modified or reviewed) by the given user, or to any user if the argument is empty. Multiple users can be given as a comma-separated list, and selection inverted by prepending <literal>~</literal>.</para>
0921 </listitem>
0922 </varlistentry>
0923 
0924 <varlistentry>
0925 <term><literal>branch:<replaceable>NAME</replaceable></literal> (shallow)</term>
0926 <listitem>
0927 <para>Selects messages belonging to the given branch (see <xref linkend="ch-summit"/>). Several branch names may be given, as comma-separated list.</para>
0928 </listitem>
0929 </varlistentry>
0930 
0931 <varlistentry>
0932 <term><literal>current</literal> (shallow)</term>
0933 <listitem>
0934 <para>Selects current messages, i.e. those not obsolete.</para>
0935 </listitem>
0936 </varlistentry>
0937 
0938 <varlistentry>
0939 <term><literal>e:<replaceable>ENTRYNUM</replaceable></literal> (shallow)</term>
0940 <listitem>
0941 <para>Selects a message with given entry number in the PO file (first message has entry number 1, second 2, etc).</para>
0942 </listitem>
0943 </varlistentry>
0944 
0945 <varlistentry>
0946 <term><literal>espan:<replaceable>START</replaceable>:<replaceable>END</replaceable></literal> (shallow)</term>
0947 <listitem>
0948 <para>Select messages with entry numbers between given start and end, including both. If start is empty, 1 is assumed; if end is empty, number of messages is assumed.</para>
0949 </listitem>
0950 </varlistentry>
0951 
0952 <varlistentry>
0953 <term><literal>fexpr:<replaceable>EXPRESSION</replaceable></literal> (shallow)</term>
0954 <listitem>
0955 <para>Selects messages matching a boolean search expression on message parts. It has same syntax as the <link linkend="p-fexprdesc"><literal>fexpr</literal> parameter</link> of the <command>find-messages</command> sieve.</para>
0956 </listitem>
0957 </varlistentry>
0958 
0959 <varlistentry>
0960 <term><literal>hexpr:<replaceable>EXPRESSION</replaceable>:<replaceable>USER</replaceable>:<replaceable>DIFFSPEC</replaceable></literal> (history)</term>
0961 <listitem>
0962 <para>Like <literal>fexpr</literal>, but matches through historical messages starting from the latest ascription. If user argument is not empty, matches only messages ascribed to that user. Multiple users can be given as a comma-separated list, and selection inverted by prepending <literal>~</literal>. The last argument, if not empty, requests to reduce historical messages by incremental differences before matching them; see the <option>--diff-reduce-history</option> option for the syntax and other details.</para>
0963 </listitem>
0964 </varlistentry>
0965 
0966 <varlistentry>
0967 <term><literal>l:<replaceable>LINENUM</replaceable></literal> (shallow)</term>
0968 <listitem>
0969 <para>Selects a message with given referent line number in the PO file. This is the line number of <varname>msgid</varname> message field. ±1 offset is accepted.</para>
0970 </listitem>
0971 </varlistentry>
0972 
0973 <varlistentry>
0974 <term><literal>lspan:<replaceable>START</replaceable>:<replaceable>END</replaceable></literal> (shallow)</term>
0975 <listitem>
0976 <para>Select messages with referent line numbers between given start and end, including both. If start is empty, 1 is assumed; if end is empty, total number of lines is assumed.</para>
0977 </listitem>
0978 </varlistentry>
0979 
0980 <varlistentry>
0981 <term><literal>mod:<replaceable>USER</replaceable></literal> (history)</term>
0982 <listitem>
0983 <para>Selects latest historical message modified by the given user, or by any user if the argument is empty. Multiple users can be given as a comma-separated list, and selection inverted by prepending <literal>~</literal>.</para>
0984 </listitem>
0985 </varlistentry>
0986 
0987 <varlistentry>
0988 <term><literal>modafter:<replaceable>TIMESTAMP</replaceable>:<replaceable>USER</replaceable></literal> (history)</term>
0989 <listitem>
0990 <para>Selects the earliest historical message modified at or after the given date and time. The full timestamp format is <literal><replaceable>YEAR</replaceable>-<replaceable>MONTH</replaceable> <replaceable>DAY</replaceable> <replaceable>HOUR</replaceable>:<replaceable>MINUTE</replaceable>:<replaceable>SECOND</replaceable></literal>, but trailing elements can be omitted as logical; for example, <literal>2010-10</literal> would be interpreted as <literal>2010-10-01 00:00:00</literal>. If the user argument is not empty, only modifications by that user are considered; multiple users can be given as a comma-separated list, and selection inverted by prepending <literal>~</literal>.</para>
0991 </listitem>
0992 </varlistentry>
0993 
0994 <varlistentry>
0995 <term><literal>modam:<replaceable>USER1</replaceable>:<replaceable>USER2</replaceable></literal> (history)</term>
0996 <listitem>
0997 <para>Selects the earliest historical message which introduced modifications after the last modification, or the very first historical message. This makes sense only if one or both of the user arguments are not empty. If the first user argument is not empty, only modifications by that user are considered for selection. If the second user argument is not empty, only the modifications by that user are considered as base. For both user arguments, multiple users can be given as a comma-separated list, and selection inverted by prepending <literal>~</literal>.</para>
0998 </listitem>
0999 </varlistentry>
1000 
1001 <varlistentry>
1002 <term><literal>modar:<replaceable>MODUSER</replaceable>:<replaceable>REVUSER</replaceable>:<replaceable>TAG</replaceable></literal> (history)</term>
1003 <listitem>
1004 <para>Selects the earliest historical message which introduced modifications after the last review, or the very first historical message if there was no review yet. If the first user argument is not empty, only modifications by that user are considered and reviews by that user are ignored. If the second user argument is not empty, only reviews by that user are considered and modifications by that user are ignored. For both user arguments, multiple users can be given as a comma-separated list, and selection inverted by prepending <literal>~</literal>. The last argument determines which review types (by review tag) to consider, where empty value means "general review"; multiple tags can be given as comma-separated list.</para>
1005 </listitem>
1006 </varlistentry>
1007 
1008 <varlistentry>
1009 <term><literal>modarm:<replaceable>MODUSER</replaceable>:<replaceable>REVUSER</replaceable>:<replaceable>TAG</replaceable></literal> (history)</term>
1010 <listitem>
1011 <para>Like <literal>modar</literal>, but uses as base for selection the last review <emphasis>or</emphasis> the last modification. This generally makes sense only if some combination of user arguments is given too.</para>
1012 </listitem>
1013 </varlistentry>
1014 
1015 <varlistentry>
1016 <term><literal>rev:<replaceable>USER</replaceable></literal> (history)</term>
1017 <listitem>
1018 <para>Selects latest historical message reviewed by the given user, or by any user if the argument is empty. Multiple users can be given as a comma-separated list, and selection inverted by prepending <literal>~</literal>.</para>
1019 </listitem>
1020 </varlistentry>
1021 
1022 <varlistentry>
1023 <term><literal>revbm:<replaceable>REVUSER</replaceable>:<replaceable>MODUSER</replaceable>:<replaceable>TAG</replaceable></literal> (history)</term>
1024 <listitem>
1025 <para>Selects the earliest historical message which has been reviewed just before a modification occurred. If the first user argument is not empty, only reviews by that user are considered and modifications by that user are ignored. If the second user argument is not empty, only modifications by that user are considered and reviews by that user are ignored. For both user arguments, multiple users can be given as a comma-separated list, and selection inverted by prepending <literal>~</literal>. The last argument determines which review types (by review tag) to consider, where empty value means "general review"; multiple tags can be given as comma-separated list.</para>
1026 </listitem>
1027 </varlistentry>
1028 
1029 <varlistentry>
1030 <term><literal>tmodar:<replaceable>MODUSER</replaceable>:<replaceable>REVUSER</replaceable>:<replaceable>TAG</replaceable></literal> (history)</term>
1031 <listitem>
1032 <para>Like <literal>modar</literal>, but considers as modified only those historical messages with modifications in translation (<varname>msgstr</varname>).</para>
1033 </listitem>
1034 </varlistentry>
1035 
1036 <varlistentry>
1037 <term><literal>unasc</literal> (shallow)</term>
1038 <listitem>
1039 <para>Select messages that are not yet ascribed, i.e. those which are modified but not yet committed.</para>
1040 </listitem>
1041 </varlistentry>
1042 
1043 </variablelist>
1044 </para>
1045 
1046 <para>Every selector automatically gets a negative counterpart, with the name prefixed by <literal>n*</literal>. The negative selector is always shallow, regardless of the type of the original selector.</para>
1047 
1048 <sect2 id="sec-asccustsels">
1049 <title>Custom Review Selectors</title>
1050 
1051 <para>Custom selectors can be written in a standalone Python source file, which is then fed to <command>poascribe</command> using the <option>-x</option>/<option>--externals</option> option. A file with several custom selectors should have this layout:
1052 <programlisting language="python">
1053 def selector_foo (args):
1054     ...
1055 
1056 def selector_bar (args):
1057     ...
1058 
1059 asc_selector_factories = {
1060     # key: (factory, is_history_selector)
1061     "foo": (selector_foo, False),
1062     "bar": (selector_bar, True),
1063 }
1064 </programlisting>
1065 <function>selector_foo</function> and <function>selector_bar</function> are factory functions for selectors <literal>foo</literal> and <literal>bar</literal>. After loading the file, <command>poascribe</command> will look for the <varname>asc_selector_factories</varname> dictionary to see which selectors are defined and of what type they are. See <xref linkend="sec-prascsel"/> for the instructions on writing selector factory functions.</para>
1066 
1067 </sect2>
1068 
1069 </sect1>
1070 
1071 </chapter>