Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/chameleon/i18n.py : 26%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1##############################################################################
2#
3# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
4# All Rights Reserved.
5#
6# This software is subject to the provisions of the Zope Public License,
7# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
8# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
9# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
11# FOR A PARTICULAR PURPOSE.
12#
13##############################################################################
15import re
17from .exc import CompilationError
18from .utils import unicode_string
20NAME_RE = r"[a-zA-Z][-a-zA-Z0-9_]*"
22WHITELIST = frozenset([
23 "translate",
24 "domain",
25 "context",
26 "target",
27 "source",
28 "attributes",
29 "data",
30 "name",
31 "mode",
32 "xmlns",
33 "xml",
34 "comment",
35 "ignore",
36 "ignore-attributes",
37 ])
39_interp_regex = re.compile(r'(?<!\$)(\$(?:(%(n)s)|{(%(n)s)}))'
40 % ({'n': NAME_RE}))
43try: # pragma: no cover
44 str = unicode
45except NameError:
46 pass
48# BBB: The ``fast_translate`` function here is kept for backwards
49# compatibility reasons. Do not use!
51try: # pragma: no cover
52 from zope.i18n import interpolate
53 from zope.i18n import translate
54 from zope.i18nmessageid import Message
55except ImportError: # pragma: no cover
56 pass
57else: # pragma: no cover
58 def fast_translate(msgid, domain=None, mapping=None, context=None,
59 target_language=None, default=None):
60 if msgid is None:
61 return
63 if target_language is not None or context is not None:
64 result = translate(
65 msgid, domain=domain, mapping=mapping, context=context,
66 target_language=target_language, default=default)
67 if result != msgid:
68 return result
70 if isinstance(msgid, Message):
71 default = msgid.default
72 mapping = msgid.mapping
74 if default is None:
75 default = str(msgid)
77 if not isinstance(default, basestring):
78 return default
80 return interpolate(default, mapping)
83def simple_translate(msgid, domain=None, mapping=None, context=None,
84 target_language=None, default=None):
85 if default is None:
86 default = getattr(msgid, "default", msgid)
88 if mapping is None:
89 mapping = getattr(msgid, "mapping", None)
91 if mapping:
92 def replace(match):
93 whole, param1, param2 = match.groups()
94 return unicode_string(mapping.get(param1 or param2, whole))
95 return _interp_regex.sub(replace, default)
97 return default
100def parse_attributes(attrs, xml=True):
101 d = {}
103 # filter out empty items, eg:
104 # i18n:attributes="value msgid; name msgid2;"
105 # would result in 3 items where the last one is empty
106 attrs = [spec for spec in attrs.split(";") if spec]
108 for spec in attrs:
109 if ',' in spec:
110 raise CompilationError(
111 "Attribute must not contain comma. Use semicolon to "
112 "list multiple attributes", spec
113 )
114 parts = spec.split()
115 if len(parts) == 2:
116 attr, msgid = parts
117 elif len(parts) == 1:
118 attr = parts[0]
119 msgid = None
120 else:
121 raise CompilationError(
122 "Illegal i18n:attributes specification.", spec)
123 if not xml:
124 attr = attr.lower()
125 attr = attr.strip()
126 if attr in d:
127 raise CompilationError(
128 "Attribute may only be specified once in i18n:attributes", attr)
129 d[attr] = msgid
131 return d