File indexing completed on 2024-05-12 05:47:03

0001 # -*- coding: UTF-8 -*
0002 
0003 """
0004 Resolve trapnakron references in translations.
0005 
0006 @author: Chusslove Illich (Часлав Илић) <caslav.ilic@gmx.net>
0007 @license: GPLv3
0008 """
0009 
0010 from pology import PologyError
0011 import pology.lang.sr.trapnakron as T
0012 from pology.comments import manc_parse_list
0013 from pology.markup import xml_entities, html_entities
0014 from pology.resolve import resolve_entities
0015 
0016 
0017 _known_cons = {}
0018 def _get_names ():
0019     _known_cons[""] = T.trapnakron # base constructor
0020     for name in dir(T): # specialized constructors
0021         if name.startswith("trapnakron_"):
0022             _known_cons[name[len("trapnakron_"):]] = getattr(T, name)
0023 _get_names()
0024 
0025 
0026 def froments (name, args=(), kwargs={}, vfilter=None, testsub=False):
0027     """
0028     Resolve trapnakron references in translation using XML entity format
0029     [hook factory].
0030 
0031     If an entity cannot be resolved as trapnakron reference,
0032     warning is output and the entity is left unresolved.
0033     Instead of leaving the entity unresolved, an illustrative expansion
0034     for the property key given by the reference can be substituted
0035     by setting the C{testsub} parameter to C{True}.
0036 
0037     Entities in a given message can be manually ignored through
0038     C{ignore-entity:} translation comment, which contains
0039     comma-separated list of entity names::
0040 
0041         # ignore-entity: foo, bar
0042         msgid "Blah, blah, &foo;, blah, blah, &bar;."
0043         msgstr "Бла, бла, &foo;, бла, бла, &bar;."
0044 
0045     Standard XML and HTML entities are ignored by default.
0046 
0047     @param name: suffix of trapnakron constructor,
0048         e.g. "ui" for L{trapnakron_ui<lang.sr.trapnakron.trapnakron_ui>}
0049     @type name: string
0050     @param args: positional arguments to send to the constructor
0051     @type args: tuple
0052     @param kwargs: keyword arguments to send to the constructor
0053     @type kwargs: dict
0054     @param vfilter: format string (with single C{%s} directive) or function
0055         to apply to every resolved reference
0056     @type vfilter: string or (string)->string
0057     @param testsub: whether to substitute test forms in place of
0058         undefined references
0059     @type testsub: bool
0060 
0061     @return: type F3C hook
0062     @rtype: C{(msgstr, msg, cat) -> msgstr}
0063     """
0064 
0065     trapcon = _known_cons.get(name)
0066     if trapcon is None:
0067         raise PologyError(
0068             _("@info \"trapnakron\" is a shorthand for "
0069               "\"Transcriptions and Translations of Names and Acronyms\" "
0070               "in Serbian",
0071               "Unknown trapnakron constructor '%(name)s'.",
0072               name=name))
0073 
0074     tp = trapcon(*args, **kwargs)
0075 
0076     # Setup dummy replacement for undefined references.
0077     undefrepl = None
0078     if testsub:
0079         dkeysub1 = "__test1234a__"
0080         dkeysub2 = "__test1234b__"
0081         tp.import_string("""
0082         >%s/base/aff.sd
0083         %s: лопт|а, лопт|е+2, лопт|ин, лопта|сти
0084         %s: ваљ|ак, ваљ|ци+, ваљк|ов, ваљка|сти
0085         """ % (T.rootdir(), dkeysub1, dkeysub2))
0086         def undefrepl (ref):
0087             res = ref.rsplit("-", 1)
0088             if len(res) != 2:
0089                 return None
0090             dkey, pkey = res
0091             if pkey == "":
0092                 pkey = "n"
0093             dkeysub = dkeysub1
0094             if len(pkey) == 2 and pkey.endswith("k"):
0095                 dkeysub = dkeysub2
0096             ckeysub = dkeysub + "-" + pkey
0097             return tp[ckeysub].upper()
0098 
0099     # Entitites normally ignored on resolution.
0100     # FIXME: This should go by markup type advertised in catalog header.
0101     ignored_refs = {}
0102     ignored_refs.update(xml_entities)
0103     ignored_refs.update(html_entities)
0104 
0105     def hook (msgstr, msg, cat):
0106 
0107         srcstr = "%s:%d(%d)" % (cat.filename, msg.refline, msg.refentry)
0108 
0109         locally_ignored = manc_parse_list(msg, "ignore-entity:", ",")
0110         if locally_ignored:
0111             ignored_refs_mod = ignored_refs.copy()
0112             ignored_refs_mod.update([(x, None) for x in locally_ignored])
0113         else:
0114             ignored_refs_mod = ignored_refs
0115 
0116         res = resolve_entities(msgstr, tp, ignored_refs_mod,
0117                                srcname=srcstr, vfilter=vfilter,
0118                                undefrepl=undefrepl)
0119         msgstr, resolved, unknown = res
0120 
0121         return msgstr
0122 
0123     return hook
0124 
0125 
0126 _froments_t1_hook = None
0127 
0128 def froments_t1 (msgstr, msg, cat):
0129     """
0130     A testing specialization of L{froments}: C{name="ui"},
0131     C{vfilter="^%s"}, C{testsub=True} [type F3C hook].
0132     """
0133 
0134     global _froments_t1_hook
0135     if not _froments_t1_hook:
0136         _froments_t1_hook = froments("ui", vfilter="^%s", testsub=True)
0137 
0138     return _froments_t1_hook(msgstr, msg, cat)
0139 
0140 
0141 def froments_t1db (msgstr, msg, cat):
0142     """
0143     A testing specialization of L{froments}: C{name="docbook4"},
0144     C{vfilter="^%s"}, C{testsub=True} [type F3C hook].
0145     """
0146 
0147     global _froments_t1_hook
0148     if not _froments_t1_hook:
0149         _froments_t1_hook = froments("docbook4", vfilter="^%s", testsub=True)
0150 
0151     return _froments_t1_hook(msgstr, msg, cat)
0152