def test_markup(mofile): mo = polib.mofile(mofile) for entry in mo.translated_entries(): if is_markup(entry.msgid): # If this is a plural, check each of the plural translations if entry.msgid_plural: for plural_id, msgstr in entry.msgstr_plural.items(): if not markup_match(entry.msgid, msgstr): raise AssertionError( "Markup does not match for %d translation of msgid %s" % (plural_id, entry.msgid) ) elif not markup_match(entry.msgid, entry.msgstr): raise AssertionError("Markup does not match for msgid %s" % entry.msgid)
def test_markup(mofile): mo = polib.mofile(mofile) for entry in mo.translated_entries(): if is_markup(entry.msgid): # If this is a plural, check each of the plural translations if entry.msgid_plural: xlations = entry.msgstr_plural else: xlations = {None: entry.msgstr} for plural_id, msgstr in xlations.items(): # Check if the markup is valid at all try: # pylint: disable=unescaped-markup ET.fromstring('<markup>%s</markup>' % msgstr) except ET.ParseError: if entry.msgid_plural: raise AssertionError("Invalid markup translation for %d translation of msgid %s" % (plural_id, entry.msgid)) else: raise AssertionError("Invalid markup translation for msgid %s" % entry.msgid) # Check if the markup has the same number and kind of tags if not markup_match(entry.msgid, msgstr): if entry.msgid_plural: raise AssertionError("Markup does not match for %d translation of msgid %s" % (plural_id, entry.msgid)) else: raise AssertionError("Markup does not match for msgid %s" % entry.msgid)
def test_markup(pofile): po = polib.pofile(pofile) for entry in po.translated_entries(): if is_markup(entry.msgid): # If this is a plural, check each of the plural translations if entry.msgid_plural: xlations = entry.msgstr_plural else: xlations = {None: entry.msgstr} for plural_id, msgstr in xlations.items(): # Check if the markup is valid at all try: # pylint: disable=unescaped-markup ET.fromstring('<markup>%s</markup>' % msgstr) except ET.ParseError: if entry.msgid_plural: raise AssertionError("Invalid markup translation for %d translation of msgid %s\n%s" % (plural_id, entry.msgid, msgstr)) else: raise AssertionError("Invalid markup translation for msgid %s\n%s" % (entry.msgid, msgstr)) # Check if the markup has the same number and kind of tags if not markup_match(entry.msgid, msgstr): if entry.msgid_plural: raise AssertionError("Markup does not match for %d translation of msgid %s\n%s" % (plural_id, entry.msgid, msgstr)) else: raise AssertionError("Markup does not match for msgid %s\n%s" % (entry.msgid, msgstr))
def checkGlade(self, glade_tree): """Check the validity of Pango markup.""" lang = glade_tree.getroot().get("lang") if lang: lang_str = " for language %s" % lang else: lang_str = "" # 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']"): # Wrap the label text in <markup> tags and parse the tree try: # pylint: disable=unescaped-markup pango_tree = etree.fromstring("<markup>%s</markup>" % label.text) _validate_pango_markup(pango_tree) # Check if the markup is necessary self.assertTrue(markup_necessary(pango_tree), msg="Markup %s could be expressed as attributes at %s%s:%d" % (label.text, label.base, lang_str, label.sourceline)) except etree.XMLSyntaxError: raise AssertionError("Unable to parse pango markup %s at %s%s:%d" % (label.text, label.base, lang_str, label.sourceline)) except PangoElementException as px: raise AssertionError("Invalid pango element %s at %s%s:%d" % (px.element, label.base, lang_str, label.sourceline)) # If this is a translated node, check that the translated markup # has the same elements and attributes as the original. orig_markup = label.get("original_text") if orig_markup: self.assertTrue(markup_match(label.text, orig_markup), msg="Translated markup %s does not contain the same elements and attributes at %s%s:%d" % (label.text, label.base, lang_str, label.sourceline))
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=unescaped-markup pango_tree = etree.fromstring("<markup>%s</markup>" % label_text) _validate_pango_markup(pango_tree) # Check if the markup is necessary if not markup_necessary(pango_tree): print( "Markup could be expressed as attributes at %s%s:%d" % (glade_file_path, lang_str, label.sourceline) ) glade_success = False 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
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=unescaped-markup pango_tree = etree.fromstring("<markup>%s</markup>" % label_text) _validate_pango_markup(pango_tree) # Check if the markup is necessary if not markup_necessary(pango_tree): print("Markup could be expressed as attributes at %s%s:%d" % \ (glade_file_path, lang_str, label.sourceline)) glade_success = False 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
def _check_markup(self, glade_tree): """Check the validity of Pango markup.""" lang = glade_tree.getroot().get("lang") if lang: lang_str = " for language %s" % lang else: lang_str = "" # 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']" ): # Wrap the label text in <markup> tags and parse the tree try: # pylint: disable=unescaped-markup pango_tree = etree.fromstring("<markup>%s</markup>" % label.text) _validate_pango_markup(pango_tree) # Check if the markup is necessary self.assertTrue( markup_necessary(pango_tree), msg="Markup %s could be expressed as attributes at %s%s:%d" % (label.text, label.base, lang_str, label.sourceline)) except etree.XMLSyntaxError as xx: raise AssertionError( "Unable to parse pango markup %s at %s%s:%d" % (label.text, label.base, lang_str, label.sourceline)) from xx except PangoElementException as px: raise AssertionError("Invalid pango element %s at %s%s:%d" % (px.element, label.base, lang_str, label.sourceline)) from px # If this is a translated node, check that the translated markup # has the same elements and attributes as the original. orig_markup = label.get("original_text") if orig_markup: self.assertTrue( markup_match(label.text, orig_markup), msg= "Translated markup %s does not contain the same elements and attributes at %s%s:%d" % (label.text, label.base, lang_str, label.sourceline))
def visit_const(self, node): if not isinstance(node.value, (str, bytes)): return if not is_markup(node.value): return self._validate_pango_markup_string(node, node.value) # Check translated versions of the string if requested if self.config.translate_markup: global podicts # Check if this is a translatable string curr = node i18nFunc = None while curr.parent: if isinstance(curr.parent, astroid.CallFunc) and \ getattr(curr.parent.func, "name", "") in i18n_funcs: i18nFunc = curr.parent break curr = curr.parent if i18nFunc: # If not done already, import polib and read the translations if not podicts: try: from pocketlint.translatepo import translate_all except ImportError: print("Unable to load po translation module") sys.exit(99) else: podicts = translate_all(os.path.join(os.environ.get('top_srcdir', '.'), 'po')) if i18nFunc.func.name in i18n_ctxt_funcs: msgctxt = i18nFunc.args[0].value else: msgctxt = None # Loop over all translations for the string for podict in podicts.values(): try: node_values = podict.get(node.value, msgctxt) except KeyError: continue for value in node_values: self._validate_pango_markup_string(node, value, podict.metadata['Language']) # Check that the markup matches, roughly if not markup_match(node.value, value): self.add_message("W9925", node=node, args=(podict.metadata['Language'],)) # Check if this the left side of a % operation curr = node formatOp = None while curr.parent: if isinstance(curr.parent, astroid.BinOp) and curr.parent.op == "%" and \ curr.parent.left == curr: formatOp = curr.parent break curr = curr.parent # Check whether the right side of the % operation is escaped if formatOp: if isinstance(formatOp.right, astroid.CallFunc): if getattr(formatOp.right.func, "name", "") not in escapeMethods: self.add_message("W9922", node=formatOp.right) # If a tuple, each item in the tuple must be escaped elif isinstance(formatOp.right, astroid.Tuple): for elt in formatOp.right.elts: if not isinstance(elt, astroid.CallFunc) or\ getattr(elt.func, "name", "") not in escapeMethods: self.add_message("W9922", node=elt) # If a dictionary, each value must be escaped elif isinstance(formatOp.right, astroid.Dict): for item in formatOp.right.items: if not isinstance(item[1], astroid.CallFunc) or\ getattr(item[1].func, "name", "") not in escapeMethods: self.add_message("W9922", node=item[1]) else: self.add_message("W9922", node=formatOp)