ctioga 1.11.1
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 +340 -0
- data/ctioga/bin/ctable +28 -0
- data/ctioga/bin/ctioga +37 -0
- data/ctioga/doc/ctable.1 +156 -0
- data/ctioga/doc/ctioga.1 +2363 -0
- data/ctioga/examples/README +46 -0
- data/ctioga/examples/ctioga.gnuplot +4 -0
- data/ctioga/examples/ctioga_within_tioga.rb +53 -0
- data/ctioga/examples/ctiogarc.rb +24 -0
- data/ctioga/examples/include_1.rb +15 -0
- data/ctioga/examples/noise.dat +100 -0
- data/ctioga/examples/noise.rb +13 -0
- data/ctioga/examples/trig.csv +100 -0
- data/ctioga/examples/trig.dat +100 -0
- data/ctioga/examples/trig.rb +14 -0
- data/ctioga/examples/trigh.dat +100 -0
- data/ctioga/examples/trigh.rb +10 -0
- data/ctioga/examples/tutorial +763 -0
- data/ctioga/examples/tutorial.sh +269 -0
- data/ctioga/tests/README +14 -0
- data/ctioga/tests/axes.sh +40 -0
- data/ctioga/tests/basic.sh +11 -0
- data/ctioga/tests/draw.sh +24 -0
- data/ctioga/tests/histograms.sh +14 -0
- data/ctioga/tests/insets.sh +41 -0
- data/ctioga/tests/layouts.sh +29 -0
- data/ctioga/tests/legends.sh +113 -0
- data/ctioga/tests/styles.sh +43 -0
- data/ctioga/tests/test_style.sh +8 -0
- data/ctioga/tests/tests.sh +24 -0
- data/ctioga/tests/text_backend.sh +83 -0
- data/ctioga/tests/tioga_defaults.rb +18 -0
- data/lib/CTioga/axes.rb +904 -0
- data/lib/CTioga/backends.rb +88 -0
- data/lib/CTioga/boundaries.rb +224 -0
- data/lib/CTioga/ctable.rb +134 -0
- data/lib/CTioga/curve_style.rb +246 -0
- data/lib/CTioga/debug.rb +199 -0
- data/lib/CTioga/dimension.rb +133 -0
- data/lib/CTioga/elements.rb +17 -0
- data/lib/CTioga/elements/base.rb +84 -0
- data/lib/CTioga/elements/containers.rb +578 -0
- data/lib/CTioga/elements/curves.rb +368 -0
- data/lib/CTioga/elements/tioga_primitives.rb +440 -0
- data/lib/CTioga/layout.rb +595 -0
- data/lib/CTioga/legends.rb +29 -0
- data/lib/CTioga/legends/cmdline.rb +187 -0
- data/lib/CTioga/legends/item.rb +164 -0
- data/lib/CTioga/legends/style.rb +257 -0
- data/lib/CTioga/log.rb +73 -0
- data/lib/CTioga/movingarrays.rb +131 -0
- data/lib/CTioga/partition.rb +271 -0
- data/lib/CTioga/plot_style.rb +230 -0
- data/lib/CTioga/plotmaker.rb +1677 -0
- data/lib/CTioga/shortcuts.rb +69 -0
- data/lib/CTioga/structures.rb +82 -0
- data/lib/CTioga/styles.rb +140 -0
- data/lib/CTioga/themes.rb +581 -0
- data/lib/CTioga/themes/classical.rb +82 -0
- data/lib/CTioga/themes/demo.rb +63 -0
- data/lib/CTioga/themes/fits.rb +91 -0
- data/lib/CTioga/themes/mono.rb +33 -0
- data/lib/CTioga/tioga.rb +32 -0
- data/lib/CTioga/utils.rb +173 -0
- data/lib/MetaBuilder/Parameters/dates.rb +38 -0
- data/lib/MetaBuilder/Parameters/lists.rb +132 -0
- data/lib/MetaBuilder/Parameters/numbers.rb +69 -0
- data/lib/MetaBuilder/Parameters/strings.rb +86 -0
- data/lib/MetaBuilder/Parameters/styles.rb +75 -0
- data/lib/MetaBuilder/Qt4/Parameters/dates.rb +51 -0
- data/lib/MetaBuilder/Qt4/Parameters/numbers.rb +65 -0
- data/lib/MetaBuilder/Qt4/Parameters/strings.rb +106 -0
- data/lib/MetaBuilder/Qt4/parameter.rb +172 -0
- data/lib/MetaBuilder/Qt4/parameters.rb +9 -0
- data/lib/MetaBuilder/descriptions.rb +603 -0
- data/lib/MetaBuilder/factory.rb +101 -0
- data/lib/MetaBuilder/group.rb +57 -0
- data/lib/MetaBuilder/metabuilder.rb +10 -0
- data/lib/MetaBuilder/parameter.rb +374 -0
- data/lib/MetaBuilder/parameters.rb +11 -0
- data/lib/MetaBuilder/qt4.rb +8 -0
- data/lib/SciYAG/Backends/backend.rb +379 -0
- data/lib/SciYAG/Backends/binner.rb +168 -0
- data/lib/SciYAG/Backends/cache.rb +102 -0
- data/lib/SciYAG/Backends/dataset.rb +158 -0
- data/lib/SciYAG/Backends/descriptions.rb +469 -0
- data/lib/SciYAG/Backends/filters.rb +25 -0
- data/lib/SciYAG/Backends/filters/average.rb +134 -0
- data/lib/SciYAG/Backends/filters/cumulate.rb +37 -0
- data/lib/SciYAG/Backends/filters/filter.rb +70 -0
- data/lib/SciYAG/Backends/filters/norm.rb +39 -0
- data/lib/SciYAG/Backends/filters/smooth.rb +63 -0
- data/lib/SciYAG/Backends/filters/sort.rb +43 -0
- data/lib/SciYAG/Backends/filters/strip.rb +34 -0
- data/lib/SciYAG/Backends/filters/trim.rb +64 -0
- data/lib/SciYAG/Backends/gnuplot.rb +131 -0
- data/lib/SciYAG/Backends/math.rb +108 -0
- data/lib/SciYAG/Backends/mdb.rb +462 -0
- data/lib/SciYAG/Backends/multitext.rb +96 -0
- data/lib/SciYAG/Backends/source.rb +64 -0
- data/lib/SciYAG/Backends/text.rb +339 -0
- data/lib/SciYAG/backends.rb +16 -0
- metadata +191 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# log.rb, copyright (c) 2006 by Vincent Fourmond:
|
|
2
|
+
# The general logging functions for Ctioga
|
|
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
|
+
module CTioga
|
|
15
|
+
|
|
16
|
+
Version::register_svn_info('$Revision: 778 $', '$Date: 2008-03-09 03:44:48 +0100 (Sun, 09 Mar 2008) $')
|
|
17
|
+
|
|
18
|
+
# A class implementing small shortcuts, that is a set of command-line
|
|
19
|
+
# arguments.
|
|
20
|
+
class Shortcut
|
|
21
|
+
|
|
22
|
+
@@shortcut_list = {}
|
|
23
|
+
|
|
24
|
+
# The name of the shortcut
|
|
25
|
+
attr_accessor :name
|
|
26
|
+
|
|
27
|
+
# Its arguments
|
|
28
|
+
attr_accessor :arguments
|
|
29
|
+
|
|
30
|
+
def initialize(name, *args)
|
|
31
|
+
@name = name
|
|
32
|
+
@arguments = args
|
|
33
|
+
@@shortcut_list[name] = self
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.list
|
|
37
|
+
return @@shortcut_list.keys
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def self.has?(name)
|
|
41
|
+
return @@shortcut_list.key?(name)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def self.args(name)
|
|
45
|
+
return @@shortcut_list[name].arguments
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def self.pretty_print
|
|
49
|
+
for key in @@shortcut_list.keys.sort
|
|
50
|
+
val = @@shortcut_list[key]
|
|
51
|
+
puts "#{key}\t#{val.arguments.join(' ')}"
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
Shortcut.new('cloud', '--marker', 'auto', '--marker-scale', '0.2',
|
|
57
|
+
'--line-style', 'no')
|
|
58
|
+
|
|
59
|
+
Shortcut.new('filled', '--fill', 'y_axis', '--fill-transparency', '0.7')
|
|
60
|
+
|
|
61
|
+
Shortcut.new('csv', '--text-separator', '/[;,]/')
|
|
62
|
+
|
|
63
|
+
Shortcut.new('semilog', '--math-log', '--xlog')
|
|
64
|
+
|
|
65
|
+
Shortcut.new('fulllog', '--math-log', '--xlog', '--ylog')
|
|
66
|
+
|
|
67
|
+
Shortcut.new('axis-grid', '--lines-color', 'xaxis', 'Silver',
|
|
68
|
+
'--lines-color', 'yaxis', 'Silver')
|
|
69
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# structures.rb, copyright (c) 2006 by Vincent Fourmond:
|
|
2
|
+
# The code file for fancy structural elements.
|
|
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
|
+
require 'Dobjects/Dvector'
|
|
15
|
+
require 'CTioga/debug'
|
|
16
|
+
require 'CTioga/log'
|
|
17
|
+
|
|
18
|
+
require 'CTioga/elements'
|
|
19
|
+
|
|
20
|
+
module CTioga
|
|
21
|
+
|
|
22
|
+
Version::register_svn_info('$Revision: 653 $', '$Date: 2007-11-15 21:58:42 +0100 (Thu, 15 Nov 2007) $')
|
|
23
|
+
|
|
24
|
+
# A subplot class for handling plot with alternative axes.
|
|
25
|
+
class SharedAxisPlot < SubPlot
|
|
26
|
+
|
|
27
|
+
# The positions concerned by the axis type in the
|
|
28
|
+
# arrays returned by get_boundaries and the like.
|
|
29
|
+
BoundaryPositions = {
|
|
30
|
+
:y => [2,3],
|
|
31
|
+
:x => [0,1]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
# Some pseudo-accessors:
|
|
35
|
+
def shared_axis
|
|
36
|
+
if @axis == :y
|
|
37
|
+
:x
|
|
38
|
+
else
|
|
39
|
+
:y
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def private_axis
|
|
44
|
+
@axis
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Creates a subplot of _parent_ which will use alternative
|
|
48
|
+
# axes for _axis_. _axis_ is the axis which is *not* shared !
|
|
49
|
+
def initialize(axis = :y, parent = nil)
|
|
50
|
+
super(:subplot, parent)
|
|
51
|
+
@axis = axis
|
|
52
|
+
# We forward all legend information to the parent
|
|
53
|
+
@accept_legend = false
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Report appropriate values for the axes to the parent
|
|
57
|
+
# plot.
|
|
58
|
+
def get_boundaries
|
|
59
|
+
bounds = internal_get_boundaries
|
|
60
|
+
for i in BoundaryPositions[private_axis]
|
|
61
|
+
bounds[i] = 0.0/0.0 # NaN is ignored
|
|
62
|
+
end
|
|
63
|
+
return bounds
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# We use the parents boundary for the shared axis.
|
|
67
|
+
def compute_boundaries
|
|
68
|
+
# First, we compute the boundaries using the standard
|
|
69
|
+
# Subplot function
|
|
70
|
+
bounds = super
|
|
71
|
+
|
|
72
|
+
# Then we override the shared values using the parents:
|
|
73
|
+
parents = parent.compute_boundaries
|
|
74
|
+
for i in BoundaryPositions[shared_axis]
|
|
75
|
+
bounds[i] = parents[i] # We use the parents boundaries.
|
|
76
|
+
end
|
|
77
|
+
return bounds
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
end
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# styles.rb : style-related codes
|
|
2
|
+
# Copyright (C) 2007, 2008 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.
|
|
13
|
+
#
|
|
14
|
+
# You should have received a copy of the GNU General Public License
|
|
15
|
+
# along with this program; if not, write to the Free Software
|
|
16
|
+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
|
+
|
|
18
|
+
require 'MetaBuilder/parameters'
|
|
19
|
+
require 'Tioga/tioga'
|
|
20
|
+
require 'CTioga/utils'
|
|
21
|
+
|
|
22
|
+
module CTioga
|
|
23
|
+
|
|
24
|
+
Version::register_svn_info('$Revision: 874 $', '$Date: 2009-02-11 14:14:30 +0100 (Wed, 11 Feb 2009) $')
|
|
25
|
+
|
|
26
|
+
# This module holds a lot of constants for styles.
|
|
27
|
+
module Styles
|
|
28
|
+
include Tioga::FigureConstants
|
|
29
|
+
|
|
30
|
+
COLORS = {
|
|
31
|
+
"standard" =>
|
|
32
|
+
[Red, Green, Blue, Cyan, Magenta, Orange],
|
|
33
|
+
"pastel1" =>
|
|
34
|
+
[MediumSeaGreen, RoyalBlue, Pumpkin, DarkChocolate, Lilac, Crimson],
|
|
35
|
+
"colorblind" =>
|
|
36
|
+
[BrightBlue, Goldenrod, Coral, Lilac, FireBrick, RoyalPurple],
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
# The sets of markers.
|
|
40
|
+
MARKERS = {
|
|
41
|
+
"standard" =>
|
|
42
|
+
[Bullet, TriangleUp, Square, Plus, Times],
|
|
43
|
+
"open" =>
|
|
44
|
+
[BulletOpen, TriangleUpOpen, SquareOpen, PlusOpen, TimesOpen],
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
Line_Type_Dash_Dot_Dot = [[5,2,1,2,1,2],0]
|
|
48
|
+
Line_Type_Small_Dots = [[0.5,1],0]
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
# Linestyles.
|
|
52
|
+
LINES = {
|
|
53
|
+
"standard" =>
|
|
54
|
+
[Line_Type_Solid,
|
|
55
|
+
Line_Type_Dots,
|
|
56
|
+
Line_Type_Dashes,
|
|
57
|
+
Line_Type_Small_Dots,
|
|
58
|
+
Line_Type_Dot_Long_Dash,
|
|
59
|
+
Line_Type_Dash_Dot_Dot
|
|
60
|
+
],
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
# Shortcut for line styles:
|
|
64
|
+
Solid = Line_Type_Solid
|
|
65
|
+
Dots = Line_Type_Dots
|
|
66
|
+
Dashes = Line_Type_Dashes
|
|
67
|
+
Small_Dots = Line_Type_Small_Dots
|
|
68
|
+
Dot_Long_Dash = Line_Type_Dot_Long_Dash
|
|
69
|
+
Dash_Dot_Dot = Line_Type_Dash_Dot_Dot
|
|
70
|
+
|
|
71
|
+
# Now, a series of ParameterType objects that help parsing
|
|
72
|
+
# a string into a style object
|
|
73
|
+
|
|
74
|
+
# A CTioga color
|
|
75
|
+
class CTiogaColorParameter < MetaBuilder::ParameterType
|
|
76
|
+
type_name :color, 'color'
|
|
77
|
+
|
|
78
|
+
def string_to_type_internal(str)
|
|
79
|
+
return CTioga.get_tioga_color(str)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def type_to_string_internal(val)
|
|
83
|
+
return val.map {|i| i.to_s}.join(',')
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# A CTioga marker
|
|
88
|
+
class CTiogaMarkerParameter < MetaBuilder::ParameterType
|
|
89
|
+
type_name :marker, 'marker'
|
|
90
|
+
|
|
91
|
+
def string_to_type_internal(str)
|
|
92
|
+
if str =~ /(\d+)\s*,\s*(\d+)(?:\s*,\s*([\d.e+-]+))?/
|
|
93
|
+
ar = [$1.to_i, $2.to_i]
|
|
94
|
+
if $3
|
|
95
|
+
ar << $3.to_f
|
|
96
|
+
end
|
|
97
|
+
return ar
|
|
98
|
+
else
|
|
99
|
+
begin
|
|
100
|
+
return Tioga::MarkerConstants.const_get(str)
|
|
101
|
+
rescue
|
|
102
|
+
raise IncorrectInput, "'#{str}' is not a valid marker"
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def type_to_string_internal(val)
|
|
108
|
+
return val.map {|i| i.to_s}.join(',')
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
class CTiogaLineStyleParameter < MetaBuilder::ParameterType
|
|
113
|
+
type_name :line_style, 'linestyle'
|
|
114
|
+
|
|
115
|
+
def string_to_type_internal(str)
|
|
116
|
+
if str =~ /(:?\d+\s*,)+/
|
|
117
|
+
ar = str.split(/\s*,\s*/).map{|v| v.to_f}
|
|
118
|
+
if ar.size % 2 == 0
|
|
119
|
+
return [ar, 0]
|
|
120
|
+
else
|
|
121
|
+
last = ar.pop
|
|
122
|
+
return [ar, last]
|
|
123
|
+
end
|
|
124
|
+
elsif Tioga::FigureConstants.const_defined?(str)
|
|
125
|
+
return Tioga::FigureConstants.const_get(str)
|
|
126
|
+
elsif Styles.const_defined?(str)
|
|
127
|
+
return Styles.const_get(str)
|
|
128
|
+
else
|
|
129
|
+
raise IncorrectInput, "'#{str}' is not a valid line type"
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def type_to_string_internal(val)
|
|
134
|
+
return val.flatten.map {|i| i.to_s}.join(',')
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
end
|
|
140
|
+
end
|
|
@@ -0,0 +1,581 @@
|
|
|
1
|
+
# themes.rb, copyright (c) 2007 by Vincent Fourmond:
|
|
2
|
+
# The main support for themes in ctioga
|
|
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
|
+
require 'CTioga/log'
|
|
15
|
+
require 'CTioga/utils'
|
|
16
|
+
require 'CTioga/shortcuts'
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
module CTioga
|
|
20
|
+
|
|
21
|
+
Version::register_svn_info('$Revision: 869 $', '$Date: 2009-01-13 17:56:12 +0100 (Tue, 13 Jan 2009) $')
|
|
22
|
+
|
|
23
|
+
# The namespace for themes. Supposedly, all themes should end up
|
|
24
|
+
# here.
|
|
25
|
+
module Themes
|
|
26
|
+
|
|
27
|
+
class BaseTheme
|
|
28
|
+
|
|
29
|
+
THEMES = {}
|
|
30
|
+
|
|
31
|
+
# Basic initialization. Cannot take any compulsory parameter
|
|
32
|
+
def initialize
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Returns an object appropriate to describe the
|
|
36
|
+
# style of the next curve. It must return all information
|
|
37
|
+
# as appropriate, in the form of a CurveStyle object.
|
|
38
|
+
# It takes the _name_ of the next set.
|
|
39
|
+
def next_curve_style(name)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# A hook to be run at the beginning of the drawing.
|
|
43
|
+
# _t_ is the FigureMaker object.
|
|
44
|
+
def bod_hook(t)
|
|
45
|
+
# Does nothing by default.
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# returns extra arguments to be pushed onto the
|
|
49
|
+
# cmdline. Can come in useful if you don't want to
|
|
50
|
+
# play with ctiog's internals
|
|
51
|
+
def cmdline_extra_args
|
|
52
|
+
return []
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# A function to be reimplemented by children to handle color_
|
|
56
|
+
def choose_set(type,set)
|
|
57
|
+
warn "Theme #{self.class.name} does not support sets"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# A callback to register themes.
|
|
61
|
+
def self.inherited(cls)
|
|
62
|
+
# THEMES[cls.name] = cls # Probably too long to be useful.
|
|
63
|
+
THEMES[cls.name.split(/::/).last.gsub(/Theme/,"")] = cls
|
|
64
|
+
THEMES[cls.name.split(/::/).last.gsub(/Theme/,"").downcase] = cls
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# Now, some code to be used as an inclusion directly.
|
|
71
|
+
|
|
72
|
+
attr_accessor :override_style
|
|
73
|
+
attr_accessor :histogram
|
|
74
|
+
|
|
75
|
+
# Resets the override_style to default:
|
|
76
|
+
|
|
77
|
+
def reset_override_style
|
|
78
|
+
@override_style = CurveStyle.new
|
|
79
|
+
|
|
80
|
+
# To reproduce old ctioga behavior, we manually set
|
|
81
|
+
# :marker to false
|
|
82
|
+
@override_style[:marker] = false
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def initialize_themes
|
|
86
|
+
# Initialize override_style
|
|
87
|
+
reset_override_style
|
|
88
|
+
|
|
89
|
+
# Start with an inexistant style to restore
|
|
90
|
+
@restored_style = nil
|
|
91
|
+
|
|
92
|
+
# The style stack; every single style used is pushed there
|
|
93
|
+
@style_stack = []
|
|
94
|
+
|
|
95
|
+
# The hash used for named saves
|
|
96
|
+
@saved_styles = {}
|
|
97
|
+
|
|
98
|
+
# And for saved overrides
|
|
99
|
+
@saved_overrides = {}
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
# We look for themes in the themes subdirectory of the directory
|
|
103
|
+
# where this file is found and in the $HOME/.ctioga/themes
|
|
104
|
+
for f in Dir.glob(File.dirname(__FILE__) + "/themes/*") +
|
|
105
|
+
Dir.glob("#{ENV['HOME']}/.ctioga/themes/*")
|
|
106
|
+
begin
|
|
107
|
+
require f
|
|
108
|
+
info "Successfully loaded theme file #{f}"
|
|
109
|
+
rescue Exception => e
|
|
110
|
+
warn "Failed to load theme file #{f}, ignoring"
|
|
111
|
+
debug "Failed to load theme #{f} with #{e.inspect}"
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# The current theme:
|
|
116
|
+
choose_theme(BaseTheme::THEMES.keys.first) unless
|
|
117
|
+
choose_theme('Classical')
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Selects the current theme:
|
|
121
|
+
def choose_theme(theme_name)
|
|
122
|
+
if BaseTheme::THEMES.key?(theme_name)
|
|
123
|
+
@theme_name = theme_name
|
|
124
|
+
@theme = BaseTheme::THEMES[theme_name].new
|
|
125
|
+
info "Selecting theme #{theme_name}"
|
|
126
|
+
args = @theme.cmdline_extra_args
|
|
127
|
+
debug "Theme #{theme_name} pushes #{args.join ' '} onto the "+
|
|
128
|
+
"command line"
|
|
129
|
+
unshift_cmdline_args(*args)
|
|
130
|
+
return true
|
|
131
|
+
else
|
|
132
|
+
warn "Theme #{theme_name} doesn't exist, ignoring"
|
|
133
|
+
return false
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
DisableRe = /no(ne)?|off/i
|
|
138
|
+
|
|
139
|
+
# Processes a style argument.
|
|
140
|
+
|
|
141
|
+
# A correspondance style_element -> style type
|
|
142
|
+
StyleTypes = {
|
|
143
|
+
:color => :color,
|
|
144
|
+
:colors => :color,
|
|
145
|
+
:marker => :marker,
|
|
146
|
+
:markers => :marker,
|
|
147
|
+
:marker_color => :color,
|
|
148
|
+
:markers_colors => :color,
|
|
149
|
+
:line_style => :line_style,
|
|
150
|
+
:linestyle => :line_style,
|
|
151
|
+
:linewidth => :float,
|
|
152
|
+
:error_bar_color => :color,
|
|
153
|
+
:marker_scale => :float,
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
# Parses a style argument, in three different ways:
|
|
157
|
+
# * an 'auto' will remove the override
|
|
158
|
+
# * something matching DisableRe will turn it false
|
|
159
|
+
# * anything else will be converted using the appropriate
|
|
160
|
+
# type found in StyleTypes or using the block given
|
|
161
|
+
def style_argument(style_element, value)
|
|
162
|
+
if value =~ /auto/i
|
|
163
|
+
override_style.delete(style_element)
|
|
164
|
+
debug "Deleting override #{style_element}"
|
|
165
|
+
return
|
|
166
|
+
elsif value =~ DisableRe or not value
|
|
167
|
+
override_style[style_element] = false
|
|
168
|
+
else
|
|
169
|
+
override_style[style_element] =
|
|
170
|
+
if block_given?
|
|
171
|
+
yield(value)
|
|
172
|
+
else
|
|
173
|
+
begin
|
|
174
|
+
MetaBuilder::ParameterType.from_string(StyleTypes[style_element],
|
|
175
|
+
value)
|
|
176
|
+
rescue Exception => e
|
|
177
|
+
if e.is_a? MetaBuilder::ParameterType::IncorrectInput
|
|
178
|
+
warn "The argument for #{style_element} was not recognized:"
|
|
179
|
+
warn e.message
|
|
180
|
+
warn "Expect problems later"
|
|
181
|
+
end
|
|
182
|
+
value
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
debug "Setting override #{style_element} to " +
|
|
187
|
+
"#{override_style[style_element].inspect}"
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def theme_prepare_parser(parser)
|
|
192
|
+
parser.separator "\nStyle and themes options"
|
|
193
|
+
parser.on("-c", "--[no-]color COLOR",
|
|
194
|
+
"Sets the color for drawing the curves.",
|
|
195
|
+
"Use 'auto' to leave the decision to ",
|
|
196
|
+
"the themes, and 'no' to get no lines.") do |val|
|
|
197
|
+
style_argument(:color, val)
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
parser.on("-m", "--[no-]marker [MARKER]",
|
|
201
|
+
"Sets the markers for drawing data points",
|
|
202
|
+
"Use 'auto' to get automatic markers,",
|
|
203
|
+
"and 'no' to get no marker (the default)") do |val|
|
|
204
|
+
style_argument(:marker, val)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
parser.on("--marker-color COLOR",
|
|
208
|
+
"Sets the markers' color. See also --color") do |val|
|
|
209
|
+
style_argument(:marker_color, val)
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
parser.on("--[no-]line-style STYLE",
|
|
213
|
+
"Sets the line style") do |val|
|
|
214
|
+
style_argument(:line_style, val)
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
parser.on("--line-width WIDTH",
|
|
218
|
+
"Sets the line width") do |w|
|
|
219
|
+
style_argument(:linewidth, w) do |val|
|
|
220
|
+
Float(val)
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
parser.on("--[no-]interpolate",
|
|
225
|
+
"If set, the points will be joined", "by a nice "+
|
|
226
|
+
"interpolated curve") do |w|
|
|
227
|
+
override_style.interpolate = w
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
parser.on("--marker-scale SCALE",
|
|
231
|
+
"The scale of the markers used for curves.",
|
|
232
|
+
"Defaults to 0.5"
|
|
233
|
+
) do |w|
|
|
234
|
+
style_argument(:marker_scale, w)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
parser.on("--error-bar-color COLOR",
|
|
238
|
+
"Sets the error bars' color. See also --color") do |val|
|
|
239
|
+
style_argument(:error_bar_color, val)
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
parser.on("--drawing-order ORDER",
|
|
243
|
+
"Sets the order for drawing curve elements") do |val|
|
|
244
|
+
begin
|
|
245
|
+
style_argument(:drawing_order, val) do |v|
|
|
246
|
+
i = Integer(v)
|
|
247
|
+
CurveStyle::DrawingOrder.fetch(i) # To raise an
|
|
248
|
+
# exception in case i is not valid
|
|
249
|
+
i
|
|
250
|
+
end
|
|
251
|
+
rescue
|
|
252
|
+
puts "Invalid drawing order #{val}. Valid ones are the " +
|
|
253
|
+
"following integers"
|
|
254
|
+
CurveStyle::DrawingOrder.each_with_index do |vals, i|
|
|
255
|
+
puts "#{i} -> #{vals.map {|s| s.to_s}.join(', ')}"
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
parser.separator 'Transparency options'
|
|
261
|
+
parser.on("--transparency T",
|
|
262
|
+
"Sets the transparency for lines.") do |val|
|
|
263
|
+
style_argument(:transparency, val) do |v|
|
|
264
|
+
begin
|
|
265
|
+
Float(v)
|
|
266
|
+
rescue
|
|
267
|
+
false
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
parser.on("--marker-transparency T",
|
|
273
|
+
"Sets the transparency for markers.") do |val|
|
|
274
|
+
style_argument(:marker_transparency, val) do |v|
|
|
275
|
+
begin
|
|
276
|
+
Float(v)
|
|
277
|
+
rescue
|
|
278
|
+
false
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
parser.on("--error-bar-transparency T",
|
|
284
|
+
"Sets the transparency for error bars.") do |val|
|
|
285
|
+
style_argument(:error_bars_transparency, val) do |v|
|
|
286
|
+
begin
|
|
287
|
+
Float(v)
|
|
288
|
+
rescue
|
|
289
|
+
false
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
parser.separator 'Filled curves'
|
|
296
|
+
parser.on("--fill TYPE",
|
|
297
|
+
"Set the filling type for curves to TYPE") do |val|
|
|
298
|
+
style_argument(:fill_type, val) do |v|
|
|
299
|
+
Utils.interpret_arg(v, CurveStyle::FillTypeArguments)
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
parser.on("--fill-color COLOR",
|
|
304
|
+
"Set the fill color") do |val|
|
|
305
|
+
style_argument(:fill_color, val) do |v|
|
|
306
|
+
CTioga.get_tioga_color(v)
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
parser.on("--fill-transparency T",
|
|
311
|
+
"Set the fill color") do |val|
|
|
312
|
+
style_argument(:fill_transparency, val) do |v|
|
|
313
|
+
begin
|
|
314
|
+
Float(v)
|
|
315
|
+
rescue
|
|
316
|
+
false
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
parser.separator 'Histograms'
|
|
322
|
+
parser.on("--[no-]histogram",
|
|
323
|
+
"All the next curves will be drawn",
|
|
324
|
+
"as histograms. Deprecated.",
|
|
325
|
+
"Please use the --hist option") do |w|
|
|
326
|
+
@histogram = w
|
|
327
|
+
style_argument(:hist_type, false)
|
|
328
|
+
end
|
|
329
|
+
parser.on("--hist TYPE",
|
|
330
|
+
"Makes histograms from the next curves.",
|
|
331
|
+
"TYPE specifies where the step should start from,",
|
|
332
|
+
"See --fill-type for that") do |w|
|
|
333
|
+
w = false if w =~ DisableRe
|
|
334
|
+
if w
|
|
335
|
+
@histogram = true
|
|
336
|
+
style_argument(:hist_type, w) do |v|
|
|
337
|
+
Utils.interpret_arg(v, CurveStyle::FillTypeArguments)
|
|
338
|
+
end
|
|
339
|
+
else
|
|
340
|
+
@histogram = false
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
parser.on("--no-hist",
|
|
345
|
+
"Stop making histograms") do
|
|
346
|
+
@histogram = false
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
parser.on("--hist-width WIDTH",
|
|
350
|
+
"The ratio of the width drawn over the ",
|
|
351
|
+
"total width") do |w|
|
|
352
|
+
a = Float(w)
|
|
353
|
+
style_argument(:hist_left, (1 - a)/2)
|
|
354
|
+
style_argument(:hist_right, (1 + a)/2)
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
parser.on("--hist-left LEFT",
|
|
358
|
+
"The position of the left side of the step",
|
|
359
|
+
"relative to the total step") do |val|
|
|
360
|
+
style_argument(:hist_left, val) do |v|
|
|
361
|
+
begin
|
|
362
|
+
Float(v)
|
|
363
|
+
rescue
|
|
364
|
+
false
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
end
|
|
368
|
+
parser.on("--hist-right RIGHT",
|
|
369
|
+
"Pendant of --hist-left for the right") do |val|
|
|
370
|
+
style_argument(:hist_right, val) do |v|
|
|
371
|
+
begin
|
|
372
|
+
Float(v)
|
|
373
|
+
rescue
|
|
374
|
+
false
|
|
375
|
+
end
|
|
376
|
+
end
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
parser.separator 'Themes and sets'
|
|
381
|
+
parser.on("--theme THEME",
|
|
382
|
+
"Chooses the current theme. See --theme-list for ",
|
|
383
|
+
"a list of current valid themes"
|
|
384
|
+
) do |w|
|
|
385
|
+
choose_theme(w)
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
parser.on("--theme-list",
|
|
389
|
+
"Lists available themes.") do
|
|
390
|
+
puts
|
|
391
|
+
puts "Currently available themes are"
|
|
392
|
+
puts
|
|
393
|
+
puts BaseTheme::THEMES.keys.map {|i| i.downcase}.uniq.join(" ")
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
parser.on("--reset-theme",
|
|
397
|
+
"Resets theme defaults.") do
|
|
398
|
+
choose_theme(@theme_name)
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
parser.on("--mono",
|
|
403
|
+
"Compatibility option for --theme mono") do |w|
|
|
404
|
+
choose_theme('mono')
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
# TODO: there is no reason why sets should be restricted
|
|
408
|
+
# to the following things. All style things should
|
|
409
|
+
# potentially have a corresponding style-set.
|
|
410
|
+
#
|
|
411
|
+
# In short, all styles things should be converted to something
|
|
412
|
+
# more in the spirit of Parameter and the like...
|
|
413
|
+
|
|
414
|
+
# Sets:
|
|
415
|
+
# Note that, due to scoping side-effects, one has to use the
|
|
416
|
+
# block form of the iteration, else type gets overwritten
|
|
417
|
+
# and we end up writing only to the last possibility.
|
|
418
|
+
#
|
|
419
|
+
# In addition to (and taking over) specifying named sets,
|
|
420
|
+
# it is possible to provide:
|
|
421
|
+
# * a single style element, in which case the set becomes the
|
|
422
|
+
# new element
|
|
423
|
+
# * a |-separated list of elements, in which case the set
|
|
424
|
+
# becomes the given elements
|
|
425
|
+
{
|
|
426
|
+
:colors => "color",
|
|
427
|
+
:markers => "marker",
|
|
428
|
+
:markers_colors => "marker-color",
|
|
429
|
+
:linestyle => "line-style"
|
|
430
|
+
}.each do |type, name|
|
|
431
|
+
parser.on("--#{name}-set SET",
|
|
432
|
+
"Choose the current set for #{name} ",
|
|
433
|
+
"(#{@theme.sets[type].available_sets.join(' ')})") do |set|
|
|
434
|
+
debug "Using set '#{set}' for #{type} on theme " +
|
|
435
|
+
"#{current_theme.class}"
|
|
436
|
+
if target_set = current_theme.sets[type]
|
|
437
|
+
begin
|
|
438
|
+
# If there is one '|', we split the
|
|
439
|
+
if ! target_set.valid_set?(set)
|
|
440
|
+
debug "#{set} is not a named set for #{type}, " +
|
|
441
|
+
"trying other interpretations"
|
|
442
|
+
|
|
443
|
+
if set =~ /\|/
|
|
444
|
+
set = SpecialArray.new(set.split(/\|/).map do |x|
|
|
445
|
+
MetaBuilder::ParameterType.
|
|
446
|
+
from_string(StyleTypes[type], x)
|
|
447
|
+
end)
|
|
448
|
+
info "Setting set #{name} to objects #{set.inspect}"
|
|
449
|
+
else
|
|
450
|
+
set = MetaBuilder::ParameterType.
|
|
451
|
+
from_string(StyleTypes[type], set)
|
|
452
|
+
info "Setting set #{name} to single-value object #{set.inspect}"
|
|
453
|
+
end
|
|
454
|
+
end
|
|
455
|
+
current_theme.choose_set(type, set)
|
|
456
|
+
rescue Exception => e
|
|
457
|
+
error "Set #{set} was not understood for #{name}, ignoring"
|
|
458
|
+
debug "Exception raised on set interpretation code: #{e.inspect}"
|
|
459
|
+
end
|
|
460
|
+
else
|
|
461
|
+
warn "Theme #{current_theme.class} does not appear to have " +
|
|
462
|
+
"sets for #{type}, ignoring"
|
|
463
|
+
end
|
|
464
|
+
end
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
parser.separator 'Style manipulations'
|
|
468
|
+
|
|
469
|
+
parser.on("--skip-style",
|
|
470
|
+
"Skips the next style" ) do
|
|
471
|
+
@theme.next_curve_style("useless")
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
parser.on("-s", "--same-style",
|
|
475
|
+
"Uses the same style as last curve as a base ",
|
|
476
|
+
"for next curve") do
|
|
477
|
+
@restored_style = @style_stack.last
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
parser.on("--save-style NAME",
|
|
481
|
+
"Saves the style of the last curve for later use") do |n|
|
|
482
|
+
@saved_styles[n] = @style_stack.last
|
|
483
|
+
end
|
|
484
|
+
parser.on("--use-style NAME",
|
|
485
|
+
"Uses the style named NAME for the next curve",
|
|
486
|
+
"If NAME does not exist, it will be interpreted as",
|
|
487
|
+
"the 0-numbered style starting from the first") do |n|
|
|
488
|
+
if @saved_styles.key?(n)
|
|
489
|
+
@restored_style = @saved_styles[n]
|
|
490
|
+
else
|
|
491
|
+
@restored_style = @style_stack[n.to_i]
|
|
492
|
+
end
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
parser.on("--reset-override",
|
|
496
|
+
"Resets style override") do
|
|
497
|
+
reset_override_style
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
parser.on("--save-override NAME",
|
|
501
|
+
"Saves the current override") do |n|
|
|
502
|
+
@saved_overrides[n] = @override_style.dup
|
|
503
|
+
# But we don't save the legend !!!
|
|
504
|
+
@saved_overrides[n].delete(:legend)
|
|
505
|
+
end
|
|
506
|
+
parser.on("--use-override NAME",
|
|
507
|
+
"Uses the override named NAME from now on") do |n|
|
|
508
|
+
if @saved_overrides.key?(n)
|
|
509
|
+
legend = @override_style.legend
|
|
510
|
+
@override_style = @saved_overrides[n].dup
|
|
511
|
+
if legend
|
|
512
|
+
@override_style[:legend] = legend
|
|
513
|
+
end
|
|
514
|
+
else
|
|
515
|
+
warn "Saved override #{n} does not exist"
|
|
516
|
+
end
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
parser.separator 'Shortcuts'
|
|
520
|
+
parser.on("--short SHORTCUT",
|
|
521
|
+
"Use given shortcut") do |name|
|
|
522
|
+
if Shortcut.has? name
|
|
523
|
+
# Function from Plotmaker:
|
|
524
|
+
unshift_cmdline_args(*Shortcut.args(name))
|
|
525
|
+
else
|
|
526
|
+
warn "Shortcut #{name} was not found"
|
|
527
|
+
end
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
parser.on("--short-list",
|
|
531
|
+
"Lists available shortcuts") do
|
|
532
|
+
puts "Available shortcuts:"
|
|
533
|
+
Shortcut.pretty_print
|
|
534
|
+
end
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
end
|
|
539
|
+
|
|
540
|
+
# The current theme:
|
|
541
|
+
def current_theme
|
|
542
|
+
return @theme
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
# Returns the current style and resets all pending elements.
|
|
547
|
+
def get_current_style(set)
|
|
548
|
+
debug "Legend: #{override_style.legend}"
|
|
549
|
+
|
|
550
|
+
# We look in @restored_style first.
|
|
551
|
+
style = @restored_style ||
|
|
552
|
+
@theme.next_curve_style(tex_quote_text(set))
|
|
553
|
+
@restored_style = nil # Canceled everytime.
|
|
554
|
+
|
|
555
|
+
style = style.dup # To make sure we don't overwrite anything.
|
|
556
|
+
if @autolegends
|
|
557
|
+
style.legend = tex_quote_text(set)
|
|
558
|
+
else
|
|
559
|
+
style.legend = false
|
|
560
|
+
end
|
|
561
|
+
debug "Override is #{override_style.inspect}"
|
|
562
|
+
style.override!(override_style)
|
|
563
|
+
|
|
564
|
+
# We remove the legend information, that it doesn't get used
|
|
565
|
+
# again.
|
|
566
|
+
override_style.delete(:legend)
|
|
567
|
+
debug "Style: #{style.inspect}"
|
|
568
|
+
|
|
569
|
+
# We push the last used style on the stack
|
|
570
|
+
@style_stack << style
|
|
571
|
+
return style
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
# Run the hook at beginning of the drawing:
|
|
575
|
+
def theme_bod_hook(t)
|
|
576
|
+
current_theme.bod_hook(t)
|
|
577
|
+
end
|
|
578
|
+
|
|
579
|
+
end
|
|
580
|
+
|
|
581
|
+
end
|