iruby 0.1.11 → 0.1.12
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.
- checksums.yaml +4 -4
- data/CHANGES +7 -0
- data/lib/iruby.rb +1 -0
- data/lib/iruby/display.rb +247 -70
- data/lib/iruby/formatter.rb +73 -0
- data/lib/iruby/kernel.rb +1 -1
- data/lib/iruby/utils.rb +16 -54
- data/lib/iruby/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47cc7be0c54041de9aa2e48644f0812f5f902bbc
|
4
|
+
data.tar.gz: a656cdee3051efdd8db801c68ca12796577f2a6c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e18bc7e9a5fc371c552d58224a00ce42b0190c9e4e69e3be9c5bf0c2acaa137eaaf61d042c589197f77504d1fbd61aaa707306b41984d52386a86f7c8746cdae
|
7
|
+
data.tar.gz: 693f4ef8e4d09190326a05ee7ab62cbe2c06c72de5c7ab4c7a4ea502d720bbe363a9586bdba0fd4cc3a73c8db5d2fa807b019e73a39390725b3a05167c4c2432
|
data/CHANGES
CHANGED
data/lib/iruby.rb
CHANGED
data/lib/iruby/display.rb
CHANGED
@@ -1,40 +1,206 @@
|
|
1
1
|
module IRuby
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
2
|
+
module Display
|
3
|
+
class << self
|
4
|
+
def convert(obj, options)
|
5
|
+
Representation.new(obj, options)
|
6
|
+
end
|
7
|
+
|
8
|
+
def display(obj, options = {})
|
9
|
+
obj = convert(obj, options)
|
10
|
+
options = obj.options
|
11
|
+
obj = obj.object
|
12
|
+
|
13
|
+
exact_mime = options[:mime]
|
14
|
+
fuzzy_mime = options[:format] # Treated like a fuzzy mime type
|
15
|
+
raise 'Invalid argument :format' unless !fuzzy_mime || String === fuzzy_mime
|
16
|
+
if exact_mime
|
17
|
+
raise 'Invalid argument :mime' unless String === exact_mime
|
18
|
+
raise 'Invalid mime type' unless exact_mime.include?('/')
|
19
|
+
end
|
20
|
+
|
21
|
+
data = {}
|
22
|
+
|
23
|
+
# Render additional representation
|
24
|
+
render(data, obj, exact_mime, fuzzy_mime)
|
25
|
+
|
26
|
+
# IPython always requires a text representation
|
27
|
+
render(data, obj, 'text/plain', nil) unless data['text/plain']
|
28
|
+
|
29
|
+
# As a last resort, interpret string representation of the object
|
30
|
+
# as the given mime type.
|
31
|
+
data[exact_mime] = protect(exact_mime, obj) if exact_mime && !data.any? {|m,_| exact_mime == m }
|
32
|
+
|
33
|
+
data
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def protect(mime, data)
|
39
|
+
MimeMagic.new(mime).text? ? data.to_s : [data.to_s].pack('m0')
|
40
|
+
end
|
41
|
+
|
42
|
+
def render(data, obj, exact_mime, fuzzy_mime)
|
43
|
+
# Filter matching renderer by object type
|
44
|
+
renderer = Registry.renderer.select {|r| r.match?(obj) }
|
45
|
+
|
46
|
+
matching_renderer = nil
|
47
|
+
|
48
|
+
# Find exactly matching display by exact_mime
|
49
|
+
matching_renderer = renderer.find {|r| exact_mime == r.mime } if exact_mime
|
50
|
+
|
51
|
+
# Find fuzzy matching display by fuzzy_mime
|
52
|
+
matching_renderer ||= renderer.find {|r| r.mime && r.mime.include?(fuzzy_mime) } if fuzzy_mime
|
53
|
+
|
54
|
+
renderer.unshift matching_renderer if matching_renderer
|
55
|
+
|
56
|
+
# Return first render result which has the right mime type
|
57
|
+
renderer.each do |r|
|
58
|
+
mime, result = r.render(obj)
|
59
|
+
if mime && result && (!exact_mime || exact_mime == mime) && (!fuzzy_mime || mime.include?(fuzzy_mime))
|
60
|
+
data[mime] = protect(mime, result)
|
61
|
+
break
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
nil
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class Representation
|
70
|
+
attr_reader :object, :options
|
71
|
+
|
72
|
+
def initialize(object, options)
|
73
|
+
@object, @options = object, options
|
74
|
+
end
|
75
|
+
|
76
|
+
class << self
|
77
|
+
alias old_new new
|
78
|
+
|
79
|
+
def new(obj, options)
|
80
|
+
options = { format: options } if String === options
|
81
|
+
if Representation === obj
|
82
|
+
options = obj.options.merge(options)
|
83
|
+
obj = obj.object
|
84
|
+
end
|
85
|
+
old_new(obj, options)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
class Renderer
|
91
|
+
attr_reader :match, :mime, :render, :priority
|
92
|
+
|
93
|
+
def initialize(match, mime, render, priority)
|
94
|
+
@match, @mime, @render, @priority = match, mime, render, priority
|
95
|
+
end
|
96
|
+
|
97
|
+
def match?(obj)
|
98
|
+
@match.call(obj)
|
99
|
+
rescue NameError
|
100
|
+
false
|
101
|
+
end
|
102
|
+
|
103
|
+
def render(obj)
|
104
|
+
result = @render.call(obj)
|
105
|
+
Array === result ? result : [@mime, result]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
module Registry
|
110
|
+
extend self
|
111
|
+
|
112
|
+
def renderer
|
113
|
+
@renderer ||= []
|
114
|
+
end
|
115
|
+
|
116
|
+
SUPPORTED_MIMES = %w(
|
117
|
+
text/plain
|
118
|
+
text/html
|
119
|
+
text/latex
|
120
|
+
application/json
|
121
|
+
application/javascript
|
122
|
+
image/png
|
123
|
+
image/jpeg
|
124
|
+
image/svg+xml)
|
125
|
+
|
126
|
+
def match(&block)
|
127
|
+
@match = block
|
128
|
+
priority 0
|
129
|
+
nil
|
130
|
+
end
|
131
|
+
|
132
|
+
def respond_to(name)
|
133
|
+
match {|obj| obj.respond_to?(name) }
|
134
|
+
end
|
135
|
+
|
136
|
+
def type(&block)
|
137
|
+
match {|obj| block.call === obj }
|
138
|
+
end
|
139
|
+
|
140
|
+
def priority(p)
|
141
|
+
@priority = p
|
142
|
+
nil
|
143
|
+
end
|
144
|
+
|
145
|
+
def format(mime = nil, &block)
|
146
|
+
renderer << Renderer.new(@match, mime, block, @priority)
|
147
|
+
renderer.sort_by! {|r| -r.priority }
|
148
|
+
|
149
|
+
# Decrease priority implicitly for all formats
|
150
|
+
# which are added later for a type.
|
151
|
+
# Overwrite with the `priority` method!
|
152
|
+
@priority -= 1
|
153
|
+
nil
|
154
|
+
end
|
155
|
+
|
156
|
+
type { NMatrix }
|
157
|
+
format 'text/latex' do |obj|
|
158
|
+
obj.dim == 2 ?
|
159
|
+
LaTeX.matrix(obj, obj.shape[0], obj.shape[1]) :
|
160
|
+
LaTeX.vector(obj.to_a)
|
161
|
+
end
|
162
|
+
|
163
|
+
type { NArray }
|
164
|
+
format 'text/latex' do |obj|
|
165
|
+
obj.dim == 2 ?
|
166
|
+
LaTeX.matrix(obj.transpose, obj.shape[1], obj.shape[0]) :
|
167
|
+
LaTeX.vector(obj.to_a)
|
168
|
+
end
|
169
|
+
format 'text/html' do |obj|
|
170
|
+
HTML.table(obj.to_a)
|
171
|
+
end
|
172
|
+
|
173
|
+
type { Matrix }
|
174
|
+
format 'text/latex' do |obj|
|
175
|
+
LaTeX.matrix(obj, obj.row_count, obj.column_count)
|
176
|
+
end
|
177
|
+
format 'text/html' do |obj|
|
178
|
+
HTML.table(obj.to_a)
|
179
|
+
end
|
180
|
+
|
181
|
+
type { GSL::Matrix }
|
182
|
+
format 'text/latex' do |obj|
|
183
|
+
LaTeX.matrix(obj, obj.size1, obj.size2)
|
184
|
+
end
|
185
|
+
format 'text/html' do |obj|
|
186
|
+
HTML.table(obj.to_a)
|
187
|
+
end
|
188
|
+
|
189
|
+
type { GSL::Vector }
|
190
|
+
format 'text/latex' do |obj|
|
191
|
+
LaTeX.vector(obj.to_a)
|
192
|
+
end
|
193
|
+
format 'text/html' do |obj|
|
194
|
+
HTML.table(obj.to_a)
|
195
|
+
end
|
196
|
+
|
197
|
+
type { GSL::Complex }
|
198
|
+
format 'text/latex' do |obj|
|
199
|
+
"$#{obj.re}+#{obj.im}i$"
|
200
|
+
end
|
201
|
+
|
202
|
+
type { Gnuplot::Plot }
|
203
|
+
format 'image/svg+xml' do |obj|
|
38
204
|
Tempfile.open('plot') do |f|
|
39
205
|
obj.terminal 'svg enhanced'
|
40
206
|
obj.output f.path
|
@@ -42,47 +208,58 @@ module IRuby
|
|
42
208
|
io << obj.to_gplot
|
43
209
|
io << obj.store_datasets
|
44
210
|
end
|
45
|
-
|
211
|
+
File.read(f.path)
|
46
212
|
end
|
47
|
-
elsif defined?(Matrix) && Matrix === obj
|
48
|
-
add('text/latex', format_matrix(obj, obj.row_count, obj.column_count))
|
49
|
-
elsif defined?(GSL::Matrix) && GSL::Matrix === obj
|
50
|
-
add('text/latex', format_matrix(obj, obj.size1, obj.size2))
|
51
|
-
elsif defined?(GSL::Vector) && GSL::Vector === obj
|
52
|
-
add('text/latex', format_vector(obj.to_a))
|
53
|
-
elsif defined?(GSL::Complex) && GSL::Complex === obj
|
54
|
-
add('text/latex', "$#{obj.re}+#{obj.im}i$")
|
55
|
-
elsif defined?(NArray) && NArray === obj
|
56
|
-
add('text/latex', obj.dim == 2 ?
|
57
|
-
format_matrix(obj.transpose, obj.shape[1], obj.shape[0]) :
|
58
|
-
format_vector(obj.to_a))
|
59
|
-
elsif defined?(NMatrix) && NMatrix === obj
|
60
|
-
add('text/latex', obj.dim == 2 ?
|
61
|
-
format_matrix(obj, obj.shape[0], obj.shape[1]) :
|
62
|
-
format_vector(obj.to_a))
|
63
213
|
end
|
64
|
-
end
|
65
214
|
|
66
|
-
|
215
|
+
match {|obj| Magick::Image === obj || MiniMagick::Image === obj }
|
216
|
+
format 'image' do |obj|
|
217
|
+
format = obj.format || 'PNG'
|
218
|
+
[format == 'PNG' ? 'image/png' : 'image/jpeg', obj.to_blob {|i| i.format = format }]
|
219
|
+
end
|
67
220
|
|
68
|
-
|
69
|
-
|
70
|
-
|
221
|
+
type { Gruff::Base }
|
222
|
+
format 'image/png' do |obj|
|
223
|
+
obj.to_blob
|
224
|
+
end
|
71
225
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
226
|
+
respond_to :to_html
|
227
|
+
format 'text/html' do |obj|
|
228
|
+
obj.to_html
|
229
|
+
end
|
230
|
+
|
231
|
+
respond_to :to_latex
|
232
|
+
format 'text/latex' do |obj|
|
233
|
+
obj.to_latex
|
234
|
+
end
|
235
|
+
|
236
|
+
respond_to :to_javascript
|
237
|
+
format 'text/javascript' do |obj|
|
238
|
+
obj.to_javascript
|
239
|
+
end
|
240
|
+
|
241
|
+
respond_to :to_svg
|
242
|
+
format 'image/svg+xml' do |obj|
|
243
|
+
obj.render if defined?(Rubyvis) && Rubyvis::Mark === obj
|
244
|
+
obj.to_svg
|
80
245
|
end
|
81
|
-
s << "\\end{array}\\right)$$"
|
82
|
-
end
|
83
246
|
|
84
|
-
|
85
|
-
|
247
|
+
respond_to :to_iruby
|
248
|
+
format do |obj|
|
249
|
+
obj.to_iruby
|
250
|
+
end
|
251
|
+
|
252
|
+
match {|obj| obj.respond_to?(:path) && File.readable?(obj.path) }
|
253
|
+
format do |obj|
|
254
|
+
mime = MimeMagic.by_path(obj.path).to_s
|
255
|
+
[mime, File.read(obj.path)] if SUPPORTED_MIMES.include?(mime)
|
256
|
+
end
|
257
|
+
|
258
|
+
type { Object }
|
259
|
+
priority -1000
|
260
|
+
format 'text/plain' do |obj|
|
261
|
+
obj.inspect
|
262
|
+
end
|
86
263
|
end
|
87
264
|
end
|
88
265
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module IRuby
|
2
|
+
module LaTeX
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def vector(v)
|
6
|
+
x = 'c' * v.size
|
7
|
+
y = v.map(&:to_s).join(' & ')
|
8
|
+
"$$\\left(\\begin{array}{#{x}} #{y} \\end{array}\\right)$$"
|
9
|
+
end
|
10
|
+
|
11
|
+
def matrix(m, row_count, column_count)
|
12
|
+
s = "$$\\left(\\begin{array}{#{'c' * column_count}}\n"
|
13
|
+
(0...row_count).each do |i|
|
14
|
+
s << ' ' << m[i,0].to_s
|
15
|
+
(1...column_count).each do |j|
|
16
|
+
s << '&' << m[i,j].to_s
|
17
|
+
end
|
18
|
+
s << "\\\\\n"
|
19
|
+
end
|
20
|
+
s << "\\end{array}\\right)$$"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module HTML
|
25
|
+
extend self
|
26
|
+
|
27
|
+
def table(obj, options = {})
|
28
|
+
options[:maxrows] = 15 unless options.include?(:maxrows)
|
29
|
+
return obj unless Enumerable === obj
|
30
|
+
keys = nil
|
31
|
+
size = 0
|
32
|
+
rows = []
|
33
|
+
obj.each_with_index do |row, i|
|
34
|
+
row = row.flatten(1) if obj.respond_to?(:keys)
|
35
|
+
if row.respond_to?(:keys)
|
36
|
+
# Array of Hashes
|
37
|
+
keys ||= Set.new
|
38
|
+
keys.merge(row.keys)
|
39
|
+
elsif row.respond_to?(:map)
|
40
|
+
# Array of Arrays
|
41
|
+
size = row.size if size < row.size
|
42
|
+
end
|
43
|
+
if options[:maxrows] && i > options[:maxrows]
|
44
|
+
rows << '...'
|
45
|
+
break
|
46
|
+
end
|
47
|
+
rows << row
|
48
|
+
end
|
49
|
+
table = '<table>'
|
50
|
+
if keys
|
51
|
+
keys.merge(0...size)
|
52
|
+
table << '<tr>' << keys.map {|k| "<th>#{k}</th>"}.join << '</tr>'
|
53
|
+
else
|
54
|
+
keys = 0...size
|
55
|
+
end
|
56
|
+
rows.each do |row|
|
57
|
+
table << '<tr>'
|
58
|
+
if row.respond_to?(:map)
|
59
|
+
row = keys.map {|k| "<td>#{row[k] rescue nil}</td>" }
|
60
|
+
if row.empty?
|
61
|
+
table << "<td#{keys.size > 1 ? " colspan='#{keys.size}'" : ''}></td>"
|
62
|
+
else
|
63
|
+
table << row.join
|
64
|
+
end
|
65
|
+
else
|
66
|
+
table << "<td#{keys.size > 1 ? " colspan='#{keys.size}'" : ''}>#{row}</td>"
|
67
|
+
end
|
68
|
+
table << '</tr>'
|
69
|
+
end
|
70
|
+
table << '</table>'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/iruby/kernel.rb
CHANGED
@@ -68,7 +68,7 @@ module IRuby
|
|
68
68
|
|
69
69
|
def display(obj, options={})
|
70
70
|
unless obj.nil?
|
71
|
-
content = { data: Display.
|
71
|
+
content = { data: Display.display(obj, options), metadata: {}, execution_count: @execution_count }
|
72
72
|
@session.send(@pub_socket, 'pyout', content)
|
73
73
|
end
|
74
74
|
nil
|
data/lib/iruby/utils.rb
CHANGED
@@ -1,71 +1,33 @@
|
|
1
1
|
module IRuby
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
def initialize(mime, data)
|
6
|
-
super(data.to_s)
|
7
|
-
@mime = mime
|
8
|
-
end
|
9
|
-
|
10
|
-
def to_iruby
|
11
|
-
[@mime, self]
|
12
|
-
end
|
2
|
+
def self.convert(object, options)
|
3
|
+
Display.convert(object, options)
|
13
4
|
end
|
14
5
|
|
15
|
-
def self.display(obj, options={})
|
6
|
+
def self.display(obj, options = {})
|
16
7
|
Kernel.instance.display(obj, options)
|
17
8
|
end
|
18
9
|
|
19
|
-
def self.table(
|
20
|
-
|
21
|
-
keys = nil
|
22
|
-
size = 0
|
23
|
-
rows = []
|
24
|
-
obj.each do |row|
|
25
|
-
row = row.flatten(1) if obj.respond_to?(:keys)
|
26
|
-
if row.respond_to?(:keys)
|
27
|
-
# Array of Hashes
|
28
|
-
keys ||= Set.new
|
29
|
-
keys.merge(row.keys)
|
30
|
-
elsif row.respond_to?(:map)
|
31
|
-
# Array of Arrays
|
32
|
-
size = row.size if size < row.size
|
33
|
-
end
|
34
|
-
rows << row
|
35
|
-
end
|
36
|
-
table = '<table>'
|
37
|
-
if keys
|
38
|
-
keys.merge(0...size)
|
39
|
-
table << '<tr>' << keys.map {|k| "<th>#{k}</th>"}.join << '</tr>'
|
40
|
-
else
|
41
|
-
keys = 0...size
|
42
|
-
end
|
43
|
-
rows.each do |row|
|
44
|
-
table << '<tr>'
|
45
|
-
if row.respond_to?(:map)
|
46
|
-
row = keys.map {|k| "<td>#{row[k] rescue nil}</td>" }
|
47
|
-
if row.empty?
|
48
|
-
table << "<td#{keys.size > 1 ? " colspan='#{keys.size}'" : ''}></td>"
|
49
|
-
else
|
50
|
-
table << row.join
|
51
|
-
end
|
52
|
-
else
|
53
|
-
table << "<td#{keys.size > 1 ? " colspan='#{keys.size}'" : ''}>#{row}</td>"
|
54
|
-
end
|
55
|
-
table << '</tr>'
|
56
|
-
end
|
57
|
-
html(table << '</table>')
|
10
|
+
def self.table(s)
|
11
|
+
html(HTML.table(s))
|
58
12
|
end
|
59
13
|
|
60
14
|
def self.latex(s)
|
61
|
-
|
15
|
+
convert(s, mime: 'text/latex')
|
62
16
|
end
|
63
17
|
|
64
18
|
def self.math(s)
|
65
|
-
|
19
|
+
convert("$$#{s}$$", mime: 'text/latex')
|
66
20
|
end
|
67
21
|
|
68
22
|
def self.html(s)
|
69
|
-
|
23
|
+
convert(s, mime: 'text/html')
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.javascript(s)
|
27
|
+
convert(s, mime: 'application/javascript')
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.svg(s)
|
31
|
+
convert(s, mime: 'image/svg+xml')
|
70
32
|
end
|
71
33
|
end
|
data/lib/iruby/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Damián Silvani
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2014-
|
15
|
+
date: 2014-08-01 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: rake
|
@@ -106,6 +106,7 @@ files:
|
|
106
106
|
- lib/iruby/backend.rb
|
107
107
|
- lib/iruby/command.rb
|
108
108
|
- lib/iruby/display.rb
|
109
|
+
- lib/iruby/formatter.rb
|
109
110
|
- lib/iruby/kernel.rb
|
110
111
|
- lib/iruby/ostream.rb
|
111
112
|
- lib/iruby/session.rb
|