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.
- data/COPYING +339 -0
- data/Changelog +6 -0
- data/bin/ctioga2 +26 -0
- data/lib/ctioga2/commands/arguments.rb +58 -0
- data/lib/ctioga2/commands/commands.rb +258 -0
- data/lib/ctioga2/commands/doc/doc.rb +118 -0
- data/lib/ctioga2/commands/doc/documentation-commands.rb +119 -0
- data/lib/ctioga2/commands/doc/help.rb +95 -0
- data/lib/ctioga2/commands/doc/html.rb +230 -0
- data/lib/ctioga2/commands/doc/introspection.rb +211 -0
- data/lib/ctioga2/commands/doc/man.rb +279 -0
- data/lib/ctioga2/commands/doc/markup.rb +359 -0
- data/lib/ctioga2/commands/general-commands.rb +119 -0
- data/lib/ctioga2/commands/general-types.rb +118 -0
- data/lib/ctioga2/commands/groups.rb +73 -0
- data/lib/ctioga2/commands/interpreter.rb +257 -0
- data/lib/ctioga2/commands/parsers/command-line.rb +187 -0
- data/lib/ctioga2/commands/parsers/file.rb +186 -0
- data/lib/ctioga2/commands/strings.rb +303 -0
- data/lib/ctioga2/commands/type.rb +100 -0
- data/lib/ctioga2/commands/variables.rb +101 -0
- data/lib/ctioga2/data/backends/backend.rb +260 -0
- data/lib/ctioga2/data/backends/backends.rb +39 -0
- data/lib/ctioga2/data/backends/backends/gnuplot.rb +140 -0
- data/lib/ctioga2/data/backends/backends/math.rb +121 -0
- data/lib/ctioga2/data/backends/backends/text.rb +335 -0
- data/lib/ctioga2/data/backends/description.rb +405 -0
- data/lib/ctioga2/data/backends/factory.rb +73 -0
- data/lib/ctioga2/data/backends/parameter.rb +109 -0
- data/lib/ctioga2/data/datacolumn.rb +245 -0
- data/lib/ctioga2/data/dataset.rb +233 -0
- data/lib/ctioga2/data/filters.rb +131 -0
- data/lib/ctioga2/data/merge.rb +43 -0
- data/lib/ctioga2/data/point.rb +72 -0
- data/lib/ctioga2/data/stack.rb +294 -0
- data/lib/ctioga2/graphics/coordinates.rb +73 -0
- data/lib/ctioga2/graphics/elements.rb +111 -0
- data/lib/ctioga2/graphics/elements/containers.rb +111 -0
- data/lib/ctioga2/graphics/elements/curve2d.rb +155 -0
- data/lib/ctioga2/graphics/elements/element.rb +90 -0
- data/lib/ctioga2/graphics/elements/primitive.rb +256 -0
- data/lib/ctioga2/graphics/elements/subplot.rb +140 -0
- data/lib/ctioga2/graphics/generator.rb +68 -0
- data/lib/ctioga2/graphics/legends.rb +108 -0
- data/lib/ctioga2/graphics/legends/area.rb +199 -0
- data/lib/ctioga2/graphics/legends/items.rb +183 -0
- data/lib/ctioga2/graphics/legends/provider.rb +58 -0
- data/lib/ctioga2/graphics/legends/storage.rb +65 -0
- data/lib/ctioga2/graphics/root.rb +209 -0
- data/lib/ctioga2/graphics/styles.rb +30 -0
- data/lib/ctioga2/graphics/styles/axes.rb +247 -0
- data/lib/ctioga2/graphics/styles/background.rb +122 -0
- data/lib/ctioga2/graphics/styles/base.rb +115 -0
- data/lib/ctioga2/graphics/styles/carrays.rb +53 -0
- data/lib/ctioga2/graphics/styles/curve.rb +101 -0
- data/lib/ctioga2/graphics/styles/drawable.rb +87 -0
- data/lib/ctioga2/graphics/styles/factory.rb +351 -0
- data/lib/ctioga2/graphics/styles/legend.rb +63 -0
- data/lib/ctioga2/graphics/styles/plot.rb +410 -0
- data/lib/ctioga2/graphics/styles/sets.rb +64 -0
- data/lib/ctioga2/graphics/styles/texts.rb +277 -0
- data/lib/ctioga2/graphics/subplot-commands.rb +141 -0
- data/lib/ctioga2/graphics/types.rb +188 -0
- data/lib/ctioga2/graphics/types/bijection.rb +79 -0
- data/lib/ctioga2/graphics/types/boundaries.rb +170 -0
- data/lib/ctioga2/graphics/types/boxes.rb +157 -0
- data/lib/ctioga2/graphics/types/dimensions.rb +157 -0
- data/lib/ctioga2/graphics/types/point.rb +247 -0
- data/lib/ctioga2/log.rb +97 -0
- data/lib/ctioga2/metabuilder/type.rb +316 -0
- data/lib/ctioga2/metabuilder/types.rb +39 -0
- data/lib/ctioga2/metabuilder/types/coordinates.rb +124 -0
- data/lib/ctioga2/metabuilder/types/dates.rb +43 -0
- data/lib/ctioga2/metabuilder/types/lists.rb +188 -0
- data/lib/ctioga2/metabuilder/types/numbers.rb +97 -0
- data/lib/ctioga2/metabuilder/types/strings.rb +93 -0
- data/lib/ctioga2/metabuilder/types/styles.rb +178 -0
- data/lib/ctioga2/plotmaker.rb +677 -0
- data/lib/ctioga2/postprocess.rb +115 -0
- data/lib/ctioga2/utils.rb +120 -0
- data/setup.rb +1586 -0
- 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
|
+
|