/usr/share/pyshared/translate/convert/accesskey.py is in translate-toolkit 1.10.0-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | # -*- coding: utf-8 -*-
#
# Copyright 2002-2009,2011 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 this program; if not, see <http://www.gnu.org/licenses/>.
"""functions used to manipulate access keys in strings"""
from translate.storage.placeables.general import XMLEntityPlaceable
DEFAULT_ACCESSKEY_MARKER = u"&"
class UnitMixer(object):
"""Helper to mix separately defined labels and accesskeys into one unit."""
def __init__(self, labelsuffixes, accesskeysuffixes):
self.labelsuffixes = labelsuffixes
self.accesskeysuffixes = accesskeysuffixes
def match_entities(self, index):
"""Populates mixedentities from the index."""
#: Entities which have a .label/.title and .accesskey combined
mixedentities = {}
for entity in index:
for labelsuffix in self.labelsuffixes:
if entity.endswith(labelsuffix):
entitybase = entity[:entity.rfind(labelsuffix)]
# see if there is a matching accesskey in this line,
# making this a mixed entity
for akeytype in self.accesskeysuffixes:
if (entitybase + akeytype) in index:
# add both versions to the list of mixed entities
mixedentities[entity] = {}
mixedentities[entitybase+akeytype] = {}
# check if this could be a mixed entity (labelsuffix and
# ".accesskey")
return mixedentities
def mix_units(self, label_unit, accesskey_unit, target_unit):
"""Mix the given units into the given target_unit if possible.
Might return None if no match is possible.
"""
target_unit.addlocations(label_unit.getlocations())
target_unit.addlocations(accesskey_unit.getlocations())
target_unit.msgidcomment = target_unit._extract_msgidcomments() + \
label_unit._extract_msgidcomments()
target_unit.msgidcomment = target_unit._extract_msgidcomments() + \
accesskey_unit._extract_msgidcomments()
target_unit.addnote(label_unit.getnotes("developer"), "developer")
target_unit.addnote(accesskey_unit.getnotes("developer"), "developer")
target_unit.addnote(label_unit.getnotes("translator"), "translator")
target_unit.addnote(accesskey_unit.getnotes("translator"), "translator")
label = label_unit.source
accesskey = accesskey_unit.source
label = combine(label, accesskey)
if label is None:
return None
target_unit.source = label
target_unit.target = ""
return target_unit
def find_mixed_pair(self, mixedentities, store, unit):
entity = unit.getid()
if entity not in mixedentities:
return None, None
# depending on what we come across first, work out the label
# and the accesskey
labelentity, accesskeyentity = None, None
for labelsuffix in self.labelsuffixes:
if entity.endswith(labelsuffix):
entitybase = entity[:entity.rfind(labelsuffix)]
for akeytype in self.accesskeysuffixes:
if (entitybase + akeytype) in store.index:
labelentity = entity
accesskeyentity = labelentity[:labelentity.rfind(labelsuffix)] + akeytype
break
else:
for akeytype in self.accesskeysuffixes:
if entity.endswith(akeytype):
accesskeyentity = entity
for labelsuffix in self.labelsuffixes:
labelentity = accesskeyentity[:accesskeyentity.rfind(akeytype)] + labelsuffix
if labelentity in store.index:
break
else:
labelentity = None
accesskeyentity = None
return (labelentity, accesskeyentity)
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 marker_pos == len(string):
break
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
|