ctioga2 0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. data/COPYING +339 -0
  2. data/Changelog +6 -0
  3. data/bin/ctioga2 +26 -0
  4. data/lib/ctioga2/commands/arguments.rb +58 -0
  5. data/lib/ctioga2/commands/commands.rb +258 -0
  6. data/lib/ctioga2/commands/doc/doc.rb +118 -0
  7. data/lib/ctioga2/commands/doc/documentation-commands.rb +119 -0
  8. data/lib/ctioga2/commands/doc/help.rb +95 -0
  9. data/lib/ctioga2/commands/doc/html.rb +230 -0
  10. data/lib/ctioga2/commands/doc/introspection.rb +211 -0
  11. data/lib/ctioga2/commands/doc/man.rb +279 -0
  12. data/lib/ctioga2/commands/doc/markup.rb +359 -0
  13. data/lib/ctioga2/commands/general-commands.rb +119 -0
  14. data/lib/ctioga2/commands/general-types.rb +118 -0
  15. data/lib/ctioga2/commands/groups.rb +73 -0
  16. data/lib/ctioga2/commands/interpreter.rb +257 -0
  17. data/lib/ctioga2/commands/parsers/command-line.rb +187 -0
  18. data/lib/ctioga2/commands/parsers/file.rb +186 -0
  19. data/lib/ctioga2/commands/strings.rb +303 -0
  20. data/lib/ctioga2/commands/type.rb +100 -0
  21. data/lib/ctioga2/commands/variables.rb +101 -0
  22. data/lib/ctioga2/data/backends/backend.rb +260 -0
  23. data/lib/ctioga2/data/backends/backends.rb +39 -0
  24. data/lib/ctioga2/data/backends/backends/gnuplot.rb +140 -0
  25. data/lib/ctioga2/data/backends/backends/math.rb +121 -0
  26. data/lib/ctioga2/data/backends/backends/text.rb +335 -0
  27. data/lib/ctioga2/data/backends/description.rb +405 -0
  28. data/lib/ctioga2/data/backends/factory.rb +73 -0
  29. data/lib/ctioga2/data/backends/parameter.rb +109 -0
  30. data/lib/ctioga2/data/datacolumn.rb +245 -0
  31. data/lib/ctioga2/data/dataset.rb +233 -0
  32. data/lib/ctioga2/data/filters.rb +131 -0
  33. data/lib/ctioga2/data/merge.rb +43 -0
  34. data/lib/ctioga2/data/point.rb +72 -0
  35. data/lib/ctioga2/data/stack.rb +294 -0
  36. data/lib/ctioga2/graphics/coordinates.rb +73 -0
  37. data/lib/ctioga2/graphics/elements.rb +111 -0
  38. data/lib/ctioga2/graphics/elements/containers.rb +111 -0
  39. data/lib/ctioga2/graphics/elements/curve2d.rb +155 -0
  40. data/lib/ctioga2/graphics/elements/element.rb +90 -0
  41. data/lib/ctioga2/graphics/elements/primitive.rb +256 -0
  42. data/lib/ctioga2/graphics/elements/subplot.rb +140 -0
  43. data/lib/ctioga2/graphics/generator.rb +68 -0
  44. data/lib/ctioga2/graphics/legends.rb +108 -0
  45. data/lib/ctioga2/graphics/legends/area.rb +199 -0
  46. data/lib/ctioga2/graphics/legends/items.rb +183 -0
  47. data/lib/ctioga2/graphics/legends/provider.rb +58 -0
  48. data/lib/ctioga2/graphics/legends/storage.rb +65 -0
  49. data/lib/ctioga2/graphics/root.rb +209 -0
  50. data/lib/ctioga2/graphics/styles.rb +30 -0
  51. data/lib/ctioga2/graphics/styles/axes.rb +247 -0
  52. data/lib/ctioga2/graphics/styles/background.rb +122 -0
  53. data/lib/ctioga2/graphics/styles/base.rb +115 -0
  54. data/lib/ctioga2/graphics/styles/carrays.rb +53 -0
  55. data/lib/ctioga2/graphics/styles/curve.rb +101 -0
  56. data/lib/ctioga2/graphics/styles/drawable.rb +87 -0
  57. data/lib/ctioga2/graphics/styles/factory.rb +351 -0
  58. data/lib/ctioga2/graphics/styles/legend.rb +63 -0
  59. data/lib/ctioga2/graphics/styles/plot.rb +410 -0
  60. data/lib/ctioga2/graphics/styles/sets.rb +64 -0
  61. data/lib/ctioga2/graphics/styles/texts.rb +277 -0
  62. data/lib/ctioga2/graphics/subplot-commands.rb +141 -0
  63. data/lib/ctioga2/graphics/types.rb +188 -0
  64. data/lib/ctioga2/graphics/types/bijection.rb +79 -0
  65. data/lib/ctioga2/graphics/types/boundaries.rb +170 -0
  66. data/lib/ctioga2/graphics/types/boxes.rb +157 -0
  67. data/lib/ctioga2/graphics/types/dimensions.rb +157 -0
  68. data/lib/ctioga2/graphics/types/point.rb +247 -0
  69. data/lib/ctioga2/log.rb +97 -0
  70. data/lib/ctioga2/metabuilder/type.rb +316 -0
  71. data/lib/ctioga2/metabuilder/types.rb +39 -0
  72. data/lib/ctioga2/metabuilder/types/coordinates.rb +124 -0
  73. data/lib/ctioga2/metabuilder/types/dates.rb +43 -0
  74. data/lib/ctioga2/metabuilder/types/lists.rb +188 -0
  75. data/lib/ctioga2/metabuilder/types/numbers.rb +97 -0
  76. data/lib/ctioga2/metabuilder/types/strings.rb +93 -0
  77. data/lib/ctioga2/metabuilder/types/styles.rb +178 -0
  78. data/lib/ctioga2/plotmaker.rb +677 -0
  79. data/lib/ctioga2/postprocess.rb +115 -0
  80. data/lib/ctioga2/utils.rb +120 -0
  81. data/setup.rb +1586 -0
  82. metadata +144 -0
@@ -0,0 +1,677 @@
1
+ # plotmaker.rb: the main class for ctioga
2
+ # copyright (c) 2006, 2007, 2008, 2009 by Vincent Fourmond
3
+
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # (at your option) any later version.
8
+
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details (in the COPYING file).
13
+
14
+
15
+ # TODO, the main one:
16
+ #
17
+ # It currently is a pain to make complex plots with ctioga. A real
18
+ # pain. What could be done to improve the situation ?
19
+ #
20
+ # * hide the difference between edges and axes.
21
+ # * the layout mechanism is not comfortable enough to work with, especially
22
+ # with the need for relative positioning.
23
+ #
24
+ # Would it be possible to allow for the 'real size' to be determined
25
+ # *afterwards* ??? Difficult !
26
+
27
+ # TODO, an even bigger one:
28
+ # Switch to a real command-based plotting program:
29
+ # - any single operation that is realized by ctioga would be a command
30
+ # - every single of these commands would take a given (fixed) number of
31
+ # parameters (we should take care about boolean stuff)
32
+ # - every command would be of course reachable as command-line options
33
+ # but it could also be within files
34
+ # - in these files, provide an additional mechanism for quickly defining
35
+ # variables and do variable substitution.
36
+ # - one command (plus arguments) per line, with provisions for
37
+ # line-splitting
38
+ # - allow some kind of 'include' directives (that would also be used for
39
+ # cmdline inclusion of files)
40
+ # - command-line arguments and command files could intermix (that *would*
41
+ # be fun, since it would allow very little changes to a command-line
42
+ # to change significantly the look of a file...!)
43
+ # - LONG TERM: allow conditionals and variable
44
+ # definition/substitution on command-line ?
45
+ # - Use typed variables, converted into string when substitution occurs,
46
+ # but manipulable as *typed* before ?? proposed syntax:
47
+ # type: variable = contents ?
48
+ #
49
+ # Each command could take *typed* arguments. That would allow typed
50
+ # variables along with a string-to-type conversion ? (is that useful
51
+ # ?) NO. Commands take String. And that is fine...
52
+ #
53
+ # Provide *optional* hash-like arguments that probably could not be
54
+ # used in the command-line, but could be in the file.
55
+ #
56
+ # Provide self-documentation in each and every command
57
+ #
58
+ # Manipulations of a buffer stack - including mathematical
59
+ # expressions; provide commands to only *load* a file, but not
60
+ # necessarily draw it.
61
+ #
62
+ # Provide a way to 'save' a command-line into a command-file.
63
+ #
64
+ # Write as many test suites as possible ??
65
+ #
66
+ # Merge Metabuilder and Backends into the ctioga code base. There's
67
+ # no need for extra complexity.
68
+ #
69
+ # That requires a huge amount of work, but on the other hand, that
70
+ # would be much more satisfactory than the current mess.
71
+ #
72
+ # Commands would be part of "groups".
73
+ #
74
+ # Release a new version of ctioga before that.
75
+ #
76
+ # Don't rely on huge mess of things !
77
+
78
+ # IDEAS:
79
+ #
80
+ # * write a :point type that would parse figure/frame/page coordinates + maybe
81
+ # arbitrary additions ?
82
+ # * drop the layout system, but instead write a simple plotting system:
83
+ # - start the image as a figure
84
+ # - start a subplot in the full figure if nothing was specified before the
85
+ # first dataset
86
+ # - start subplots manually using --inset or things of this spirit
87
+ # - maybe, for the case when subplots were manually specified, resize
88
+ # the graph so it fits ? (difficult, especially if the positions/sizes
89
+ # are relative... but trivial if that isn't the case. Maybe provide
90
+ # a autoresize function for that ? Or do it automatically if all the
91
+ # toplevel (sub)plot positions are absolute ?)
92
+ #
93
+ # This scheme would allow for a relatively painless way to draw graphs...
94
+
95
+
96
+ # TODO: make --xrange automatically select the range for the --math
97
+ # backend unless another range was explicitly specified.
98
+
99
+ require 'ctioga2/utils'
100
+ require 'ctioga2/log'
101
+
102
+ require 'shellwords'
103
+
104
+ # Maybe, maybe, maybe... We need tioga ?
105
+ require 'Tioga/FigureMaker'
106
+
107
+
108
+ # Command interpreter
109
+ require 'ctioga2/commands/interpreter'
110
+ # Various global scope commands:
111
+ require 'ctioga2/commands/general-commands'
112
+ # Introspection...
113
+ require 'ctioga2/commands/doc/introspection'
114
+ require 'ctioga2/commands/doc/documentation-commands'
115
+
116
+
117
+ # Data handling
118
+ require 'ctioga2/data/dataset'
119
+ require 'ctioga2/data/stack'
120
+ require 'ctioga2/data/backends/factory'
121
+
122
+
123
+ # Graphics
124
+ require 'ctioga2/graphics/root'
125
+ require 'ctioga2/graphics/styles'
126
+ require 'ctioga2/graphics/generator'
127
+
128
+
129
+ # Miscellaneous
130
+ require 'ctioga2/postprocess'
131
+
132
+
133
+
134
+ # This module contains all the classes used by ctioga
135
+ module CTioga2
136
+
137
+ Version::register_svn_info('$Revision: 98 $', '$Date: 2009-06-27 21:43:31 +0200 (Sat, 27 Jun 2009) $')
138
+
139
+ # This class is the core of ctioga. It parses the command-line arguments,
140
+ # reads all necessary files and plots graphs. Most of its functionality
141
+ # is delegated into classes.
142
+ class PlotMaker
143
+
144
+ # Include logging facilities for ctioga2
145
+ include CTioga2::Log
146
+
147
+ # The Commands::Interpreter object which runs all the commands.
148
+ attr_accessor :interpreter
149
+
150
+ # The Data::DataStack object that manipulates Dataset objects
151
+ attr_accessor :data_stack
152
+
153
+ # The Graphics::RootObject in charge of holding all things that
154
+ # will eventually get drawn
155
+ attr_accessor :root_object
156
+
157
+ # A Graphics::CurveGenerator object in charge of producing
158
+ # suitable elements to be added to the Graphics::RootObject
159
+ attr_accessor :curve_generator
160
+
161
+ # Below are simple plot attributes. Maybe they should be in their
162
+ # own namespace.
163
+
164
+ # The name of the figure
165
+ attr_accessor :figure_name
166
+
167
+ # The output directory
168
+ attr_accessor :output_directory
169
+
170
+ # Additional preamble for LaTeX output
171
+ attr_accessor :latex_preamble
172
+
173
+ # What happens to generated PDF files (a PostProcess object)
174
+ attr_accessor :postprocess
175
+
176
+ # Whether or not to include the command-line used to produce the
177
+ # file in the target PDF file.
178
+ attr_accessor :mark
179
+
180
+ # Whether intermediate files are cleaned up automatically
181
+ # afterwards or not...
182
+ attr_accessor :cleanup
183
+
184
+
185
+ # The first instance of PlotMaker created
186
+ @@first_plotmaker_instance = nil
187
+
188
+ # Returns the first created instance of PlotMaker. This sounds
189
+ # less object-oriented, yes, but that can come in useful some
190
+ # times.
191
+ def self.plotmaker
192
+ return @@first_plotmaker_instance
193
+ end
194
+
195
+
196
+ # Setting up of the PlotMaker object
197
+ def initialize
198
+ CTioga2::Log::init_logger
199
+ @data_stack = Data::DataStack.new
200
+ @root_object = Graphics::RootObject.new
201
+ @interpreter = Commands::Interpreter.new(self)
202
+ @curve_generator = Graphics::CurveGenerator.new
203
+
204
+ # Figure name:
205
+ @figure_name = nil
206
+
207
+ # Original preamble
208
+ @latex_preamble = ""
209
+
210
+ @postprocess = PostProcess.new
211
+
212
+ # Make sure it is registered
213
+ @@first_plotmaker_instance ||= self
214
+
215
+ # We mark by default, as it comes dead useful.
216
+ @mark = true
217
+
218
+ # Remove intermediate files by default.
219
+ @cleanup = true
220
+ end
221
+
222
+ # ctioga's entry point.
223
+ def run(command_line)
224
+
225
+ # The main catch-all around the plot:
226
+ begin
227
+ @command_line = command_line.dup
228
+ if ENV.key? 'CTIOGA2_PRE'
229
+ command_line.unshift(*Shellwords.shellwords(ENV['CTIOGA2_PRE']))
230
+ end
231
+
232
+ if ENV.key? 'CTIOGA2_POST'
233
+ command_line.push(*Shellwords.shellwords(ENV['CTIOGA2_POST']))
234
+ end
235
+
236
+ @interpreter.run_command_line(command_line)
237
+
238
+ # Now, draw the main figure
239
+ file = draw_figure(@figure_name || "Plot", true)
240
+ rescue SystemExit => e
241
+ # We special-case the exit exception ;-)...
242
+ rescue Exception => e
243
+ debug format_exception(e)
244
+ fatal "#{e.message}"
245
+ end
246
+ end
247
+
248
+ # Flushes the current root object and starts a new one:
249
+ def reset_graphics
250
+ draw_figure(@figure_name || "Plot", true)
251
+
252
+ @root_object = Graphics::RootObject.new
253
+ @curve_generator = Graphics::CurveGenerator.new
254
+ end
255
+
256
+ # Returns a quoted version of the command line, that possibly
257
+ # could be used again to reproduce the same results.
258
+ def quoted_command_line
259
+ quoted_args = @command_line.collect do |s|
260
+ Utils::shell_quote_string(s)
261
+ end.join ' '
262
+
263
+ return "#{File.basename($0)} #{quoted_args}"
264
+ end
265
+
266
+ # Draws the figure currently accumulated in the #root_object.
267
+ # It returns the path of the PDF file produced.
268
+ #
269
+ # TODO:
270
+ # * cleanup or not ?
271
+ def draw_figure(figname = "Plot", last = false)
272
+ return if @root_object.empty?
273
+ info "Producing figure '#{figname}'"
274
+
275
+ t = create_figure_maker
276
+ # If figname is clearly a path, we split it into directory/name
277
+ # and set the output directory to directory.
278
+ if File::basename(figname) != figname
279
+ dir = File::dirname(figname)
280
+ # If path is relative and output_directory is specified, we make
281
+ # the path relative to output_dir
282
+ if @output_directory && dir =~ /^[^\/~]/
283
+ dir = File::join(@output_directory, dir)
284
+ end
285
+ t.save_dir = dir
286
+ figname = File::basename(figname)
287
+ elsif @output_directory
288
+ t.save_dir = @output_directory
289
+ end
290
+
291
+ t.def_figure(figname) do
292
+ @root_object.draw_root_object(t)
293
+ end
294
+ t.make_preview_pdf(t.figure_index(figname))
295
+
296
+ file = t.save_dir ? File::join(t.save_dir, figname + ".pdf") :
297
+ figname + ".pdf"
298
+
299
+ # Feed it
300
+ @postprocess.process_file(file, last)
301
+ return file
302
+ end
303
+
304
+ # Add *one* Data::Dataset object using the current style (that can
305
+ # be overridden by stuff given as options) to the #root_object.
306
+ #
307
+ # TODO: here, keep a state of the current styles:
308
+ # * which is the color/marker/filling and so on of the curve ?
309
+ # * are we drawing plain 2D curve, a histogram or something
310
+ # even more fancy ?
311
+ # * this should be a separated class.
312
+ #
313
+ # TODO: all curve objects should only take a Data::Dataset and a
314
+ # style as arguments to new.
315
+ def add_curve(dataset, options = {})
316
+ plot = @root_object.current_plot
317
+ curve = @curve_generator.
318
+ curve_from_dataset(plot, dataset, options)
319
+ plot.add_element(curve)
320
+ info "Adding curve '#{dataset.name}' to the current plot"
321
+ end
322
+
323
+ # Transforms a _dataset_spec_ into one or several Data::Dataset
324
+ # using the current backend (or any other that might be specified
325
+ # in the options), and add them as curves to the #root_object,
326
+ # using #add_curve
327
+ def add_curves(dataset_spec, options = {})
328
+ begin
329
+ sets = @data_stack.get_datasets(dataset_spec, options)
330
+ rescue Exception => exception
331
+ error "A problem occurred while processing dataset '#{dataset_spec}' using backend #{@data_stack.backend_factory.current.description.name}. Ignoring it."
332
+ debug format_exception(exception)
333
+ return
334
+ end
335
+ for set in sets
336
+ # We first trim elements from options that are not inside
337
+ # Graphics::Styles::CurveStyleFactory::PlotCommandOptions
338
+ options.delete_if { |k,v|
339
+ ! Graphics::Styles::
340
+ CurveStyleFactory::PlotCommandOptions.key?(k)
341
+ }
342
+ add_curve(set, options)
343
+ end
344
+ end
345
+
346
+ protected
347
+
348
+ # Creates a new FigureMaker object and returns it
349
+ def create_figure_maker
350
+ t = Tioga::FigureMaker.new
351
+ t.tex_preamble += @latex_preamble
352
+ t.autocleanup = @cleanup
353
+
354
+ # The title field of the information is the command-line if marking
355
+ # is on.
356
+ if @mark
357
+ title = "/Title (#{Utils::pdftex_quote_string(quoted_command_line)})\n"
358
+ else
359
+ title = ""
360
+ end
361
+
362
+ # We now use \pdfinfo to provide information about the version
363
+ # of ctioga2 used to produce the PDF, and the command-line if
364
+ # applicable.
365
+ t.tex_preamble +=
366
+ "\n\\pdfinfo {\n#{title}/Creator(#{Utils::pdftex_quote_string("ctioga2 #{Version::version}")})\n}\n"
367
+ return t
368
+ end
369
+
370
+
371
+ PlotGroup = CmdGroup.new('plots', "Plots","Plots", 0)
372
+
373
+ PlotOptions =
374
+ Graphics::Styles::CurveStyleFactory::PlotCommandOptions.dup
375
+
376
+
377
+ PlotOptions.merge!(Data::LoadDatasetOptions) do |key, oldval, newval|
378
+ raise "Duplicated option between PlotCommandOptions and LoadDatasetOptions"
379
+ end
380
+
381
+ PlotCommand =
382
+ Cmd.new("plot",nil,"--plot",
383
+ [ CmdArg.new('dataset') ],
384
+ PlotOptions ) do |plotmaker, set, options|
385
+ plotmaker.add_curves(set, options)
386
+ end
387
+
388
+ PlotCommand.describe("Plots the given datasets",
389
+ <<EOH, PlotGroup)
390
+ Use the current backend to load the given datasets onto the data stack
391
+ and plot them. It is a combination of the {command: load} and the
392
+ {command: plot-last} commands; you might want to see their
393
+ documentation.
394
+ EOH
395
+
396
+ PlotLastOptions =
397
+ Graphics::Styles::CurveStyleFactory::PlotCommandOptions.dup
398
+
399
+ PlotLastOptions['which'] = CmdArg.new('stored-dataset')
400
+
401
+ PlotLastCommand =
402
+ Cmd.new("plot-last",'-p',"--plot-last",
403
+ [], PlotLastOptions) do |plotmaker, options|
404
+ ds = plotmaker.data_stack.specified_dataset(options)
405
+ options.delete('which') # To avoid problems with extra options.
406
+ plotmaker.add_curve(ds, options)
407
+ end
408
+
409
+ PlotLastCommand.describe("Plots the last dataset pushed onto the stack",
410
+ <<EOH, PlotGroup)
411
+ Plots the last dataset pushed onto the data stack (or the one
412
+ specified with the 'which' option), with the current style. All
413
+ aspects of the curve style (colors, markers, line styles...) can be
414
+ overridden through the use of options.
415
+ EOH
416
+
417
+ LaTeXGroup = CmdGroup.new('latex', "LaTeX",<<EOD, 30)
418
+ Commands providing control over the LaTeX output (preamble,
419
+ packages...)
420
+ EOD
421
+
422
+ UsePackageCommand =
423
+ Cmd.new("use",nil,"--use",
424
+ [ CmdArg.new('text') ],
425
+ { 'arguments' => CmdArg.new('text')}
426
+ ) do |plotmaker, package, options|
427
+ if options['arguments']
428
+ plotmaker.latex_preamble <<
429
+ "\\usepackage[#{options['arguments']}]{#{package}}\n"
430
+ else
431
+ plotmaker.latex_preamble << "\\usepackage{#{package}}\n"
432
+ end
433
+ end
434
+
435
+ UsePackageCommand.describe('Includes a LaTeX package',
436
+ <<EOD, LaTeXGroup)
437
+ Adds a command to include the LaTeX package into the preamble. The
438
+ arguments, if given, are given within [square backets].
439
+ EOD
440
+
441
+ PreambleCommand =
442
+ Cmd.new("preamble",nil,"--preamble",
443
+ [ CmdArg.new('text') ]) do |plotmaker, txt|
444
+ plotmaker.latex_preamble << "#{txt}\n"
445
+ end
446
+
447
+ PreambleCommand.describe('Adds a string to the LaTeX preamble',
448
+ <<EOD, LaTeXGroup)
449
+ Adds the given string to the LaTeX preamble of the output.
450
+ EOD
451
+
452
+ Utf8Command =
453
+ Cmd.new("utf8",nil,"--utf8", []) do |plotmaker|
454
+ plotmaker.latex_preamble <<
455
+ "\\usepackage[utf8]{inputenc}\n\\usepackage[T1]{fontenc}"
456
+ end
457
+
458
+ Utf8Command.describe('Uses UTF-8 in strings',
459
+ <<EOD, LaTeXGroup)
460
+ Makes ctioga2 use UTF-8 for all text. It is exactly equivalent to
461
+ the command {command: preamble} with the argument:
462
+
463
+ @ \\usepackage[utf8]{inputenc}\\usepackage[T1]{fontenc}
464
+
465
+ EOD
466
+
467
+
468
+
469
+ OutputSetupGroup =
470
+ CmdGroup.new('output-setup',
471
+ "Output setup", <<EOD, 50)
472
+ Commands in this group deal with various aspects of the production of
473
+ output files:
474
+ * output file location
475
+ * post-processing (including automatic display)
476
+ * cleanup...
477
+ EOD
478
+
479
+ PageSizeCommand =
480
+ Cmd.new("page-size",'-r',"--page-size",
481
+ [ CmdArg.new('text') ], # TODO: change that !
482
+ { 'count-legend' => CmdArg.new('boolean')}
483
+ ) do |plotmaker, size, options|
484
+ plotmaker.root_object.set_page_size(size)
485
+ if options.key? 'count-legend'
486
+ plotmaker.root_object.count_legend_in_page =
487
+ options['count-legend']
488
+ end
489
+ end
490
+
491
+ PageSizeCommand.describe('Sets the page size',
492
+ <<EOH, OutputSetupGroup)
493
+ Sets the size of the output PDF file, in real units. Takes arguments in the
494
+ form of 12cm x 3in (spaces can be omitted).
495
+ EOH
496
+
497
+ CleanupCommand =
498
+ Cmd.new("clean",nil,"--clean",
499
+ [ CmdArg.new('boolean') ]) do |plotmaker, cleanup|
500
+ plotmaker.cleanup = cleanup
501
+ end
502
+
503
+
504
+ CleanupCommand.describe('Remove intermediate files',
505
+ <<EOH, OutputSetupGroup)
506
+ When this is on (the default), ctioga2 automatically cleans up
507
+ intermediate files produced by Tioga. When LaTeX fails, it can be
508
+ useful to have a closer look at them, so disable it to be able to look
509
+ into them.
510
+ EOH
511
+
512
+
513
+ NameCommand =
514
+ Cmd.new("name",'-n',"--name",
515
+ [ CmdArg.new('text', 'figure name') ]) do |plotmaker, name|
516
+ plotmaker.figure_name = name
517
+ end
518
+
519
+
520
+ NameCommand.describe('Sets the name of the figure',
521
+ <<EOH, OutputSetupGroup)
522
+ Sets the name of the figure, which is also the base name for the output file.
523
+ This has nothing to do with the title of the plot, which can be set using
524
+ the command {command: title}.
525
+ EOH
526
+
527
+ OutputNowCommand =
528
+ Cmd.new("output-now",'-o',"--output",
529
+ [ CmdArg.new('text', 'figure name') ]) do |plotmaker, name|
530
+ plotmaker.draw_figure(name)
531
+ end
532
+
533
+ OutputNowCommand.describe('Outputs the current state of the figure',
534
+ <<EOH, OutputSetupGroup)
535
+ Writes a figure with the given name (see {command: name}) and keeps the
536
+ current state. This can be used to create an animation.
537
+ EOH
538
+
539
+ OutputAndResetCommand =
540
+ Cmd.new("output-and-reset",nil,"--output-and-reset",
541
+ [ ]) do |plotmaker|
542
+ plotmaker.reset_graphics
543
+ end
544
+
545
+ OutputAndResetCommand.describe('Writes the current figure and starts anew',
546
+ <<EOH, OutputSetupGroup)
547
+ Writes the current figure and starts a fresh one. All non-graphical
548
+ information are kept (curves loaded, figure names, preamble, and so on).
549
+ EOH
550
+
551
+ OutputDirCommand =
552
+ Cmd.new("output-directory",'-O',"--output-directory",
553
+ [ CmdArg.new('text') ]) do |plotmaker, dir|
554
+ plotmaker.output_directory = dir
555
+ end
556
+
557
+ OutputDirCommand.describe('Sets the output directory for produced files',
558
+ <<EOH, OutputSetupGroup)
559
+ Sets the directory to which files will be plot. It defaults to the current
560
+ directory.
561
+ EOH
562
+
563
+
564
+ # These commands belong rather to the PostProcess file, but, well,
565
+ # they don't do much harm here anyway...
566
+
567
+
568
+ ViewerCommand =
569
+ Cmd.new("viewer",nil,"--viewer",
570
+ [ CmdArg.new('text') ]) do |plotmaker, viewer|
571
+ plotmaker.postprocess.viewer = viewer
572
+ end
573
+
574
+ ViewerCommand.describe('Uses the given viewer to view the produced PDF files',
575
+ <<EOH, OutputSetupGroup)
576
+ Sets the command for viewing the PDF file after ctioga2 has been run.
577
+ EOH
578
+
579
+ XpdfViewerCommand =
580
+ Cmd.new("xpdf",'-X',"--xpdf", [ ]) do |plotmaker|
581
+ plotmaker.postprocess.viewer = "xpdf -z page"
582
+ end
583
+
584
+ XpdfViewerCommand.describe('Uses xpdf to view the produced PDF files',
585
+ <<EOH, OutputSetupGroup)
586
+ Uses xpdf to view the PDF files produced by ctioga2.
587
+ EOH
588
+
589
+ OpenViewerCommand =
590
+ Cmd.new("open",nil,"--open", [ ]) do |plotmaker|
591
+ plotmaker.postprocess.viewer = "open"
592
+ end
593
+
594
+ OpenViewerCommand.describe('Uses open to view the produced PDF files',
595
+ <<EOH, OutputSetupGroup)
596
+ Uses open (available on MacOS) to view the PDF files produced by ctioga2.
597
+ EOH
598
+
599
+ SVGCommand =
600
+ Cmd.new("svg",nil,"--svg",
601
+ [CmdArg.new('boolean') ]) do |plotmaker,val|
602
+ plotmaker.postprocess.svg = val
603
+ end
604
+
605
+ SVGCommand.describe('Converts produced PDF to SVG using pdf2svg',
606
+ <<EOH, OutputSetupGroup)
607
+ When this feature is on, all produced PDF files are converted to SVG
608
+ using the neat pdf2svg program.
609
+ EOH
610
+
611
+ EPSCommand =
612
+ Cmd.new("eps",nil,"--eps",
613
+ [CmdArg.new('boolean') ]) do |plotmaker,val|
614
+ plotmaker.postprocess.eps = val
615
+ end
616
+
617
+ EPSCommand.describe('Converts produced PDF to EPS using pdftops',
618
+ <<EOH, OutputSetupGroup)
619
+ When this feature is on, all produced PDF files are converted to EPS
620
+ using the pdftops program (from the xpdf tools suite).
621
+ EOH
622
+
623
+ PNGCommand =
624
+ Cmd.new("png",nil,"--png",
625
+ [CmdArg.new('text', 'resolution') ],
626
+ {
627
+ 'oversampling' => CmdArg.new('float'),
628
+ 'scale' => CmdArg.new('float'),
629
+ }) do |plotmaker,res, opts|
630
+ if res =~ /^\s*(\d+)\s*x\s*(\d+)\s*$/
631
+ size = [$1.to_i, $2.to_i]
632
+ plotmaker.postprocess.png_res = size
633
+ if opts['oversampling']
634
+ plotmaker.postprocess.png_oversampling = opts['oversampling']
635
+ end
636
+ scale = opts['scale'] || 1
637
+ plotmaker.postprocess.png_scale = scale
638
+ page_size = size.map { |n| (n/(1.0 *scale)).to_s + "bp" }.join('x')
639
+ plotmaker.root_object.set_page_size(page_size)
640
+ else
641
+ raise "Invalid resolution for PNG output: #{res}"
642
+ end
643
+ end
644
+
645
+ PNGCommand.describe('Converts produced PDF to PNG using convert',
646
+ <<EOH, OutputSetupGroup)
647
+ Turns all produced PDF files into PNG images of the given resolution
648
+ using convert. This also has for effect to set the {command:
649
+ page-size} to the resolution divided by the 'scale' option in
650
+ Postscript points. By default, 2 pixels are rendered for 1 final to
651
+ produce a nicely antialiased image. Use the 'oversampling' option to
652
+ change that, in case the output looks too pixelized. This option only
653
+ affects conversion time.
654
+ EOH
655
+
656
+ MarkCommand =
657
+ Cmd.new("mark",nil,"--mark",
658
+ [CmdArg.new('boolean') ]) do |plotmaker,val|
659
+ plotmaker.mark = val
660
+ end
661
+
662
+ MarkCommand.describe('Fills the title of the produced PDF with the command-line',
663
+ <<EOH, OutputSetupGroup)
664
+ When this feature is on (which is the default, as it comes in very
665
+ useful), the 'title' field of the PDF informations is set to the
666
+ command-line that resulted in the PDF file. Disable it if you don't
667
+ want any information to leak.
668
+
669
+ Please note that this will not log the values of the CTIOGA2_PRE and
670
+ CTIOGA2_POST variables, so you might still get a different output if
671
+ you make heavy use of those.
672
+ EOH
673
+
674
+ end
675
+
676
+ end
677
+