1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """functions used to manipulate access keys in strings"""
23
24 from translate.storage.placeables.general import XMLEntityPlaceable
25
26 DEFAULT_ACCESSKEY_MARKER = u"&"
27
28
30 """Extract the label and accesskey from a label+accesskey string
31
32 The function will also try to ignore &entities; which would obviously not
33 contain accesskeys.
34
35 @type string: Unicode
36 @param string: A string that might contain a label with accesskey marker
37 @type accesskey_marker: Char
38 @param accesskey_marker: The character that is used to prefix an access key
39 """
40 assert isinstance(string, unicode)
41 assert isinstance(accesskey_marker, unicode)
42 assert len(accesskey_marker) == 1
43 if string == u"":
44 return u"", u""
45 accesskey = u""
46 label = string
47 marker_pos = 0
48 while marker_pos >= 0:
49 marker_pos = string.find(accesskey_marker, marker_pos)
50 if marker_pos != -1:
51 marker_pos += 1
52 if marker_pos == len(string):
53 break
54 if accesskey_marker == '&' and XMLEntityPlaceable.regex.match(string[marker_pos-1:]):
55 continue
56 label = string[:marker_pos-1] + string[marker_pos:]
57 accesskey = string[marker_pos]
58 break
59 return label, accesskey
60
61
64 """Combine a label and and accesskey to form a label+accesskey string
65
66 We place an accesskey marker before the accesskey in the label and this creates a
67 string with the two combined e.g. "File" + "F" = "&File"
68
69 @type label: unicode
70 @param label: a label
71 @type accesskey: unicode char
72 @param accesskey: The accesskey
73 @rtype: unicode or None
74 @return: label+accesskey string or None if uncombineable
75 """
76 assert isinstance(label, unicode)
77 assert isinstance(accesskey, unicode)
78 if len(accesskey) == 0:
79 return None
80 searchpos = 0
81 accesskeypos = -1
82 in_entity = False
83 accesskeyaltcasepos = -1
84 while (accesskeypos < 0) and searchpos < len(label):
85 searchchar = label[searchpos]
86 if searchchar == '&':
87 in_entity = True
88 elif searchchar == ';':
89 in_entity = False
90 else:
91 if not in_entity:
92 if searchchar == accesskey.upper():
93
94 accesskeypos = searchpos
95 if searchchar == accesskey.lower():
96
97 if accesskeyaltcasepos == -1:
98
99 accesskeyaltcasepos = searchpos
100
101
102 searchpos += 1
103
104 if accesskeypos == -1:
105 accesskeypos = accesskeyaltcasepos
106
107 if accesskeypos >= 0:
108 string = label[:accesskeypos] + accesskey_marker + label[accesskeypos:]
109 string = string.encode("UTF-8", "replace")
110 return string
111 else:
112
113 return None
114