1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright 2002-2008 Zuza Software Foundation
#
# This file is part of The Translate Toolkit.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with translate; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""functions used to manipulate access keys in strings"""
from translate.storage.placeables.general import XMLEntityPlaceable
DEFAULT_ACCESSKEY_MARKER = u"&"
def extract(string, accesskey_marker=DEFAULT_ACCESSKEY_MARKER):
"""Extract the label and accesskey from a label+accesskey string
The function will also try to ignore &entities; which would obviously not
contain accesskeys.
@type string: Unicode
@param string: A string that might contain a label with accesskey marker
@type accesskey_marker: Char
@param accesskey_marker: The character that is used to prefix an access key
"""
assert isinstance(string, unicode)
assert isinstance(accesskey_marker, unicode)
assert len(accesskey_marker) == 1
if string == u"":
return u"", u""
accesskey = u""
label = string
marker_pos = 0
while marker_pos >= 0:
marker_pos = string.find(accesskey_marker, marker_pos)
if marker_pos != -1:
marker_pos += 1
if accesskey_marker == '&' and XMLEntityPlaceable.regex.match(string[marker_pos-1:]):
continue
label = string[:marker_pos-1] + string[marker_pos:]
accesskey = string[marker_pos]
break
return label, accesskey
def combine(label, accesskey,
accesskey_marker=DEFAULT_ACCESSKEY_MARKER):
"""Combine a label and and accesskey to form a label+accesskey string
We place an accesskey marker before the accesskey in the label and this creates a
string with the two combined e.g. "File" + "F" = "&File"
@type label: unicode
@param label: a label
@type accesskey: unicode char
@param accesskey: The accesskey
@rtype: unicode or None
@return: label+accesskey string or None if uncombineable
"""
assert isinstance(label, unicode)
assert isinstance(accesskey, unicode)
if len(accesskey) == 0:
return None
searchpos = 0
accesskeypos = -1
in_entity = False
accesskeyaltcasepos = -1
while (accesskeypos < 0) and searchpos < len(label):
searchchar = label[searchpos]
if searchchar == '&':
in_entity = True
elif searchchar == ';':
in_entity = False
else:
if not in_entity:
if searchchar == accesskey.upper():
# always prefer uppercase
accesskeypos = searchpos
if searchchar == accesskey.lower():
# take lower case otherwise...
if accesskeyaltcasepos == -1:
# only want to remember first altcasepos
accesskeyaltcasepos = searchpos
# note: we keep on looping through in hope
# of exact match
searchpos += 1
# if we didn't find an exact case match, use an alternate one if available
if accesskeypos == -1:
accesskeypos = accesskeyaltcasepos
# now we want to handle whatever we found...
if accesskeypos >= 0:
string = label[:accesskeypos] + accesskey_marker + label[accesskeypos:]
string = string.encode("UTF-8", "replace")
return string
else:
# can't currently mix accesskey if it's not in label
return None
|