1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """classes that hold units of .properties files (propunit) or entire files
23 (propfile) these files are used in translating Mozilla and other software
24
25 @note: The following {.properties file
26 description<http://java.sun.com/j2se/1.4.2/docs/api/java/util/Properties.html#load(java.io.Reader)>}
27 and {example <http://www.exampledepot.com/egs/java.util/Props.html>} give some
28 good references to the .properties specification. A simple summary of what is
29 permissible follows.
30
31 # a comment
32 ! a comment
33
34 a = a string
35 b = a string with escape sequences \t \n \r \\ \" \' \ (space) \u0123
36 c = a string with a continuation line \
37 continuation line
38 d.e.f = another string
39
40 """
41
42 from translate.storage import base
43 from translate.misc import quote
44 import re
45
46
47
48
49 eol = "\n"
50
52 """an element of a properties file i.e. a name and value, and any comments
53 associated"""
61
65
75
76 source = property(getsource, setsource)
77
79 """Note: this also sets the .source attribute!"""
80
81 self.source = target
82
85 target = property(gettarget, settarget)
86
93
102
105
106 - def addnote(self, note, origin=None):
107 self.comments.append(note)
108
110 return '\n'.join(self.comments)
111
114
116 """returns whether this is a blank element, containing only comments..."""
117 return not (self.name or self.value)
118
120 """this class represents a .properties file, made up of propunits"""
121 UnitClass = propunit
123 """construct a propfile, optionally reading in from inputfile"""
124 super(propfile, self).__init__(unitclass = self.UnitClass)
125 self.filename = getattr(inputfile, 'name', '')
126 if inputfile is not None:
127 propsrc = inputfile.read()
128 inputfile.close()
129 self.parse(propsrc)
130
131 - def parse(self, propsrc):
132 """read the source of a properties file in and include them as units"""
133 newunit = propunit()
134 inmultilinevalue = False
135 for line in propsrc.split("\n"):
136
137 line = quote.rstripeol(line)
138 if inmultilinevalue:
139 newunit.value += line.lstrip()
140
141 inmultilinevalue = (newunit.value[-1:] == '\\')
142
143 if inmultilinevalue:
144
145 newunit.value = newunit.value[:-1]
146 if not inmultilinevalue:
147
148 self.addunit(newunit)
149 newunit = propunit()
150
151 elif line.strip()[:1] == '#':
152
153 line = quote.escapecontrols(line)
154 newunit.comments.append(line+"\n")
155 elif not line.strip():
156
157 if str(newunit).strip():
158 self.addunit(newunit)
159 newunit = propunit()
160 else:
161 equalspos = line.find('=')
162
163 if equalspos == -1:
164 continue
165
166 else:
167 newunit.name = line[:equalspos].strip()
168 newunit.value = line[equalspos+1:].lstrip()
169
170 if newunit.value[-1:] == '\\':
171 inmultilinevalue = True
172 newunit.value = newunit.value[:-1]
173 else:
174 self.addunit(newunit)
175 newunit = propunit()
176
177 if inmultilinevalue or len(newunit.comments) > 0:
178 self.addunit(newunit)
179
181 """convert the units back to lines"""
182 lines = []
183 for unit in self.units:
184 lines.append(str(unit))
185 return "".join(lines)
186
187 if __name__ == '__main__':
188 import sys
189 pf = propfile(sys.stdin)
190 sys.stdout.write(str(pf))
191