2 # -*- coding: ISO-8859-1 -*-
5 # Copyright (C) 2002, 2003 Jörg Lehmann <joergl@users.sourceforge.net>
6 # Copyright (C) 2002, 2003 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
30 scale
= { 't':1, 'u':1, 'v':1, 'w':1 }
34 unit_pattern
= re
.compile(r
"""^\s*([+-]?\d*((\d\.?)|(\.?\d))\d*(E[+-]?\d+)?)
36 (\s+(([a-z][a-z]+)|[^t-w]))?\s*$""",
37 re
.IGNORECASE | re
.VERBOSE
)
48 def set(uscale
=None, vscale
=None, wscale
=None, defaultunit
=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'] ) / _m
[dest_unit
]
72 return _convert_to(l
, "m")
75 return _convert_to(l
, "cm")
78 return _convert_to(l
, "mm")
81 return _convert_to(l
, "inch")
84 return _convert_to(l
, "pt")
86 ################################################################################
87 # class for generic length
88 ################################################################################
93 Lengths can either be a initialized with a number or a string:
95 - a length specified as a number corresponds to the default values of
96 unit_type and unit_name
97 - a string has to consist of a maximum of three parts:
98 -quantifier: integer/float value
99 -unit_type: "t", "u", "v", or "w".
100 Optional, defaults to "u"
101 -unit_name: "m", "cm", "mm", "inch", "pt".
102 Optional, defaults to _default_unit
104 Internally all length are stored in units of m as a quadruple of the four
109 def __init__(self
, l
=1, default_type
="u", dunit
=None):
110 self
.length
= { 't': 0 , 'u': 0, 'v': 0, 'v':0, 'w':0 }
112 if isinstance(l
, length
):
113 self
.length
= l
.length
114 elif helper
.isstring(l
):
115 unit_match
= re
.match(unit_pattern
, l
)
116 if unit_match
is None:
117 raise ValueError("expecting number or string of the form 'number [u|v|w] unit'")
119 self
.prefactor
= float(unit_match
.group(1))
120 self
.unit_type
= unit_match
.group(7) or default_type
121 self
.unit_name
= unit_match
.group(9) or dunit
or _default_unit
123 self
.length
[self
.unit_type
] = self
.prefactor
*_m
[self
.unit_name
]
124 elif helper
.isnumber(l
):
125 self
.length
[default_type
] = l
*_m
[dunit
or _default_unit
]
127 raise ( NotImplementedError,
128 "cannot convert given argument to length type" )
130 def __mul__(self
, factor
):
131 newlength
= self
.__class
__()
132 for unit_type
in newlength
.length
.keys():
133 newlength
.length
[unit_type
] = self
.length
[unit_type
]*factor
138 def __div__(self
, factor
):
139 newlength
= self
.__class
__()
140 for unit_type
in newlength
.length
.keys():
141 newlength
.length
[unit_type
] = self
.length
[unit_type
]/factor
144 def __add__(self
, l
):
145 # convert to length if necessary
147 newlength
= self
.__class
__()
148 for unit_type
in newlength
.length
.keys():
149 newlength
.length
[unit_type
] = self
.length
[unit_type
] + ll
.length
[unit_type
]
154 def __sub__(self
, l
):
155 # convert to length if necessary
157 newlength
= self
.__class
__()
158 for unit_type
in newlength
.length
.keys():
159 newlength
.length
[unit_type
] = self
.length
[unit_type
] - ll
.length
[unit_type
]
162 def __rsub__(self
, l
):
163 # convert to length if necessary
165 newlength
= self
.__class
__()
166 for unit_type
in newlength
.length
.keys():
167 newlength
.length
[unit_type
] = ll
.length
[unit_type
] - self
.length
[unit_type
]
171 newlength
= self
.__class
__()
172 for unit_type
in newlength
.length
.keys():
173 newlength
.length
[unit_type
] = -self
.length
[unit_type
]
177 return "(%(t)f t + %(u)f u + %(v)f v + %(w)f w) m" % self
.length
180 ################################################################################
181 # class for more specialized lengths
182 ################################################################################
184 # lengths with user units as default
187 def __init__(self
, l
=1, default_type
="u"):
188 length
.__init
__(self
, l
, default_type
=default_type
, dunit
="pt")
192 def __init__(self
, l
=1, default_type
="u"):
193 length
.__init
__(self
, l
, default_type
=default_type
, dunit
="m")
197 def __init__(self
, l
=1, default_type
="u"):
198 length
.__init
__(self
, l
, default_type
=default_type
, dunit
="mm")
202 def __init__(self
, l
=1, default_type
="u"):
203 length
.__init
__(self
, l
, default_type
=default_type
, dunit
="cm")
206 class u_inch(length
):
207 def __init__(self
, l
=1, default_type
="u"):
208 length
.__init
__(self
, l
, default_type
=default_type
, dunit
="inch")
210 # without further specification, length are user length. Hence we
211 # define the following aliases
222 def __init__(self
, l
=1):
223 length
.__init
__(self
, l
, default_type
="t", dunit
="pt")
227 def __init__(self
, l
=1):
228 length
.__init
__(self
, l
, default_type
="t", dunit
="m")
232 def __init__(self
, l
=1):
233 length
.__init
__(self
, l
, default_type
="t", dunit
="cm")
237 def __init__(self
, l
=1):
238 length
.__init
__(self
, l
, default_type
="t", dunit
="mm")
241 class t_inch(length
):
242 def __init__(self
, l
=1):
243 length
.__init
__(self
, l
, default_type
="t", dunit
="inch")
248 def __init__(self
, l
=1):
249 length
.__init
__(self
, l
, default_type
="v", dunit
="pt")
253 def __init__(self
, l
=1):
254 length
.__init
__(self
, l
, default_type
="v", dunit
="m")
258 def __init__(self
, l
=1):
259 length
.__init
__(self
, l
, default_type
="v", dunit
="cm")
263 def __init__(self
, l
=1):
264 length
.__init
__(self
, l
, default_type
="v", dunit
="mm")
267 class v_inch(length
):
268 def __init__(self
, l
=1):
269 length
.__init
__(self
, l
, default_type
="v", dunit
="inch")
274 def __init__(self
, l
=1):
275 length
.__init
__(self
, l
, default_type
="w", dunit
="pt")
279 def __init__(self
, l
=1):
280 length
.__init
__(self
, l
, default_type
="w", dunit
="m")
284 def __init__(self
, l
=1):
285 length
.__init
__(self
, l
, default_type
="w", dunit
="cm")
289 def __init__(self
, l
=1):
290 length
.__init
__(self
, l
, default_type
="w", dunit
="mm")
293 class w_inch(length
):
294 def __init__(self
, l
=1):
295 length
.__init
__(self
, l
, default_type
="w", dunit
="inch")