Package PyFoam :: Package ThirdParty :: Package Gnuplot :: Module termdefs
[hide private]
[frames] | no frames]

Source Code for Module PyFoam.ThirdParty.Gnuplot.termdefs

  1  # $Id: termdefs.py 302 2008-01-14 22:15:19Z bmcage $ 
  2   
  3  # Copyright (C) 2001-2003 Michael Haggerty <mhagger@alum.mit.edu> 
  4  # 
  5  # This file is licensed under the GNU Lesser General Public License 
  6  # (LGPL).  See LICENSE.txt for details. 
  7   
  8  """Terminal definition file. 
  9   
 10  This module describes the options available to gnuplot's various 
 11  terminals.  For the moment, it only supports a few terminals, but the 
 12  infrastructure is here to add others as they are needed. 
 13   
 14  Part of the trick is that the 'set terminal' command takes myriad 
 15  suboptions with various argument types, and order is sometimes 
 16  significant.  The other part of the trick is that there are over 50 
 17  terminal types, and each terminal has its own set of options. 
 18   
 19  The strategy here is to define a general mechanism for turning Python 
 20  keyword parameters into fragments of gnuplot command strings.  There 
 21  are a number of classes derived from Arg that do this.  Some take 
 22  string args, some boolean, etc.  Then the list of options that each 
 23  terminal accepts is stored in the terminal_opts dictionary. 
 24  Gnuplot.hardcopy(), in turn, uses this dictionary to interpret its 
 25  keyword arguments and build the 'set terminal' command. 
 26   
 27  """ 
 28   
 29   
 30  import types 
 31   
 32  import gp, Errors 
 33   
 34   
35 -class Arg:
36 """Process terminal subargs and return a command fragment. 37 38 Pull one or more arguments from keyw and output a list of strings 39 that will be appended to the 'set terminal' (separated by spaces). 40 Delete any used args from keyw. If no relevant options are found, 41 return None. 42 43 This is a base class for the actual argument-processing classes. 44 Derived classes must define a __call__(self, keyw) method 45 returning a list of strings or None. 46 47 """ 48 49 pass
50 51
52 -class ArgOneParam(Arg):
53 """Arg abstract base class specialized for exactly one parameter. 54 55 Members: 56 57 'argname' -- The name of the keyword argument used to pass 58 this argument to Python. 59 60 'default' -- The default value of the argument, used if no 61 keyword parameter is found. If this is None, then no 62 default is assumed. 63 64 """ 65
66 - def __init__(self, argname, default):
67 self.argname = argname 68 self.default = default
69
70 - def get_option(self, keyw):
71 """Get the keyword argument corresponding to this Arg. 72 73 Look in keyw for the keyword argument needed by this Arg. If 74 it is found, delete it from keyw and return it. If it is not 75 found, return self.default. 76 77 """ 78 79 try: 80 k = keyw[self.argname] 81 except KeyError: 82 return self.default 83 else: 84 del keyw[self.argname] 85 return k
86 87
88 -class KeywordArg(ArgOneParam):
89 """Represent an argument that must be passed as a keyword to gnuplot. 90 91 Some gnuplot options take the form of single unquoted keywords 92 (possibly preceded by a fixed keyword). We allow those to be 93 passed as strings 'option="keyword"'. Check that the option 94 supplied is in the list of allowed options. 95 96 Members: 97 98 'fixedword' -- the fixed keyword that must precede the 99 variable keyword in the gnuplot command, or None if none 100 is required. 101 102 'options' -- a list of strings containing the legal 103 alternatives for this argument. 104 105 """ 106
107 - def __init__(self, argname, options, fixedword=None, default=None):
108 ArgOneParam.__init__(self, argname, default) 109 self.fixedword = fixedword 110 self.options = options
111
112 - def __call__(self, keyw):
113 k = self.get_option(keyw) 114 115 if k is None: 116 return None 117 elif k in self.options: 118 if self.fixedword is None: 119 return [k] 120 else: 121 return [self.fixedword, k] 122 else: 123 raise Errors.OptionError( 124 'Illegal option %s="%s"' % (self.argname, k,))
125 126
127 -class StringArg(ArgOneParam):
128 """An option taking a quoted string argument.""" 129
130 - def __init__(self, argname, fixedword=None, default=None):
131 ArgOneParam.__init__(self, argname, default) 132 self.fixedword = fixedword
133
134 - def __call__(self, keyw):
135 k = self.get_option(keyw) 136 137 if k is None: 138 return None 139 elif type(k) is not types.StringType: 140 raise Errors.OptionError( 141 'Option %s must be a string' % (self.argname,)) 142 else: 143 retval = [] 144 if self.fixedword is not None: 145 retval.append(self.fixedword) 146 retval.append('"%s"' % k) 147 return retval
148 149
150 -class BareStringArg(ArgOneParam):
151 """An arbitrary argument output without quotes. 152 153 The argument can be a string or anything with a str() 154 representation, or a tuple of such things. Thus this can be used 155 for strings (which will be output without quotation marks), 156 integers, floating point arguments, or multiple arguments of the 157 above types (which will be output separated by spaces). No 158 checking is done that the argument is sensible. 159 160 """ 161
162 - def __init__(self, argname, fixedword=None, default=None):
163 ArgOneParam.__init__(self, argname, default) 164 self.fixedword = fixedword
165
166 - def __call__(self, keyw):
167 k = self.get_option(keyw) 168 169 if k is None: 170 return None 171 else: 172 retval = [] 173 if self.fixedword is not None: 174 retval.append(self.fixedword) 175 if type(k) in (types.TupleType, types.ListType): 176 for i in k: 177 retval.append(str(i)) 178 else: 179 retval.append(str(k)) 180 return retval
181 182
183 -class BooleanArg(ArgOneParam):
184 """An argument that takes a true/false value. 185 186 The argument should be 0 or 1. The option is output to gnuplot as 187 'trueval' if the argument is true or 'falseval' if the argument is 188 false. Either one can be 'None', in which case nothing is output. 189 'default' should also be 0 or 1. 190 191 """ 192
193 - def __init__(self, argname, trueval, falseval, 194 fixedword=None, default=None):
195 ArgOneParam.__init__(self, argname, default) 196 self.trueval = trueval 197 self.falseval = falseval 198 self.fixedword = fixedword
199
200 - def __call__(self, keyw):
201 k = self.get_option(keyw) 202 if k is None: 203 return None 204 else: 205 retval = [] 206 if self.fixedword is not None: 207 retval.append(self.fixedword) 208 if k: 209 val = self.trueval 210 else: 211 val = self.falseval 212 if val is not None: 213 retval.append(val) 214 return retval
215 216
217 -class MutuallyExclusiveArgs(Arg):
218 """A group of args, of which either zero or one may be set, but not more. 219 220 Members: 221 222 subargs -- a list [('argname', arg), ...] of Arg instances. 223 'argname' is used to identify the corresponding arg in 224 error messages. (The name of the corresponding keyword 225 args is determined internally by each arg.) 226 227 """ 228
229 - def __init__(self, *subargs):
230 self.subargs = list(subargs)
231
232 - def __call__(self, keyw):
233 foundargname = None 234 retval = None 235 for (argname, arg,) in self.subargs: 236 cmd = arg(keyw) 237 if cmd is not None: 238 if foundargname is not None: 239 raise Errors.OptionError( 240 'Arguments %s and %s cannot both be specified' 241 % (foundargname, argname,) 242 ) 243 else: 244 foundargname = argname 245 retval = cmd 246 return retval # might be None
247 248
249 -class KeywordOrBooleanArg(Arg):
250 """Allow a keyword arg to be specified either as a keyword or a boolean. 251 252 This arg type is the most flexible way to allow keyword parameters 253 to be specified. Say there is an option like 'fontsize' that can 254 take the values 'small' or 'large'. This could be represented as 255 256 'KeywordOrBooleanArg(options=["small", "large"], argname="fontsize")' 257 258 In that case, the fontsize could be specified in any of the 259 following ways: 260 261 'g.hardcopy(..., fontsize="small", ...)' 262 'g.hardcopy(..., fontsize="large", ...)' 263 'g.hardcopy(..., small=1, ...)' 264 'g.hardcopy(..., large=1, ...)' 265 266 If 'argname' is set to be 'None', then the first two possibilities 267 are omitted. 268 269 In the special case that there are exactly two alternatives, one 270 can also use: 271 272 'g.hardcopy(..., small=0, ...) # implies fontsize="large"' 273 'g.hardcopy(..., large=0, ...) # implies fontsize="small"' 274 275 Obviously care must be taken to ensure that none of the implied 276 keyword parameter names conflict with one another or with any of 277 the other Args allowed by a function. 278 279 Members: 280 281 'options' -- a list of strings representing allowed keyword 282 values. These options can be used as boolean values in 283 the style 'option=1'. 284 285 'argname' -- the name of the argname for the 'arg=value' style 286 of setting the argument. If 'None', then this style is 287 not allowed. 288 289 'fixedword' -- a fixed keyword that must precede the option, 290 or 'None'. 291 292 'default' -- the default option to set if nothing is set 293 explicitly, or None to leave nothing set in that case. 294 295 """ 296
297 - def __init__(self, options, argname=None, fixedword=None, default=None):
298 self.options = options 299 self.argname = argname 300 self.fixedword = fixedword 301 self.default = default 302 assert self.default is None or self.default in self.options, \ 303 'default must be a valid option'
304
305 - def __call__(self, keyw):
306 if self.argname is not None and self.argname in keyw: 307 k = keyw[self.argname] 308 del keyw[self.argname] 309 if k is None: 310 pass 311 elif k in self.options: 312 # Make sure it isn't contradicted by the corresponding boolean: 313 if k in keyw and not keyw[k]: 314 raise Errors.OptionError( 315 'Arguments %s and %s are contradictory' 316 % (self.argname, k,) 317 ) 318 else: 319 # Store the option into the boolean to be processed below: 320 keyw[k] = 1 321 else: 322 raise Errors.OptionError( 323 'Illegal option %s=%s' % (self.argname, k,)) 324 325 # Now scan the booleans and make sure that at most one is set: 326 option = None 327 for i in range(len(self.options)): 328 k = self.options[i] 329 if k in keyw: 330 newval = keyw[k] 331 del keyw[k] 332 if newval: 333 if option is not None: 334 raise Errors.OptionError( 335 'Arguments %s and %s cannot both be specified' 336 % (option, k,) 337 ) 338 else: 339 option = k 340 else: 341 # newval was false. This is only legal if this 342 # option only has two possible values: 343 if len(self.options) == 2: 344 option = self.options[1 - i] 345 else: 346 pass 347 348 if option is None: 349 if self.default is None: 350 return None 351 else: 352 option = self.default 353 retval = [] 354 if self.fixedword is not None: 355 retval.append(self.fixedword) 356 retval.append(option) 357 return retval
358 359 360 # Now we define the allowed options for a few terminal types. This 361 # table is used by Gnuplot.hardcopy() to construct the necessary 'set 362 # terminal' command. 363 364 terminal_opts = {} 365 366 terminal_opts['postscript'] = [ 367 KeywordOrBooleanArg( 368 options=['landscape', 'portrait', 'eps', 'default'], 369 argname='mode', 370 ), 371 KeywordOrBooleanArg( 372 options=['enhanced', 'noenhanced'], 373 # This default should probably be computed from the *current* 374 # value of GnuplotOpts, not at import time. ### 375 default=(gp.GnuplotOpts.prefer_enhanced_postscript 376 and 'enhanced' 377 or 'noenhanced'), 378 ), 379 KeywordOrBooleanArg(options=['color', 'monochrome']), 380 KeywordOrBooleanArg(options=['solid', 'dashed']), 381 KeywordOrBooleanArg( 382 options=['defaultplex', 'simplex', 'duplex'], 383 argname='duplexing', 384 ), 385 StringArg(argname='fontname'), 386 BareStringArg(argname='fontsize'), 387 ] 388 389 terminal_opts['pdf'] = [ 390 KeywordOrBooleanArg( 391 options=['landscape', 'portrait', 'eps', 'default'], 392 argname='mode', 393 ), 394 KeywordOrBooleanArg(options=['color', 'monochrome']), 395 KeywordOrBooleanArg(options=['solid', 'dashed']), 396 KeywordOrBooleanArg( 397 options=['defaultplex', 'simplex', 'duplex'], 398 argname='duplexing', 399 ), 400 StringArg(argname='fontname'), 401 BareStringArg(argname='fontsize'), 402 ] 403 404 terminal_opts['png'] = [ 405 KeywordOrBooleanArg( 406 options=['small', 'medium', 'large'], 407 argname='fontsize', 408 ), 409 KeywordOrBooleanArg(options=['monochrome', 'gray', 'color']), 410 ] 411 412 terminal_opts['fig'] = [ 413 KeywordOrBooleanArg(options=['monochrome', 'color']), 414 KeywordOrBooleanArg(options=['small', 'big']), 415 BareStringArg(argname='pointsmax', fixedword='pointsmax'), 416 KeywordOrBooleanArg(options=['landscape', 'portrait']), 417 KeywordOrBooleanArg(options=['metric', 'inches']), 418 BareStringArg(argname='fontsize'), 419 BareStringArg(argname='size'), # needs a tuple of two doubles 420 BareStringArg(argname='thickness'), 421 BareStringArg(argname='depth'), 422 ] 423 424 terminal_opts['cgm'] = [ 425 KeywordOrBooleanArg( 426 options=['landscape', 'portrait', 'default'], 427 argname='mode', 428 ), 429 KeywordOrBooleanArg(options=['color', 'monochrome']), 430 KeywordOrBooleanArg(options=['rotate', 'norotate']), 431 BareStringArg(argname='width', fixedword='width'), 432 BareStringArg(argname='linewidth', fixedword='linewidth'), 433 StringArg(argname='font'), 434 BareStringArg(argname='fontsize'), 435 ] 436 437 terminal_opts['pict'] = [ 438 KeywordOrBooleanArg( 439 options=['landscape', 'portrait', 'default'], 440 argname='mode', 441 ), 442 KeywordOrBooleanArg(options=['color', 'monochrome']), 443 KeywordOrBooleanArg(options=['dashes', 'nodashes']), 444 445 # default font, which must be a valid pict font: 446 StringArg(argname='fontname'), 447 448 # default font size, in points: 449 BareStringArg(argname='fontsize'), 450 451 # width of plot in pixels: 452 BareStringArg(argname='width'), 453 454 # height of plot in pixels: 455 BareStringArg(argname='height'), 456 457 ] 458 459 terminal_opts['mp'] = [ 460 KeywordOrBooleanArg(options=['color', 'colour', 'monochrome']), 461 KeywordOrBooleanArg(options=['solid', 'dashed']), 462 KeywordOrBooleanArg(options=['notex', 'tex', 'latex']), 463 BareStringArg(argname='magnification'), 464 KeywordOrBooleanArg(options=['psnfss', 'psnfss-version7', 'nopsnfss']), 465 BareStringArg(argname='prologues'), 466 KeywordOrBooleanArg(options=['a4paper']), 467 KeywordOrBooleanArg(options=['amstex']), 468 StringArg(argname='fontname'), 469 BareStringArg(argname='fontsize'), 470 ] 471 472 terminal_opts['svg'] = [ 473 BareStringArg(argname='size', fixedword='size'), # tuple of two doubles 474 KeywordOrBooleanArg(options=['fixed', 'dynamic']), 475 StringArg(argname='fname', fixedword='fname'), 476 BareStringArg(argname='fsize', fixedword='fsize'), 477 KeywordOrBooleanArg(options=['enhanced', 'noenhanced']), 478 StringArg(argname='fontfile', fixedword='fontfile'), 479 ] 480