trans-coord-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

trans-coord/gnun/server/gnun AUTHORS ChangeLog ...


From: Ineiev
Subject: trans-coord/gnun/server/gnun AUTHORS ChangeLog ...
Date: Fri, 18 Aug 2017 07:40:41 -0400 (EDT)

CVSROOT:        /sources/trans-coord
Module name:    trans-coord
Changes by:     Ineiev <ineiev> 17/08/18 07:40:41

Modified files:
        gnun/server/gnun: AUTHORS ChangeLog Makefile.am NEWS 
        gnun/server/gnun/doc: gnun.texi 
Added files:
        gnun/server/gnun: gnun-link-diff.in link-diff.awk 

Log message:
        New script, gnun-link-diff.
        
        * gnun-link-diff.in, link-diff.awk: New files.
        * doc/gnun.texi (gnun-link-diff): New node.
        * Makefile.am (bin_SCRIPTS): Add gnun-link-diff.
        (pkglibexec_SCRIPTS): Add link-diff.awk.
        (EXTRA_DIST): Add gnun-link-diff.in link-diff.awk.
        (gnun-link-diff): New target.
        * AUTHORS:
        * NEWS: Update.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/trans-coord/gnun/server/gnun/AUTHORS?cvsroot=trans-coord&r1=1.24&r2=1.25
http://cvs.savannah.gnu.org/viewcvs/trans-coord/gnun/server/gnun/ChangeLog?cvsroot=trans-coord&r1=1.458&r2=1.459
http://cvs.savannah.gnu.org/viewcvs/trans-coord/gnun/server/gnun/Makefile.am?cvsroot=trans-coord&r1=1.49&r2=1.50
http://cvs.savannah.gnu.org/viewcvs/trans-coord/gnun/server/gnun/NEWS?cvsroot=trans-coord&r1=1.128&r2=1.129
http://cvs.savannah.gnu.org/viewcvs/trans-coord/gnun/server/gnun/gnun-link-diff.in?cvsroot=trans-coord&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/trans-coord/gnun/server/gnun/link-diff.awk?cvsroot=trans-coord&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/trans-coord/gnun/server/gnun/doc/gnun.texi?cvsroot=trans-coord&r1=1.108&r2=1.109

Patches:
Index: AUTHORS
===================================================================
RCS file: /sources/trans-coord/trans-coord/gnun/server/gnun/AUTHORS,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -b -r1.24 -r1.25
--- AUTHORS     24 Jan 2017 15:50:12 -0000      1.24
+++ AUTHORS     18 Aug 2017 11:40:41 -0000      1.25
@@ -21,7 +21,8 @@
         expand-ssi.awk.in,
         languages.txt (compiled from www.gnu.org pages),
         gnun-add-fuzzy-diff, gnun-diff-po.in,
-        gnun-init-po.in, gnun-report.in, make-prototype.awk,
+        gnun-init-po.in, gnun-link-diff.in, gnun-report.in,
+        link-diff.awk, make-prototype.awk,
         priorities.mk, update-localized-urls.in, sort.awk.in, sort-linguas,
         m4/ax_arg_prog.m4, m4/ax_arg_progs.m4,
         all files in test/.

Index: ChangeLog
===================================================================
RCS file: /sources/trans-coord/trans-coord/gnun/server/gnun/ChangeLog,v
retrieving revision 1.458
retrieving revision 1.459
diff -u -b -r1.458 -r1.459
--- ChangeLog   9 Jun 2017 17:32:38 -0000       1.458
+++ ChangeLog   18 Aug 2017 11:40:41 -0000      1.459
@@ -1,3 +1,16 @@
+2017-08-18  Pavel Kharitonov  <address@hidden>
+
+       New script, gnun-link-diff.
+
+       * gnun-link-diff.in, link-diff.awk: New files.
+       * doc/gnun.texi (gnun-link-diff): New node.
+       * Makefile.am (bin_SCRIPTS): Add gnun-link-diff.
+       (pkglibexec_SCRIPTS): Add link-diff.awk.
+       (EXTRA_DIST): Add gnun-link-diff.in link-diff.awk.
+       (gnun-link-diff): New target.
+       * AUTHORS:
+       * NEWS: Update.
+
 2017-06-09  Pavel Kharitonov  <address@hidden>
 
        * doc/web-trans.texi (New Team): Mention monthly automatic

Index: Makefile.am
===================================================================
RCS file: /sources/trans-coord/trans-coord/gnun/server/gnun/Makefile.am,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -b -r1.49 -r1.50
--- Makefile.am 24 Jan 2017 15:50:12 -0000      1.49
+++ Makefile.am 18 Aug 2017 11:40:41 -0000      1.50
@@ -20,7 +20,7 @@
 
 SUBDIRS = doc dtd
 
-bin_SCRIPTS =
+bin_SCRIPTS = gnun-link-diff
 tests_available =
 tests_enabled =
 check_environment = bindir="$(bindir)" \
@@ -55,7 +55,7 @@
 if HAVE_SORT
 noinst_SCRIPTS += stamp-i18n.mk
 endif
-pkglibexec_SCRIPTS = copy-msgid mailfail update-localized-urls \
+pkglibexec_SCRIPTS = copy-msgid link-diff.awk mailfail update-localized-urls \
  validate-html-notify
 
 if HAVE_VALIDATION
@@ -144,7 +144,7 @@
        -e 's|@address@hidden|$(WDIFF)|g'
 
 add-fuzzy-diff copy-msgid diff-po.awk gnun-add-fuzzy-diff \
-gnun-diff-po gnun-init-po gnun-merge-preconverted gnun-report \
+gnun-diff-po gnun-init-po gnun-link-diff gnun-merge-preconverted gnun-report \
 gnun-validate-html mailfail sort.awk update-localized-urls \
 validate-html-notify: Makefile
        $(AM_V_at)rm -f $@ address@hidden
@@ -182,6 +182,7 @@
 gnun-add-fuzzy-diff: $(srcdir)/gnun-add-fuzzy-diff.in
 gnun-diff-po: $(srcdir)/gnun-diff-po.in
 gnun-init-po: $(srcdir)/gnun-init-po.in
+gnun-link-diff: $(srcdir)/gnun-link-diff.in
 gnun-merge-preconverted: $(srcdir)/gnun-merge-preconverted.in
 gnun-report: $(srcdir)/gnun-report.in
 gnun-validate-html: $(srcdir)/gnun-validate-html.in
@@ -208,8 +209,8 @@
 EXTRA_DIST = m4-external/README \
             add-fuzzy-diff.in copy-msgid.in diff-po.awk.in \
             expand-ssi.awk.in gnun-add-fuzzy-diff.in gnun-diff-po.in \
-            gnun-init-po.in gnun-merge-preconverted.in \
-            gnun-report.in gnun-validate-html.in \
+            gnun-init-po.in gnun-link-diff.in gnun-merge-preconverted.in \
+            gnun-report.in gnun-validate-html.in link-diff.awk \
             mailfail.in sort.awk.in sort-linguas update-localized-urls.in \
             validate-html-notify.in \
             tests/add-fuzzy-diff tests/fuzzy-diff-0.po tests/fuzzy-diff-1.po \
@@ -237,7 +238,7 @@
             tests/validate/match3.1.html
 
 CLEANFILES = add-fuzzy-diff copy-msgid diff-po.awk gnun-add-fuzzy-diff \
-            gnun-diff-po gnun-init-po gnun-merge-preconverted gnun-report \
+            gnun-diff-po gnun-init-po gnun-link-diff gnun-merge-preconverted 
gnun-report \
             gnun-validate-html mailfail sort.awk \
             update-localized-urls validate-html-notify \
             stamp-config.mk

Index: NEWS
===================================================================
RCS file: /sources/trans-coord/trans-coord/gnun/server/gnun/NEWS,v
retrieving revision 1.128
retrieving revision 1.129
diff -u -b -r1.128 -r1.129
--- NEWS        20 Jan 2017 18:36:49 -0000      1.128
+++ NEWS        18 Aug 2017 11:40:41 -0000      1.129
@@ -2,6 +2,8 @@
 
 * Changes in GNUnited Nations 0.12 (????-??-??)
 
+** New script, gnun-link-diff.
+
 ** configure script detects GNU sed-4.3-specific bug and issues
    a warning; all configuration warnings are printed
    after outputting results.

Index: doc/gnun.texi
===================================================================
RCS file: /sources/trans-coord/trans-coord/gnun/server/gnun/doc/gnun.texi,v
retrieving revision 1.108
retrieving revision 1.109
diff -u -b -r1.108 -r1.109
--- doc/gnun.texi       27 Sep 2016 08:47:30 -0000      1.108
+++ doc/gnun.texi       18 Aug 2017 11:40:41 -0000      1.109
@@ -1728,6 +1728,8 @@
 
 It is highly desirable that you check if the PO file you finished
 translating (or editing) is valid, before committing it.  This is done
address@hidden running checks
address@hidden validation, PO files
 by running @code{msgfmt -cv -o /dev/null @var{file}} or by simply
 pressing @kbd{V} in PO mode.  The build system automatically verifies
 each PO file when invoked with @code{VALIDATE=yes}, but you won't get a
@@ -2289,6 +2291,7 @@
                                @code{msgid}s.
 * gnun-diff-po::             Compare two revisions of a PO file.
 * gnun-init-po::             Initialize a new translation.
+* gnun-link-diff::           Figure out mismatched links.
 * gnun-preconvert::          Invoke the first step in converting
                                HTML translation to PO format.
 * gnun-merge-preconverted::  Run the second step of the conversion.
@@ -2426,6 +2429,51 @@
 The PO file name is guessed from the name of POT and language
 suffix; the file is created in the current working directory.
 
address@hidden gnun-link-diff
address@hidden The @command{gnun-link-diff} Script
address@hidden running checks
+
+This script finds mismatched links and anchors
+and fills some fields in the header.  Usually this is a typo,
+though in @emph{very} rare cases changes in links are justified.
+
+The script takes into account possible translator's notes
+and changes in links to Creative Commons licenses.
address@hidden Terms, , , web-trans, GNU Web Translators Manual}.
+
+The output is a HTML page with highlighted differences.
+In the beginning, numbers of mismatched links and anchors
+are written. Links starting with "mailto:"; are not counted,
+but highlighted.
+
+The exit status of the script is 0 when the counts of mismatched
+links and anchors are zero, 1 when their sum is not zero,
+2 when an error occurred.
+
address@hidden
+gnun-link-diff [OPTION...] FILE
address@hidden example
+
address@hidden @option
address@hidden -l
address@hidden address@hidden
+Specify language suffix, e.g ``bg''.  The suffix is used
+to adjust links to Creative Commons licenses.
+When unspecified, it is filled from the file name.
+
address@hidden -t
address@hidden --title="@var{page title}"
+Specify title.  When unspecified, the file name is used.
+
address@hidden -v
address@hidden --version
+Display copyright and version information and exit.
+
address@hidden -h
address@hidden --help
+Display usage information and exit.
address@hidden table
+
 @node gnun-preconvert
 @subsection The @command{gnun-preconvert} Script
 @cindex migration, translations

Index: gnun-link-diff.in
===================================================================
RCS file: gnun-link-diff.in
diff -N gnun-link-diff.in
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnun-link-diff.in   18 Aug 2017 11:40:41 -0000      1.1
@@ -0,0 +1,157 @@
+#! @BASH@
+
+# Copyright (C) 2012, 2013, 2014, 2017 Free Software Foundation, Inc.
+
+# This file is part of GNUnited Nations.
+
+# GNUnited Nations is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+
+# GNUnited Nations is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GNUnited Nations.  If not, see <http://www.gnu.org/licenses/>.
+
+# Wrap around link-diff.awk to provide a command line interface compliant
+# with GNU Coding Standards.
+
+function version () {
+cat <<EOF
+gnun-link-diff (@PACKAGE_NAME@) @PACKAGE_VERSION@
+Copyright (C) 2017 Free Software Foundation, Inc.
+You may redistribute copies of @PACKAGE_NAME@
+under the terms of the GNU General Public License.
+For more information about these matters, see the file named COPYING.
+EOF
+}
+
+function usage () {
+cat <<EOF
+Usage: gnun-link-diff [OPTION...] [FILE]
+Output link and id differences in original vs. translated messages
+in a PO file in a HTML format.
+
+Options:
+  -t[TITLE], --title[=TITLE]
+                 Set page title (default is file name)
+  -l[LANG], --language[=LANG]
+                 Set language suffix (default is figured out from file name)
+  -v, --version  Display version info and exit
+  -h, --help     Display this help and exit
+
+Report bugs to @PACKAGE_BUGREPORT@
address@hidden@ home page: <@PACKAGE_URL@>
+General help using GNU software: <http://www.gnu.org/gethelp/>
+EOF
+}
+
+function single_file_needed () {
+  echo 1>&2 "$0:" Single FILE argument is required.
+  exit 2
+}
+
+# Parse command line.
+
+language=
+title=
+file=
+
+function parse_option () {
+  skip_option=
+  trimmed_option=
+  end_of_options=
+  case "$1" in
+      --help | -h* )
+         usage
+         exit 0
+         ;;
+      --version | -v* )
+         version
+         exit 0
+         ;;
+      -t | --title )
+          skip_option=yes
+          title="$2"
+          ;;
+      --title=* )
+          title="${1#--translator=}"
+          ;;
+      -t* )
+          title="${1#-t}"
+          ;;
+      -l | --language )
+         skip_option=yes
+         language="$2"
+         ;;
+      --language=* )
+         language="${1#--language=}"
+         ;;
+      -l* )
+          language="${1#-l}"
+          ;;
+      -- )
+          end_of_options=yes
+         ;;
+      -* )
+          echo 1>&2 "$0:" Invalid option -- \'$1\'.
+          exit 2
+         ;;
+      * )
+          if test "x$file" = x; then
+            file="$1"
+          else
+            single_file_needed
+          fi
+         ;;
+  esac
+}
+
+while [ $# -ge 1 ]; do
+  current_option="$1"
+  while test -n "$current_option";do
+    parse_option "$current_option" "$2"
+    if test -n "$skip_option"; then
+      shift
+    fi
+    if test -n "$trimmed_option"; then
+      current_option=-"$trimmed_option"
+    else
+      current_option=
+    fi
+  done
+  shift
+  if test -n "$end_of_options"; then
+    break
+  fi
+done
+
+if test "x$file" = x; then
+  if test $# -ne 1; then
+    single_file_needed
+  else
+    file="$1"
+  fi
+else
+  if test $# -gt 0; then
+    single_file_needed
+  fi
+fi
+
+if test "x$language" = x; then
+  language=${file%.po}
+  language=${language##*.}
+fi
+
+if test "x$title" = x; then
+  title=${file##*/}
+fi
+
address@hidden@ -f @pkglibexecdir@/link-diff.awk -v language="$language" \
+  -v title="$title" "$file"
+
+exit $?

Index: link-diff.awk
===================================================================
RCS file: link-diff.awk
diff -N link-diff.awk
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ link-diff.awk       18 Aug 2017 11:40:41 -0000      1.1
@@ -0,0 +1,499 @@
+# Copyright (C) 2014, 2016, 2017 Free Software Foundation, Inc.
+
+# This file is part of GNUnited Nations.
+
+# GNUnited Nations is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+
+# GNUnited Nations is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GNUnited Nations.  If not, see <https://www.gnu.org/licenses/>.
+
+# Output differences in sets of links and anchors in msgids and msgstrs
+# as a HTML file. Exit code is 0 when no crucially unmatched things
+# were found, else 1.
+
+# To use like
+# f=../licenses/gpl-faq.cv.po;time LC_ALL=C awk -v language=cv \
+#    -v title=${f##*/} -f link-diff.awk <$f > t.html
+
+BEGIN {
+# The language code is used for adjusting links to CC licenses;
+# creativecommons.org uses the ll_CC notation, our file suffix
+# convention is ll-cc.
+  if (length(language) > 2)
+    language = substr(language, 1, 2) "_" toupper(substr(language, 4))
+}
+
+# Transform special characters from PO file to HTML text. 
+function escape_chars(x)
+{
+# Unescape quotes \" -> ".
+  gsub(/\\"/, "\"", x)
+# Escape HTML specal characters.
+  gsub(/&/, "\\&amp;", x)
+  gsub(/>/, "\\&gt;", x)
+  gsub(/</, "\\&lt;", x)
+# Make newlines visible in a browser.
+  gsub(/\n/, "<br />\n", x)
+  return x
+}
+
+# Honor newlines escaped in PO msgids an mststrs.
+function make_po_breaks(x)
+{
+  gsub(/\\n/, "<br />\n", x)
+  return x
+}
+
+# Fill output array out with links from array.
+# The items of array are strings like
+# "http://link.org";>text...</a> more text...
+# The function puts http://link.org in the out array
+# (the number of entries is put to out[0]).
+# n is the length of the input array,
+# label is only used to report where errors occur.
+function list_attr(array, n, label, out,
+  delimiter, j, l)
+{
+  delete out
+  j = 1
+  for (i = 2; i <= n; i++)
+    {
+      delimiter = substr(links[i], 1, 1)
+      l = index(substr(links[i], 2), delimiter)
+      if (l < 1)
+        {
+          print "No closing " delimiter " found in " \
+                label " " links[i] > "/dev/stderr"
+          continue
+        }
+      out[j++] = substr(links[i], 2, l - 1)
+    }
+  out[0] = j
+}
+
+# Like split, but also fill the idx array with the indices
+# of matched strings.
+function split_with_pos(txt, links, idx, regex,
+  n, t, i)
+{
+  t = txt; n = 1; i = 1
+  while (match(t, regex))
+    {
+      links[n] = substr(t, 1, RSTART + RLENGTH - 1)
+      i += RSTART + RLENGTH - 1
+      idx[n] = i + 1
+      t = substr (t, RSTART + RLENGTH)
+      n++
+    }
+  links[n] = t
+  idx[n] = i
+  return n
+}
+
+# Find HTML links in the text.
+# txt - input text
+# out - output array with links
+# pos - output array of respective link positions
+function get_links(txt, out, pos,
+  n)
+{
+  n = split_with_pos(txt, links, pos,
+            "[&]lt;a[ \t\r\n]+([^&]*[ \t\r\n]+?)href[ \t\r\n]*=[ \t\r\n]*")
+  list_attr(links, n, "link", out)
+}
+
+# Find HTML ids and names in the text.
+# txt - input text
+# out - output array with ids
+# pos - output array of respective id positions
+function get_ids(txt, out, pos,
+  n)
+{
+  n = split_with_pos(txt, links, pos,
+            "[&]lt;[^&]*[ \t\r\n]+(id|name)[ \t\r\n]*=[ \t\r\n]*")
+  list_attr(links, n, "id", out)
+}
+
+# Compile difference between the set of links in msgid (orig_links
+# at orig_pos) and the set of links in translations (trans_links
+# at trans_pos).  Links to CC licenses are adjusted according to
+# language code lang.
+# The return value is a diff string like
+# -pos0:link0
+# +pos1:link1
+function diff_attr_set(orig_links, orig_pos, trans_links, trans_pos, lang,
+  i, j, k, vex, out, msgid_links)
+{
+  msgid_links[0] = orig_links[0]
+  for (i = 0; i < orig_links[0]; i++)
+    {
+      msgid_links[i] = orig_links[i]
+      if (!lang)
+        continue
+      if (msgid_links[i] ~ \
+/^(http(s?):?)\/\/creativecommons.org\/licenses\/by-(nd|sa)\/(3\.0((\/us)?)|4\.0)\/$/)
+         msgid_links[i] = msgid_links[i] "deed." lang
+    }
+  i = 1; j = 1
+  out = ""
+  while (i < msgid_links[0] && j < trans_links[0])
+    {
+      id_link = msgid_links[i]
+      if (verbose_diff)
+        out = out "&:" i "[" orig_pos[i] "]:" j "[" trans_pos[j] "]:" \
+              orig_links[i] ":" trans_links[j] "\n"
+      if (msgid_links[i] == trans_links[j])
+        {
+          if (verbose_diff)
+            out = out "0:" orig_pos[i] ":" trans_pos[j] ":" \
+                  orig_links[i] "\n"
+          i++; j++
+          continue
+        }
+      vex = 0
+      for (k = 1; i + k < msgid_links[0]; k++)
+        if (msgid_links[i + k] == trans_links[j])
+          {
+            vex = 1
+            while (k--)
+              {
+                out = out "-" orig_pos[i] ":" orig_links[i] "\n"
+                i++
+              }
+            break
+          }
+      if (!vex)
+        for (k = 1; j + k < trans_links[0]; k++)
+          if (msgid_links[i] == trans_links[j + k])
+            {
+              vex = !0
+              while (k--)
+                {
+                  out = out "+" trans_pos[j] ":" trans_links[j] "\n"
+                  j++
+                }
+              break
+            }
+      if (!vex)
+        {
+          out = out "-" orig_pos[i] ":" orig_links[i] "\n"
+          i++
+          out = out "+" trans_pos[j] ":" trans_links[j] "\n"
+          j++
+        }
+    }
+  while (i < msgid_links[0])
+    {
+      out = out "-" orig_pos[i] ":" orig_links[i] "\n"
+      i++
+    }
+  while (j < trans_links[0])
+    {
+      out = out "+" trans_pos[j] ":" trans_links[j] "\n"
+      j++
+    }
+  if (out != "") # Strip trailing newline.
+    out = substr(out, 1, length(out) - 1)
+  return out
+}
+
+# Assign link_diff and id_diff items for the next PO entry.
+# link_diff is difference in the set of links,
+# id_diff is difference in the set of ids of original string vs translation.
+function process_entry( \
+  n, msgid_links, trans_links, msgid_pos, trans_pos, i)
+{
+  n = msg_no++
+  comments[n] = escape_chars(substr(comment, 2)); comment = ""
+  msg_ids[n] = make_po_breaks(escape_chars(msgid)); msgid = ""
+  msg_strs[n] = make_po_breaks(escape_chars(msgstr)); msgstr = ""
+  link_diff[n] = id_diff[n] = ""
+  if (msg_ids[n] == "")
+    return
+  get_links(msg_ids[n], msgid_links, msgid_pos)
+  get_links(msg_strs[n], trans_links, trans_pos)
+  link_diff[n] = diff_attr_set(msgid_links, msgid_pos, trans_links,
+                               trans_pos, language)
+  get_ids(msg_ids[n], msgid_links, msgid_pos)
+  get_ids(msg_strs[n], trans_links, trans_pos)
+  id_diff[n] = diff_attr_set(msgid_links, msgid_pos, trans_links, trans_pos, 
"")
+}
+
+# Parse difference diff to array of positions pos and array of links
+# links, filtering the differences starting with one-letter prefix.
+function parse_diff(diff, pos, links, prefix,
+  i, j, n, p, t)
+{
+  n = split(diff, t, "\n")
+  j = 0
+  for (i = 1; i <= n; i++)
+    {
+      if (substr(t[i], 1, 1) != prefix)
+        continue
+      p = index(t[i], ":")
+      pos[j] = substr(t[i], 2, p - 2) - 1
+      links[j++] = substr(t[i], p + 1)
+    }
+  return j
+}
+
+# Merge two difference strings to single string with
+# prefix '0' for diff0 and '1' for diff1.
+function merge_diffs(diff0, diff1, prefix,
+  i0, i1, n0, n1, pos0, pos1, links0, links1, sum)
+{
+  n0 = parse_diff(diff0, pos0, links0, prefix)
+  n1 = parse_diff(diff1, pos1, links1, prefix)
+  sum = ""
+  i0 = i1 = 0
+  while (i0 < n0 || i1 < n1)
+    if (i0 < n0 && (i1 == n1 || pos0[i0] < pos1[i1]))
+      {
+        sum = sum "\n0" pos0[i0] ":" links0[i0]
+        i0++
+      }
+    else
+      {
+        sum = sum "\n1" pos1[i1] ":" links1[i1]
+        i1++
+      }
+  return substr(sum, 2)
+}
+
+# Return text highlighted according to merged difference diff
+# using HTML tags given in the tags array.
+function highlight(text, diff, tags,
+  i, t_idx, n, t, a, pos, len, p, out)
+{
+  n = split(diff, t, "\n")
+  a = 0; out = ""
+  for (i = 1; i <= n; i++)
+    {
+      idx = substr(t[i], 1, 1)
+      p = index(t[i], ":")
+      pos = substr(t[i], 2, p - 2) + a
+      len = length(t[i]) - p
+      text = substr(text, 1, pos) "<" tags[idx] ">" substr(text, pos + 1, len) 
\
+            "</" tags[idx] ">" substr(text, pos + len + 1)
+      a = a + length("<" tags[idx] ">" "</" tags[idx] ">")
+    }
+  return text
+}
+
+# Suppress certain differences:
+# * Local links from translations to ids defined in translator's notes
+#   are allowed.
+# * Local (back) links from translator's notes to ids additionally
+#   defined in translations are allowed.
+# * Links from translator's credits are allowed.
+function pacify_translator_notes(\
+ i, j, n, m, trans_notes, back_trans_notes, tn, tn_i, t, link, k)
+{
+  trans_notes = ""
+  back_trans_notes = ""
+  for (i = 0; i < msg_no; i++)
+    if (msg_ids[i] == "*GNUN-SLOT: TRANSLATOR'S NOTES*")
+      {
+        trans_notes = id_diff[i]
+        back_trans_notes = link_diff[i]
+        gsub(/(^|\n)[+][^:]*:[^#][^\n]*/, "", back_trans_notes)
+        gsub(/(^|\n)[-][^:]*:[^\n]*/, "", back_trans_notes)
+        gsub(/\n\n+/, "\n", back_trans_notes)
+        gsub(/(^|\n)[+][^:]*:[#][^\n]*/, "", link_diff[i])
+        gsub(/\n\n+/, "\n", link_diff[i])
+        tn_i = i
+      }
+    else if (msg_ids[i] == "*GNUN-SLOT: TRANSLATOR'S CREDITS*")
+      link_diff[i] = ""
+  if (trans_notes == "")
+    return
+  n = split(trans_notes, tn, "\n")
+  for (i = 1; i <= n; i++)
+    sub(/[^:]*:/, "", tn[i])
+  for (i = 0; i < msg_no; i++)
+    {
+      m = split(link_diff[i], t, "\n")
+      for (j = 1; j <= m; j++)
+        {
+          if (substr(t[j], 1, 1) != "+")
+            continue
+          link = t[j]
+          sub(/.*:/, "", link)
+          for (k = 1; k <= n; k++)
+            if ("#" tn[k] == link)
+              {
+                t[j] = ""
+                break
+              }
+        }
+      link_diff[i] = ""
+      for (j = 1; j <= m; j++)
+        if (t[j] != "")
+          link_diff[i] = link_diff[i] "\n" t[j]
+      link_diff[i] = substr(link_diff[i], 2)
+    }
+  n = split(back_trans_notes, tn, "\n")
+  for (i = 1; i <= n; i++)
+    sub(/[^:]*:/, "", tn[i])
+  for (i = 0; i < msg_no; i++)
+    {
+      m = split(id_diff[i], t, "\n")
+      for (j = 1; j <= m; j++)
+        {
+          if (substr(t[j], 1, 1) != "+")
+            continue
+          link = t[j]
+          sub(/.*:/, "", link)
+          for (k = 1; k <= n; k++)
+            if (tn[k] == "#" link)
+              {
+                t[j] = ""
+                break
+              }
+        }
+      id_diff[i] = ""
+      for (j = 1; j <= m; j++)
+        if (t[j] != "")
+          id_diff[i] = id_diff[i] "\n" t[j]
+      id_diff[i] = substr(id_diff[i], 2)
+    }
+  id_diff[tn_i] = ""
+}
+
+# Count the number of unmatched links; differences in mailto: are skipped.
+function count_link_diffs(\
+  i, j, n, cnt, d)
+{
+  cnt = 0
+  for (i = 0; i < msg_no; i++)
+    {
+      n = split(link_diff[i], d, "\n")
+      for (j = 1; j <= n; j++)
+        if (d[j] !~ /[^:]*:mailto:/)
+          cnt++
+    }
+  return cnt
+}
+
+# Count the number of unmatched ids.
+function count_id_diffs(\
+  i, cnt, d)
+{
+  cnt = 0
+  for (i = 0; i < msg_no; i++)
+    cnt += split(id_diff[i], d, "\n")
+  return cnt
+}
+
+# Start parsing msgid.
+/^msgid "/ {
+  state = "msgid"
+  sub(/^msgid "/, "")
+  sub(/"[ \t\r\n]*$/, "")
+  msgid = $0
+  next
+}
+
+# Start parsing translation.
+/^msgstr "/ {
+  state = "msgstr"
+  sub(/^msgstr "/, "")
+  sub(/"[ \t\r\n]*$/, "")
+  msgstr = $0
+  next
+}
+
+# Empty string: put entry into arrays.
+/^[ \t\r\n]*$/ {
+  process_entry()
+  next
+}
+
+# Skip specific PO4A comments.
+/^# type: (Content|Attribute .*) of: / { next }
+
+# Parse comment.
+/^#( |[.] TRANSLATORS)/ {
+  c = $0
+  sub(/#( |[.] )/, "", c)
+  comment = comment "\n" c
+  next
+}
+
+# Parse multiline item (msgid or translation).
+/^"/ {
+  sub(/^"/, "")
+  sub(/"[ \t\r\n]*$/, "")
+  if(state == "msgid")
+    msgid = msgid $0
+  else
+    msgstr = msgstr $0
+}
+
+# Nothing useful should be left; skip, if anything.
+{ next }
+
+# Output HTML.
+END {
+  if(msgid != "")
+    process_entry()
+  pacify_translator_notes()
+  output = "<html><head>\n"
+  output = output \
+"<meta http-equiv='content-type' content='text/html; charset=utf-8' />\n"
+  if (title)
+    output = output "<title>" title "</title>\n"
+  output = output "<style type='text/css' media='print,screen'>\n<!--\n"
+  output = output ".select, td strong.select { background: springgreen; }\n"
+  output = output "td strong { background: lightsalmon; }\n"
+  output = output "td em { background: aqua; }\n"
+  output = output "td.com { background: springgreen; }\n"
+  output = output "-->\n</style>\n"
+  output = output "</head><body>\n"
+  if (title)
+    output = output "<h2>" title "</h2>\n"
+  l_cnt = count_link_diffs()
+  i_cnt = count_id_diffs()
+  output = output "<p>Mismatched links: "  l_cnt ".</p>\n"
+  output = output "<p>Mismatched ids: "  i_cnt ".</p>\n"
+  output = output "<table border='1'>\n"
+  output = output "<tr><th>#</th><th>text</th>\n"
+  tags[0] = "strong"
+  tags[1] = "em"
+  for (i = 0; i < msg_no; i++)
+    {
+      if (!(link_diff[i] || id_diff[i] || output_all))
+        continue
+      i_text = i
+      tr_class = ""
+      if (id_diff[i] || link_diff[i])
+        {
+          i_text = "<strong class='select'>" i_text "</strong>"
+          tr_class = " class='select'"
+        }
+      output = output "<tr><td" tr_class " rowspan='3'>" i_text "</td>\n"
+      output = output "<td class='com'>\n"
+      output = output comments[i] "&nbsp;\n"
+      output = output "</td>\n</tr>\n<tr><td class='msgid'>\n"
+      diff = merge_diffs(link_diff[i], id_diff[i], "-")
+      output = output highlight(msg_ids[i], diff, tags) "&nbsp;\n"
+      output = output "</td>\n</tr>\n<tr><td class='msgstr'>\n"
+      diff = merge_diffs(link_diff[i], id_diff[i], "+")
+      output = output highlight(msg_strs[i], diff, tags) "&nbsp;\n"
+      output = output "</td>\n</tr>\n"
+    }
+  output = output "</table>\n"
+  output = output "</body>"
+  print output
+  if (l_cnt || i_cnt)
+    exit 1
+  exit 0
+}



reply via email to

[Prev in Thread] Current Thread [Next in Thread]