1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """Grep XLIFF, Gettext PO and TMX localization files
23
24 Matches are output to snippet files of the same type which can then be reviewed
25 and later merged using pomerge
26
27 See: http://translate.sourceforge.net/wiki/toolkit/pogrep for examples and
28 usage instructions
29 """
30
31 from translate.storage import factory
32 from translate.misc import optrecurse
33 from translate.misc.multistring import multistring
34 from translate.lang import data
35 import re
36 import locale
37
39 - def __init__(self, searchstring, searchparts, ignorecase=False, useregexp=False, invertmatch=False, accelchar=None, encoding='utf-8', includeheader=False):
40 """builds a checkfilter using the given checker"""
41 if isinstance(searchstring, unicode):
42 self.searchstring = searchstring
43 else:
44 self.searchstring = searchstring.decode(encoding)
45 self.searchstring = data.normalize(self.searchstring)
46 if searchparts:
47
48
49 self.search_source = ('source' in searchparts) or ('msgid' in searchparts)
50 self.search_target = ('target' in searchparts) or ('msgstr' in searchparts)
51 self.search_notes = ('notes' in searchparts) or ('comment' in searchparts)
52 self.search_locations = 'locations' in searchparts
53 else:
54 self.search_source = True
55 self.search_target = True
56 self.search_notes = False
57 self.search_locations = False
58 self.ignorecase = ignorecase
59 if self.ignorecase:
60 self.searchstring = self.searchstring.lower()
61 self.useregexp = useregexp
62 if self.useregexp:
63 self.searchpattern = re.compile(self.searchstring)
64 self.invertmatch = invertmatch
65 self.accelchar = accelchar
66 self.includeheader = includeheader
67
69 teststr = data.normalize(teststr)
70 if self.ignorecase:
71 teststr = teststr.lower()
72 if self.accelchar:
73 teststr = re.sub(self.accelchar + self.accelchar, "#", teststr)
74 teststr = re.sub(self.accelchar, "", teststr)
75 if self.useregexp:
76 found = self.searchpattern.search(teststr)
77 else:
78 found = teststr.find(self.searchstring) != -1
79 if self.invertmatch:
80 found = not found
81 return found
82
84 """runs filters on an element"""
85 if unit.isheader(): return []
86
87 if self.search_source:
88 if isinstance(unit.source, multistring):
89 strings = unit.source.strings
90 else:
91 strings = [unit.source]
92 for string in strings:
93 if self.matches(string):
94 return True
95
96 if self.search_target:
97 if isinstance(unit.target, multistring):
98 strings = unit.target.strings
99 else:
100 strings = [unit.target]
101 for string in strings:
102 if self.matches(string):
103 return True
104
105 if self.search_notes:
106 return self.matches(unit.getnotes())
107 if self.search_locations:
108 return self.matches(u" ".join(unit.getlocations()))
109 return False
110
125
127 """a specialized Option Parser for the grep tool..."""
129 """parses the command line options, handling implicit input/output args"""
130 (options, args) = optrecurse.optparse.OptionParser.parse_args(self, args, values)
131
132 if args:
133 options.searchstring = args[0]
134 args = args[1:]
135 else:
136 self.error("At least one argument must be given for the search string")
137 if args and not options.input:
138 if not options.output:
139 options.input = args[:-1]
140 args = args[-1:]
141 else:
142 options.input = args
143 args = []
144 if args and not options.output:
145 options.output = args[-1]
146 args = args[:-1]
147 if args:
148 self.error("You have used an invalid combination of --input, --output and freestanding args")
149 if isinstance(options.input, list) and len(options.input) == 1:
150 options.input = options.input[0]
151 return (options, args)
152
154 """sets the usage string - if usage not given, uses getusagestring for each option"""
155 if usage is None:
156 self.usage = "%prog searchstring " + " ".join([self.getusagestring(option) for option in self.option_list])
157 else:
158 super(GrepOptionParser, self).set_usage(usage)
159
168
169 -def rungrep(inputfile, outputfile, templatefile, checkfilter):
170 """reads in inputfile, filters using checkfilter, writes to outputfile"""
171 fromfile = factory.getobject(inputfile)
172 tofile = checkfilter.filterfile(fromfile)
173 if tofile.isempty():
174 return False
175 outputfile.write(str(tofile))
176 return True
177
179 formats = {"po":("po", rungrep), "pot":("pot", rungrep),
180 "xliff":("xliff", rungrep), "xlf":("xlf", rungrep), "xlff":("xlff", rungrep),
181 "tmx":("tmx", rungrep),
182 None:("po", rungrep)}
183 parser = GrepOptionParser(formats)
184 parser.add_option("", "--search", dest="searchparts",
185 action="append", type="choice", choices=["source", "target", "notes", "locations", "msgid", "msgstr", "comment" ],
186 metavar="SEARCHPARTS", help="searches the given parts (source, target, notes and locations)")
187 parser.add_option("-I", "--ignore-case", dest="ignorecase",
188 action="store_true", default=False, help="ignore case distinctions")
189 parser.add_option("-e", "--regexp", dest="useregexp",
190 action="store_true", default=False, help="use regular expression matching")
191 parser.add_option("-v", "--invert-match", dest="invertmatch",
192 action="store_true", default=False, help="select non-matching lines")
193 parser.add_option("", "--accelerator", dest="accelchar",
194 action="store", type="choice", choices=["&", "_", "~"],
195 metavar="ACCELERATOR", help="ignores the given accelerator when matching")
196 parser.add_option("", "--header", dest="includeheader",
197 action="store_true", default=False,
198 help="include a PO header in the output")
199 parser.set_usage()
200 parser.passthrough.append('checkfilter')
201 parser.description = __doc__
202 return parser
203
205 parser = cmdlineparser()
206 parser.run()
207
208 if __name__ == '__main__':
209 main()
210