2 # -*- coding: ISO-8859-1 -*-
5 # Copyright (C) 2002-2004 Jörg Lehmann <joergl@users.sourceforge.net>
6 # Copyright (C) 2002-2004 André Wobst <wobsta@users.sourceforge.net>
8 # This file is part of PyX (http://pyx.sourceforge.net/).
10 # PyX is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 2 of the License, or
13 # (at your option) any later version.
15 # PyX is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
20 # You should have received a copy of the GNU General Public License
21 # along with PyX; if not, write to the Free Software
22 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 scale
= { 't':1, 'u':1, 'v':1, 'w':1, 'x':1 }
32 unit_pattern
= re
.compile(r
"""^\s*([+-]?\d*((\d\.?)|(\.?\d))\d*(E[+-]?\d+)?)
34 (\s+(([a-z][a-z]+)|[^t-x]))?\s*$""",
35 re
.IGNORECASE | re
.VERBOSE
)
46 def set(uscale
=None, vscale
=None, wscale
=None, xscale
=None, defaultunit
=None):
47 if uscale
is not None:
49 if vscale
is not None:
51 if wscale
is not None:
53 if xscale
is not None:
55 if defaultunit
is not None:
57 _default_unit
= defaultunit
60 def _convert_to(l
, dest_unit
="m"):
61 if type(l
) in (types
.IntType
, types
.LongType
, types
.FloatType
):
62 return l
*_m
[_default_unit
]*scale
['u']/_m
[dest_unit
]
63 elif not isinstance(l
, length
):
64 l
=length(l
) # convert to length instance if necessary
66 return ( l
.length
['t'] +
67 l
.length
['u']*scale
['u'] +
68 l
.length
['v']*scale
['v'] +
69 l
.length
['w']*scale
['w'] +
70 l
.length
['x']*scale
['x'] ) / _m
[dest_unit
]
73 return _convert_to(l
, "m")
76 return _convert_to(l
, "cm")
79 return _convert_to(l
, "mm")
82 return _convert_to(l
, "inch")
85 return _convert_to(l
, "pt")
87 ################################################################################
88 # class for generic length
89 ################################################################################
94 Lengths can either be a initialized with a number or a string:
96 - a length specified as a number corresponds to the default values of
97 unit_type and unit_name
98 - a string has to consist of a maximum of three parts:
99 -quantifier: integer/float value
100 -unit_type: "t", "u", "v", "w", or "x".
101 Optional, defaults to "u"
102 -unit_name: "m", "cm", "mm", "inch", "pt".
103 Optional, defaults to _default_unit
105 Internally all length are stored in units of m as a quadruple of the four
110 def __init__(self
, l
=1, default_type
="u", dunit
=None):
111 self
.length
= { 't': 0 , 'u': 0, 'v': 0, 'w': 0, 'x': 0 }
113 if isinstance(l
, length
):
114 self
.length
= l
.length
115 elif helper
.isnumber(l
):
116 self
.length
[default_type
] = l
*_m
[dunit
or _default_unit
]
117 elif helper
.isstring(l
):
118 unit_match
= re
.match(unit_pattern
, l
)
119 if unit_match
is None:
120 raise ValueError("expecting number or string of the form 'number [u|v|w|x] unit'")
122 self
.prefactor
= float(unit_match
.group(1))
123 self
.unit_type
= unit_match
.group(7) or default_type
124 self
.unit_name
= unit_match
.group(9) or dunit
or _default_unit
126 self
.length
[self
.unit_type
] = self
.prefactor
*_m
[self
.unit_name
]
128 raise ( NotImplementedError,
129 "cannot convert given argument to length type" )
131 def __cmp__(self
, other
):
132 return cmp(tom(self
), tom(other
))
134 def __mul__(self
, factor
):
135 newlength
= self
.__class
__()
136 for unit_type
in newlength
.length
.keys():
137 newlength
.length
[unit_type
] = self
.length
[unit_type
]*factor
142 def __div__(self
, factor
):
143 newlength
= self
.__class
__()
144 for unit_type
in newlength
.length
.keys():
145 newlength
.length
[unit_type
] = self
.length
[unit_type
]/factor
148 def __add__(self
, l
):
149 # convert to length if necessary
151 newlength
= self
.__class
__()
152 for unit_type
in newlength
.length
.keys():
153 newlength
.length
[unit_type
] = self
.length
[unit_type
] + ll
.length
[unit_type
]
158 def __sub__(self
, l
):
159 # convert to length if necessary
161 newlength
= self
.__class
__()
162 for unit_type
in newlength
.length
.keys():
163 newlength
.length
[unit_type
] = self
.length
[unit_type
] - ll
.length
[unit_type
]
166 def __rsub__(self
, l
):
167 # convert to length if necessary
169 newlength
= self
.__class
__()
170 for unit_type
in newlength
.length
.keys():
171 newlength
.length
[unit_type
] = ll
.length
[unit_type
] - self
.length
[unit_type
]
175 newlength
= self
.__class
__()
176 for unit_type
in newlength
.length
.keys():
177 newlength
.length
[unit_type
] = -self
.length
[unit_type
]
181 return "(%(t)f t + %(u)f u + %(v)f v + %(w)f w + %(x)f x) m" % self
.length
184 ################################################################################
185 # class for more specialized lengths
186 ################################################################################
188 # lengths with user units as default
191 def __init__(self
, l
=1, default_type
="u"):
192 length
.__init
__(self
, l
, default_type
=default_type
, dunit
="pt")
196 def __init__(self
, l
=1, default_type
="u"):
197 length
.__init
__(self
, l
, default_type
=default_type
, dunit
="m")
201 def __init__(self
, l
=1, default_type
="u"):
202 length
.__init
__(self
, l
, default_type
=default_type
, dunit
="mm")
206 def __init__(self
, l
=1, default_type
="u"):
207 length
.__init
__(self
, l
, default_type
=default_type
, dunit
="cm")
210 class u_inch(length
):
211 def __init__(self
, l
=1, default_type
="u"):
212 length
.__init
__(self
, l
, default_type
=default_type
, dunit
="inch")
214 # without further specification, length are user length. Hence we
215 # define the following aliases
226 def __init__(self
, l
=1):
227 length
.__init
__(self
, l
, default_type
="t", dunit
="pt")
231 def __init__(self
, l
=1):
232 length
.__init
__(self
, l
, default_type
="t", dunit
="m")
236 def __init__(self
, l
=1):
237 length
.__init
__(self
, l
, default_type
="t", dunit
="cm")
241 def __init__(self
, l
=1):
242 length
.__init
__(self
, l
, default_type
="t", dunit
="mm")
245 class t_inch(length
):
246 def __init__(self
, l
=1):
247 length
.__init
__(self
, l
, default_type
="t", dunit
="inch")
252 def __init__(self
, l
=1):
253 length
.__init
__(self
, l
, default_type
="v", dunit
="pt")
257 def __init__(self
, l
=1):
258 length
.__init
__(self
, l
, default_type
="v", dunit
="m")
262 def __init__(self
, l
=1):
263 length
.__init
__(self
, l
, default_type
="v", dunit
="cm")
267 def __init__(self
, l
=1):
268 length
.__init
__(self
, l
, default_type
="v", dunit
="mm")
271 class v_inch(length
):
272 def __init__(self
, l
=1):
273 length
.__init
__(self
, l
, default_type
="v", dunit
="inch")
278 def __init__(self
, l
=1):
279 length
.__init
__(self
, l
, default_type
="w", dunit
="pt")
283 def __init__(self
, l
=1):
284 length
.__init
__(self
, l
, default_type
="w", dunit
="m")
288 def __init__(self
, l
=1):
289 length
.__init
__(self
, l
, default_type
="w", dunit
="cm")
293 def __init__(self
, l
=1):
294 length
.__init
__(self
, l
, default_type
="w", dunit
="mm")
297 class w_inch(length
):
298 def __init__(self
, l
=1):
299 length
.__init
__(self
, l
, default_type
="w", dunit
="inch")
304 def __init__(self
, l
=1):
305 length
.__init
__(self
, l
, default_type
="x", dunit
="pt")
309 def __init__(self
, l
=1):
310 length
.__init
__(self
, l
, default_type
="x", dunit
="m")
314 def __init__(self
, l
=1):
315 length
.__init
__(self
, l
, default_type
="x", dunit
="cm")
319 def __init__(self
, l
=1):
320 length
.__init
__(self
, l
, default_type
="x", dunit
="mm")
323 class x_inch(length
):
324 def __init__(self
, l
=1):
325 length
.__init
__(self
, l
, default_type
="x", dunit
="inch")