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