[PATCH 3/6] Check that the Pango markup in glade files is valid

David Shea dshea at redhat.com
Thu Jan 9 18:31:10 UTC 2014


When run with --translate, the script will also check the translations
of markup strings.
---
 tests/Makefile.am                      |   5 +-
 tests/glade/markup/check_markup.py     | 125 +++++++++++++++++++++++++++++++++
 tests/glade/markup/run_check_markup.sh |  21 ++++++
 3 files changed, 150 insertions(+), 1 deletion(-)
 create mode 100755 tests/glade/markup/check_markup.py
 create mode 100755 tests/glade/markup/run_check_markup.sh

diff --git a/tests/Makefile.am b/tests/Makefile.am
index cfebc7c..d67bf13 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -43,6 +43,8 @@ dist_check_SCRIPTS = glade/accelerators/check_accelerators.py \
 		     glade/validity/check_glade_validity.py \
 		     glade/validity/run_check_glade_validity.sh \
 		     $(srcdir)/lib/*.py \
+		     glade/markup/check_markup.py \
+		     glade/markup/run_check_markup.sh \
 		     nosetests.sh \
 		     pylint/intl.py \
 		     pylint/preconf.py \
@@ -63,7 +65,8 @@ TESTS = nosetests.sh \
 	storage/run_storage_tests.py \
 	glade/accelerators/run_check_accelerators.sh \
 	glade/pw_visibility/run_check_pw_visibility.sh \
-	glade/validity/run_check_glade_validity.sh
+	glade/validity/run_check_glade_validity.sh \
+	glade/markup/run_check_markup.sh
 
 clean-local:
 	-rm -rf pylint/.pylint.d
diff --git a/tests/glade/markup/check_markup.py b/tests/glade/markup/check_markup.py
new file mode 100755
index 0000000..2778a7e
--- /dev/null
+++ b/tests/glade/markup/check_markup.py
@@ -0,0 +1,125 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2014  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Shea <dshea at redhat.com>
+#
+
+"""
+Python script to check that properties in glade using Pango markup contain
+valid markup.
+"""
+
+import sys
+import argparse
+
+# Import translation methods if needed
+if ('-t' in sys.argv) or ('--translate' in sys.argv):
+    try:
+        from translatepo import translate_all
+    except ImportError:
+        print("Unable to load po translation module")
+        sys.exit(99)
+
+from pangocheck import markup_nodes, markup_match
+
+try:
+    from lxml import etree
+except ImportError:
+    print("You need to install the python-lxml package to use check_markup.py")
+    sys.exit(99)
+
+class PangoElementException(Exception):
+    def __init__(self, element):
+        Exception.__init__(self)
+        self.element = element
+
+    def __str__(self):
+        return "Invalid element %s" % self.element
+
+# Raises a PangoElementException if the pango markup contains unknown elements
+def _validate_pango_markup(root):
+    if root.tag not in markup_nodes:
+        raise PangoElementException(root.tag)
+
+    for child in root:
+        _validate_pango_markup(child)
+
+def check_glade_file(glade_file_path, po_map=None):
+    glade_success = True
+    with open(glade_file_path) as glade_file:
+        # Parse the XML
+        glade_tree = etree.parse(glade_file)
+
+        # Search for label properties on objects that have use_markup set to True
+        for label in glade_tree.xpath(".//property[@name='label' and ../property[@name='use_markup']/text() = 'True']"):
+            if po_map:
+                try:
+                    label_texts = po_map.get(label.text, label.get("context"))
+                except KeyError:
+                    continue
+                lang_str = " for language %s" % po_map.metadata['Language']
+            else:
+                label_texts = (label.text,)
+                lang_str = ""
+
+            # Wrap the label text in <markup> tags and parse the tree
+            for label_text in label_texts:
+                try:
+                    # pylint: disable-msg=W9922
+                    pango_tree = etree.fromstring("<markup>%s</markup>" % label_text)
+                    _validate_pango_markup(pango_tree)
+                except etree.XMLSyntaxError:
+                    print("Unable to parse pango markup at %s%s:%d" % \
+                            (glade_file_path, lang_str, label.sourceline))
+                    glade_success = False
+                except PangoElementException as px:
+                    print("Invalid pango element %s at %s%s:%d" % \
+                            (px.element, glade_file_path, lang_str, label.sourceline))
+                    glade_success = False
+                else:
+                    if po_map:
+                        # Check that translated markup has the same elements and attributes
+                        if not markup_match(label.text, label_text):
+                            print("Translated markup does not contain the same elements and attributes at %s%s:%d" % \
+                                    (glade_file_path, lang_str, label.sourceline))
+                            glade_success = False
+    return glade_success
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser("Check Pango markup validity")
+    parser.add_argument("-t", "--translate", action='store_true',
+            help="Check translated strings")
+    parser.add_argument("-p", "--podir", action='store', type=str,
+            metavar='PODIR', help='Directory containing po files', default='./po')
+    parser.add_argument("glade_files", nargs="+", metavar="GLADE-FILE",
+            help='The glade file to check')
+    args = parser.parse_args(args=sys.argv[1:])
+
+    success = True
+    for file_path in args.glade_files:
+        if not check_glade_file(file_path):
+            success = False
+
+    # Now loop over all of the translations
+    if args.translate:
+        podicts = translate_all(args.podir)
+        for po_dict in podicts.values():
+            for file_path in args.glade_files:
+                if not check_glade_file(file_path, po_dict):
+                    success = False
+
+    sys.exit(0 if success else 1)
diff --git a/tests/glade/markup/run_check_markup.sh b/tests/glade/markup/run_check_markup.sh
new file mode 100755
index 0000000..7448dc1
--- /dev/null
+++ b/tests/glade/markup/run_check_markup.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+: "${top_srcdir:=$(dirname "$0")/../../..}"
+. "${top_srcdir}/tests/testenv.sh"
+srcdir="${top_srcdir}/tests/glade/markup"
+
+translate_set=0
+podir_set=0
+for arg in "$@" ; do
+    if [ "$arg" = "--translate" -o "$arg" = "-t" ]; then
+        translate_set=1
+    elif [ "$arg" = "--podir" -o "$arg" = "-p" ]; then
+        podir_set=1
+    fi
+done
+
+if [ "$translate_set" -eq 1 -a "$podir_set" -eq 0 ]; then
+    set -- "$@" --podir "${top_srcdir}/po"
+fi
+
+find "${top_srcdir}/pyanaconda" -name '*.glade' -exec "${srcdir}/check_markup.py" "$@" {} +
-- 
1.8.5.2



More information about the anaconda-patches mailing list