iruby 0.2.7 → 0.5.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.
- checksums.yaml +5 -5
- data/.github/workflows/ubuntu.yml +62 -0
- data/CHANGES +62 -0
- data/Gemfile +3 -1
- data/LICENSE +1 -1
- data/README.md +148 -27
- data/Rakefile +36 -10
- data/ci/Dockerfile.base.erb +41 -0
- data/ci/Dockerfile.main.erb +7 -0
- data/ci/requirements.txt +1 -0
- data/docker/setup.sh +15 -0
- data/docker/test.sh +7 -0
- data/iruby.gemspec +14 -18
- data/lib/iruby.rb +19 -3
- data/lib/iruby/backend.rb +22 -2
- data/lib/iruby/command.rb +76 -13
- data/lib/iruby/display.rb +69 -39
- data/lib/iruby/formatter.rb +5 -4
- data/lib/iruby/input.rb +41 -0
- data/lib/iruby/input/README.ipynb +502 -0
- data/lib/iruby/input/README.md +299 -0
- data/lib/iruby/input/autoload.rb +25 -0
- data/lib/iruby/input/builder.rb +67 -0
- data/lib/iruby/input/button.rb +47 -0
- data/lib/iruby/input/cancel.rb +32 -0
- data/lib/iruby/input/checkbox.rb +74 -0
- data/lib/iruby/input/date.rb +37 -0
- data/lib/iruby/input/field.rb +31 -0
- data/lib/iruby/input/file.rb +57 -0
- data/lib/iruby/input/form.rb +77 -0
- data/lib/iruby/input/label.rb +27 -0
- data/lib/iruby/input/multiple.rb +76 -0
- data/lib/iruby/input/popup.rb +41 -0
- data/lib/iruby/input/radio.rb +59 -0
- data/lib/iruby/input/select.rb +59 -0
- data/lib/iruby/input/textarea.rb +23 -0
- data/lib/iruby/input/widget.rb +34 -0
- data/lib/iruby/jupyter.rb +77 -0
- data/lib/iruby/kernel.rb +67 -22
- data/lib/iruby/ostream.rb +24 -8
- data/lib/iruby/session.rb +85 -67
- data/lib/iruby/session/cztop.rb +70 -0
- data/lib/iruby/session/ffi_rzmq.rb +87 -0
- data/lib/iruby/session/mixin.rb +47 -0
- data/lib/iruby/session_adapter.rb +66 -0
- data/lib/iruby/session_adapter/cztop_adapter.rb +45 -0
- data/lib/iruby/session_adapter/ffirzmq_adapter.rb +55 -0
- data/lib/iruby/session_adapter/pyzmq_adapter.rb +77 -0
- data/lib/iruby/utils.rb +5 -2
- data/lib/iruby/version.rb +1 -1
- data/run-test.sh +12 -0
- data/tasks/ci.rake +65 -0
- data/test/helper.rb +90 -0
- data/test/integration_test.rb +22 -11
- data/test/iruby/backend_test.rb +37 -0
- data/test/iruby/command_test.rb +207 -0
- data/test/iruby/jupyter_test.rb +27 -0
- data/test/iruby/mime_test.rb +32 -0
- data/test/iruby/multi_logger_test.rb +1 -2
- data/test/iruby/session_adapter/cztop_adapter_test.rb +20 -0
- data/test/iruby/session_adapter/ffirzmq_adapter_test.rb +20 -0
- data/test/iruby/session_adapter/session_adapter_test_base.rb +27 -0
- data/test/iruby/session_adapter_test.rb +91 -0
- data/test/iruby/session_test.rb +47 -0
- data/test/run-test.rb +18 -0
- metadata +130 -46
- data/.travis.yml +0 -16
- data/CONTRIBUTORS +0 -19
- data/test/test_helper.rb +0 -5
data/ci/requirements.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
jupyter-console>=6.0.0
|
data/docker/setup.sh
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
set -ex
|
4
|
+
|
5
|
+
apt-get update
|
6
|
+
apt-get install -y --no-install-recommends \
|
7
|
+
libczmq-dev \
|
8
|
+
python3 \
|
9
|
+
python3-pip \
|
10
|
+
python3-setuptools \
|
11
|
+
python3-wheel
|
12
|
+
|
13
|
+
cd /tmp/iruby
|
14
|
+
bundle install --with test --without plot
|
15
|
+
pip3 install jupyter
|
data/docker/test.sh
ADDED
data/iruby.gemspec
CHANGED
@@ -1,34 +1,30 @@
|
|
1
|
-
# coding: utf-8
|
2
1
|
require_relative 'lib/iruby/version'
|
3
|
-
require 'date'
|
4
2
|
|
5
3
|
Gem::Specification.new do |s|
|
6
4
|
s.name = 'iruby'
|
7
|
-
s.date = Date.today.to_s
|
8
5
|
s.version = IRuby::VERSION
|
9
6
|
s.authors = ['Daniel Mendler', 'The SciRuby developers']
|
10
7
|
s.email = ['mail@daniel-mendler.de']
|
11
|
-
s.summary = 'Ruby Kernel for Jupyter
|
12
|
-
s.description = 'A Ruby kernel for Jupyter
|
8
|
+
s.summary = 'Ruby Kernel for Jupyter'
|
9
|
+
s.description = 'A Ruby kernel for Jupyter environment. Try it at try.jupyter.org.'
|
13
10
|
s.homepage = 'https://github.com/SciRuby/iruby'
|
14
11
|
s.license = 'MIT'
|
15
12
|
|
16
|
-
s.files = `git ls-files`.split(
|
13
|
+
s.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
17
14
|
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
15
|
s.test_files = s.files.grep(%r{^test/})
|
19
|
-
s.require_paths = %w
|
16
|
+
s.require_paths = %w[lib]
|
20
17
|
|
21
|
-
|
22
|
-
File.read('Gemfile').scan(/gem\s+'(.*?)'/) { m << " * #{$1}\n" }
|
23
|
-
s.post_install_message = m << "\n"
|
18
|
+
s.required_ruby_version = '>= 2.3.0'
|
24
19
|
|
25
|
-
s.
|
20
|
+
s.add_dependency 'bond', '~> 0.5'
|
21
|
+
s.add_dependency 'data_uri', '~> 0.1'
|
22
|
+
s.add_dependency 'ffi-rzmq'
|
23
|
+
s.add_dependency 'mime-types', '>= 3.3.1'
|
24
|
+
s.add_dependency 'multi_json', '~> 1.11'
|
26
25
|
|
27
|
-
s.add_development_dependency '
|
28
|
-
s.add_development_dependency '
|
29
|
-
|
30
|
-
s.
|
31
|
-
s.add_runtime_dependency 'rbczmq', '~> 1.7'
|
32
|
-
s.add_runtime_dependency 'multi_json', '~> 1.11'
|
33
|
-
s.add_runtime_dependency 'mimemagic', '~> 0.3'
|
26
|
+
s.add_development_dependency 'pycall', '>= 1.2.1'
|
27
|
+
s.add_development_dependency 'rake'
|
28
|
+
s.add_development_dependency 'test-unit'
|
29
|
+
s.add_development_dependency 'test-unit-rr'
|
34
30
|
end
|
data/lib/iruby.rb
CHANGED
@@ -1,16 +1,32 @@
|
|
1
|
-
require '
|
2
|
-
require 'mimemagic'
|
1
|
+
require 'mime/types'
|
3
2
|
require 'multi_json'
|
4
3
|
require 'securerandom'
|
5
4
|
require 'openssl'
|
6
5
|
require 'tempfile'
|
7
6
|
require 'set'
|
7
|
+
|
8
8
|
require 'iruby/version'
|
9
|
+
require 'iruby/jupyter'
|
9
10
|
require 'iruby/kernel'
|
10
11
|
require 'iruby/backend'
|
11
|
-
require 'iruby/session'
|
12
12
|
require 'iruby/ostream'
|
13
|
+
require 'iruby/input'
|
13
14
|
require 'iruby/formatter'
|
14
15
|
require 'iruby/utils'
|
15
16
|
require 'iruby/display'
|
16
17
|
require 'iruby/comm'
|
18
|
+
|
19
|
+
if ENV.fetch('IRUBY_OLD_SESSION', false)
|
20
|
+
require 'iruby/session/mixin'
|
21
|
+
begin
|
22
|
+
require 'iruby/session/ffi_rzmq'
|
23
|
+
rescue LoadError
|
24
|
+
begin
|
25
|
+
require 'iruby/session/cztop'
|
26
|
+
rescue LoadError
|
27
|
+
STDERR.puts "Please install ffi-rzmq or cztop before running iruby. See README."
|
28
|
+
end
|
29
|
+
end
|
30
|
+
else
|
31
|
+
require 'iruby/session'
|
32
|
+
end
|
data/lib/iruby/backend.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module IRuby
|
2
2
|
In, Out = [nil], [nil]
|
3
|
-
::In, ::Out = In, Out
|
4
3
|
|
5
4
|
module History
|
6
5
|
def eval(code, store_history)
|
@@ -33,15 +32,17 @@ module IRuby
|
|
33
32
|
end
|
34
33
|
|
35
34
|
class PlainBackend
|
35
|
+
attr_reader :eval_path
|
36
36
|
prepend History
|
37
37
|
|
38
38
|
def initialize
|
39
39
|
require 'bond'
|
40
40
|
Bond.start(debug: true)
|
41
|
+
@eval_path = '(iruby)'
|
41
42
|
end
|
42
43
|
|
43
44
|
def eval(code, store_history)
|
44
|
-
TOPLEVEL_BINDING.eval(code)
|
45
|
+
TOPLEVEL_BINDING.eval(code, @eval_path, 1)
|
45
46
|
end
|
46
47
|
|
47
48
|
def complete(code)
|
@@ -50,22 +51,41 @@ module IRuby
|
|
50
51
|
end
|
51
52
|
|
52
53
|
class PryBackend
|
54
|
+
attr_reader :eval_path
|
53
55
|
prepend History
|
54
56
|
|
55
57
|
def initialize
|
56
58
|
require 'pry'
|
59
|
+
Pry.memory_size = 3
|
57
60
|
Pry.pager = false # Don't use the pager
|
58
61
|
Pry.print = proc {|output, value|} # No result printing
|
59
62
|
Pry.exception_handler = proc {|output, exception, _| }
|
63
|
+
@eval_path = Pry.eval_path
|
60
64
|
reset
|
61
65
|
end
|
62
66
|
|
63
67
|
def eval(code, store_history)
|
68
|
+
Pry.current_line = 1
|
64
69
|
@pry.last_result = nil
|
65
70
|
unless @pry.eval(code)
|
66
71
|
reset
|
67
72
|
raise SystemExit
|
68
73
|
end
|
74
|
+
|
75
|
+
# Pry::Code.complete_expression? return false
|
76
|
+
if !@pry.eval_string.empty?
|
77
|
+
syntax_error = @pry.eval_string
|
78
|
+
@pry.reset_eval_string
|
79
|
+
@pry.evaluate_ruby(syntax_error)
|
80
|
+
|
81
|
+
# Pry::Code.complete_expression? raise SyntaxError
|
82
|
+
# evaluate again for current line number
|
83
|
+
elsif @pry.last_result_is_exception? &&
|
84
|
+
@pry.last_exception.is_a?(SyntaxError) &&
|
85
|
+
@pry.last_exception.is_a?(Pry::UserError)
|
86
|
+
@pry.evaluate_ruby(code)
|
87
|
+
end
|
88
|
+
|
69
89
|
raise @pry.last_exception if @pry.last_result_is_exception?
|
70
90
|
@pry.push_initial_binding unless @pry.current_binding # ensure that we have a binding
|
71
91
|
@pry.last_result
|
data/lib/iruby/command.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'iruby/jupyter'
|
2
|
+
|
1
3
|
require 'fileutils'
|
2
4
|
require 'multi_json'
|
3
5
|
|
@@ -6,15 +8,18 @@ module IRuby
|
|
6
8
|
def initialize(args)
|
7
9
|
@args = args
|
8
10
|
|
9
|
-
ipython_dir =
|
10
|
-
@
|
11
|
-
|
12
|
-
end
|
13
|
-
@kernel_dir = File.join(File.expand_path(ipython_dir), 'kernels', 'ruby')
|
14
|
-
@kernel_file = File.join(@kernel_dir, 'kernel.json')
|
11
|
+
@ipython_dir = File.expand_path("~/.ipython")
|
12
|
+
@kernel_dir = resolve_kernelspec_dir.freeze
|
13
|
+
@kernel_file = File.join(@kernel_dir, 'kernel.json').freeze
|
15
14
|
@iruby_path = File.expand_path $0
|
16
15
|
end
|
17
16
|
|
17
|
+
attr_reader :ipython_dir, :kernel_dir, :kernel_file
|
18
|
+
|
19
|
+
def ipython_kernel_dir
|
20
|
+
File.join(File.expand_path(@ipython_dir), 'kernels', 'ruby')
|
21
|
+
end
|
22
|
+
|
18
23
|
def run
|
19
24
|
case @args.first
|
20
25
|
when 'version', '-v', '--version'
|
@@ -23,11 +28,12 @@ module IRuby
|
|
23
28
|
when 'help', '-h', '--help'
|
24
29
|
print_help
|
25
30
|
when 'register'
|
26
|
-
|
31
|
+
force_p = @args.include?('--force')
|
32
|
+
if registered_iruby_path && !force_p
|
27
33
|
STDERR.puts "#{@kernel_file} already exists!\nUse --force to force a register."
|
28
34
|
exit 1
|
29
35
|
end
|
30
|
-
register_kernel
|
36
|
+
register_kernel(force_p)
|
31
37
|
when 'unregister'
|
32
38
|
unregister_kernel
|
33
39
|
when 'kernel'
|
@@ -39,6 +45,38 @@ module IRuby
|
|
39
45
|
|
40
46
|
private
|
41
47
|
|
48
|
+
def resolve_kernelspec_dir
|
49
|
+
if ENV.has_key?('JUPYTER_DATA_DIR')
|
50
|
+
if ENV.has_key?('IPYTHONDIR')
|
51
|
+
warn 'both JUPYTER_DATA_DIR and IPYTHONDIR are supplied; IPYTHONDIR is ignored.'
|
52
|
+
end
|
53
|
+
if @args.find {|x| /\A--ipython-dir=/ =~ x }
|
54
|
+
warn 'both JUPYTER_DATA_DIR and --ipython-dir are supplied; --ipython-dir is ignored.'
|
55
|
+
end
|
56
|
+
jupyter_data_dir = ENV['JUPYTER_DATA_DIR']
|
57
|
+
return File.join(jupyter_data_dir, 'kernels', 'ruby')
|
58
|
+
end
|
59
|
+
|
60
|
+
if ENV.has_key?('IPYTHONDIR')
|
61
|
+
warn 'IPYTHONDIR is deprecated. Use JUPYTER_DATA_DIR instead.'
|
62
|
+
ipython_dir = ENV['IPYTHONDIR']
|
63
|
+
end
|
64
|
+
|
65
|
+
@args.each do |arg|
|
66
|
+
next unless /\A--ipython-dir=(.*)\Z/ =~ arg
|
67
|
+
ipython_dir = Regexp.last_match[1]
|
68
|
+
warn '--ipython-dir is deprecated. Use JUPYTER_DATA_DIR environment variable instead.'
|
69
|
+
break
|
70
|
+
end
|
71
|
+
|
72
|
+
if ipython_dir
|
73
|
+
@ipython_dir = ipython_dir
|
74
|
+
ipython_kernel_dir
|
75
|
+
else
|
76
|
+
File.join(Jupyter.kernelspec_dir, 'ruby')
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
42
80
|
def print_help
|
43
81
|
puts %{
|
44
82
|
Usage:
|
@@ -56,6 +94,8 @@ Try `ipython help` for more information.
|
|
56
94
|
def run_kernel
|
57
95
|
require 'iruby/logger'
|
58
96
|
IRuby.logger = MultiLogger.new(*Logger.new(STDOUT))
|
97
|
+
STDOUT.sync = true # FIXME: This can make the integration test.
|
98
|
+
|
59
99
|
@args.reject! {|arg| arg =~ /\A--log=(.*)\Z/ && IRuby.logger.loggers << Logger.new($1) }
|
60
100
|
IRuby.logger.level = @args.delete('--debug') ? Logger::DEBUG : Logger::INFO
|
61
101
|
|
@@ -64,7 +104,7 @@ Try `ipython help` for more information.
|
|
64
104
|
Dir.chdir(working_dir) if working_dir
|
65
105
|
|
66
106
|
require boot_file if boot_file
|
67
|
-
check_bundler {|e| IRuby.logger.warn "Could not load bundler: #{e.message}
|
107
|
+
check_bundler {|e| IRuby.logger.warn "Could not load bundler: #{e.message}" }
|
68
108
|
|
69
109
|
require 'iruby'
|
70
110
|
Kernel.new(config_file).run
|
@@ -95,7 +135,7 @@ Try `ipython help` for more information.
|
|
95
135
|
end
|
96
136
|
|
97
137
|
def check_registered_kernel
|
98
|
-
if kernel = registered_iruby_path
|
138
|
+
if (kernel = registered_iruby_path)
|
99
139
|
STDERR.puts "#{@iruby_path} differs from registered path #{registered_iruby_path}.
|
100
140
|
This might not work. Run 'iruby register --force' to fix it." if @iruby_path != kernel
|
101
141
|
else
|
@@ -106,20 +146,39 @@ This might not work. Run 'iruby register --force' to fix it." if @iruby_path !=
|
|
106
146
|
def check_bundler
|
107
147
|
require 'bundler'
|
108
148
|
raise %q{iruby is missing from Gemfile. This might not work.
|
109
|
-
Add `gem 'iruby'` to your Gemfile to fix it.} unless Bundler.definition.
|
149
|
+
Add `gem 'iruby'` to your Gemfile to fix it.} unless Bundler.definition.specs.any? {|s| s.name == 'iruby' }
|
110
150
|
Bundler.setup
|
111
151
|
rescue LoadError
|
112
152
|
rescue Exception => e
|
113
153
|
yield(e)
|
114
154
|
end
|
115
155
|
|
116
|
-
def register_kernel
|
156
|
+
def register_kernel(force_p=false)
|
157
|
+
if force_p
|
158
|
+
unregister_kernel_in_ipython_dir
|
159
|
+
else
|
160
|
+
return unless check_existing_kernel_in_ipython_dir
|
161
|
+
end
|
117
162
|
FileUtils.mkpath(@kernel_dir)
|
118
|
-
|
163
|
+
unless RUBY_PLATFORM =~ /mswin(?!ce)|mingw|cygwin/
|
164
|
+
File.write(@kernel_file, MultiJson.dump(argv: [ @iruby_path, 'kernel', '{connection_file}' ],
|
119
165
|
display_name: "Ruby #{RUBY_VERSION}", language: 'ruby'))
|
166
|
+
else
|
167
|
+
ruby_path, iruby_path = [RbConfig.ruby, @iruby_path].map{|path| path.gsub('/', '\\\\')}
|
168
|
+
File.write(@kernel_file, MultiJson.dump(argv: [ ruby_path, iruby_path, 'kernel', '{connection_file}' ],
|
169
|
+
display_name: "Ruby #{RUBY_VERSION}", language: 'ruby'))
|
170
|
+
end
|
171
|
+
|
120
172
|
FileUtils.copy(Dir[File.join(__dir__, 'assets', '*')], @kernel_dir) rescue nil
|
121
173
|
end
|
122
174
|
|
175
|
+
def check_existing_kernel_in_ipython_dir
|
176
|
+
return true unless File.file?(File.join(ipython_kernel_dir, 'kernel.json'))
|
177
|
+
warn "IRuby kernel file already exists in the deprecated IPython's data directory."
|
178
|
+
warn "Using --force, you can replace the old kernel file with the new one in Jupyter's data directory."
|
179
|
+
false
|
180
|
+
end
|
181
|
+
|
123
182
|
def registered_iruby_path
|
124
183
|
File.exist?(@kernel_file) && MultiJson.load(File.read(@kernel_file))['argv'].first
|
125
184
|
end
|
@@ -127,5 +186,9 @@ Add `gem 'iruby'` to your Gemfile to fix it.} unless Bundler.definition.dependen
|
|
127
186
|
def unregister_kernel
|
128
187
|
FileUtils.rm_rf(@kernel_dir)
|
129
188
|
end
|
189
|
+
|
190
|
+
def unregister_kernel_in_ipython_dir
|
191
|
+
FileUtils.rm_rf(ipython_kernel_dir)
|
192
|
+
end
|
130
193
|
end
|
131
194
|
end
|
data/lib/iruby/display.rb
CHANGED
@@ -11,7 +11,10 @@ module IRuby
|
|
11
11
|
obj = obj.object
|
12
12
|
|
13
13
|
fuzzy_mime = options[:format] # Treated like a fuzzy mime type
|
14
|
-
|
14
|
+
unless !fuzzy_mime || String === fuzzy_mime
|
15
|
+
raise 'Invalid argument :format'
|
16
|
+
end
|
17
|
+
|
15
18
|
if exact_mime = options[:mime]
|
16
19
|
raise 'Invalid argument :mime' unless String === exact_mime
|
17
20
|
raise 'Invalid mime type' unless exact_mime.include?('/')
|
@@ -27,28 +30,38 @@ module IRuby
|
|
27
30
|
|
28
31
|
# As a last resort, interpret string representation of the object
|
29
32
|
# as the given mime type.
|
30
|
-
|
33
|
+
if exact_mime && data.none? { |m, _| exact_mime == m }
|
34
|
+
data[exact_mime] = protect(exact_mime, obj)
|
35
|
+
end
|
31
36
|
|
32
37
|
data
|
33
38
|
end
|
34
39
|
|
40
|
+
def clear_output(wait = false)
|
41
|
+
IRuby::Kernel.instance.session.send(:publish, :clear_output, wait: wait)
|
42
|
+
end
|
43
|
+
|
35
44
|
private
|
36
45
|
|
37
46
|
def protect(mime, data)
|
38
|
-
|
47
|
+
MIME::Type.new(mime).ascii? ? data.to_s : [data.to_s].pack('m0')
|
39
48
|
end
|
40
49
|
|
41
50
|
def render(data, obj, exact_mime, fuzzy_mime)
|
42
51
|
# Filter matching renderer by object type
|
43
|
-
renderer = Registry.renderer.select {|r| r.match?(obj) }
|
52
|
+
renderer = Registry.renderer.select { |r| r.match?(obj) }
|
44
53
|
|
45
54
|
matching_renderer = nil
|
46
55
|
|
47
56
|
# Find exactly matching display by exact_mime
|
48
|
-
|
57
|
+
if exact_mime
|
58
|
+
matching_renderer = renderer.find { |r| exact_mime == r.mime }
|
59
|
+
end
|
49
60
|
|
50
61
|
# Find fuzzy matching display by fuzzy_mime
|
51
|
-
|
62
|
+
if fuzzy_mime
|
63
|
+
matching_renderer ||= renderer.find { |r| r.mime&.include?(fuzzy_mime) }
|
64
|
+
end
|
52
65
|
|
53
66
|
renderer.unshift matching_renderer if matching_renderer
|
54
67
|
|
@@ -69,7 +82,8 @@ module IRuby
|
|
69
82
|
attr_reader :object, :options
|
70
83
|
|
71
84
|
def initialize(object, options)
|
72
|
-
@object
|
85
|
+
@object = object
|
86
|
+
@options = options
|
73
87
|
end
|
74
88
|
|
75
89
|
class << self
|
@@ -87,10 +101,13 @@ module IRuby
|
|
87
101
|
end
|
88
102
|
|
89
103
|
class Renderer
|
90
|
-
attr_reader :match, :mime, :
|
104
|
+
attr_reader :match, :mime, :priority
|
91
105
|
|
92
106
|
def initialize(match, mime, render, priority)
|
93
|
-
@match
|
107
|
+
@match = match
|
108
|
+
@mime = mime
|
109
|
+
@render = render
|
110
|
+
@priority = priority
|
94
111
|
end
|
95
112
|
|
96
113
|
def match?(obj)
|
@@ -110,7 +127,7 @@ module IRuby
|
|
110
127
|
@renderer ||= []
|
111
128
|
end
|
112
129
|
|
113
|
-
SUPPORTED_MIMES = %w
|
130
|
+
SUPPORTED_MIMES = %w[
|
114
131
|
text/plain
|
115
132
|
text/html
|
116
133
|
text/latex
|
@@ -118,7 +135,8 @@ module IRuby
|
|
118
135
|
application/javascript
|
119
136
|
image/png
|
120
137
|
image/jpeg
|
121
|
-
image/svg+xml
|
138
|
+
image/svg+xml
|
139
|
+
]
|
122
140
|
|
123
141
|
def match(&block)
|
124
142
|
@match = block
|
@@ -127,7 +145,7 @@ module IRuby
|
|
127
145
|
end
|
128
146
|
|
129
147
|
def respond_to(name)
|
130
|
-
match {|obj| obj.respond_to?(name) }
|
148
|
+
match { |obj| obj.respond_to?(name) }
|
131
149
|
end
|
132
150
|
|
133
151
|
def type(&block)
|
@@ -149,7 +167,7 @@ module IRuby
|
|
149
167
|
|
150
168
|
def format(mime = nil, &block)
|
151
169
|
renderer << Renderer.new(@match, mime, block, @priority)
|
152
|
-
renderer.sort_by! {|r| -r.priority }
|
170
|
+
renderer.sort_by! { |r| -r.priority }
|
153
171
|
|
154
172
|
# Decrease priority implicitly for all formats
|
155
173
|
# which are added later for a type.
|
@@ -165,7 +183,19 @@ module IRuby
|
|
165
183
|
LaTeX.vector(obj.to_a)
|
166
184
|
end
|
167
185
|
|
186
|
+
type { Numo::NArray }
|
187
|
+
format 'text/plain', &:inspect
|
188
|
+
format 'text/latex' do |obj|
|
189
|
+
obj.ndim == 2 ?
|
190
|
+
LaTeX.matrix(obj, obj.shape[0], obj.shape[1]) :
|
191
|
+
LaTeX.vector(obj.to_a)
|
192
|
+
end
|
193
|
+
format 'text/html' do |obj|
|
194
|
+
HTML.table(obj.to_a)
|
195
|
+
end
|
196
|
+
|
168
197
|
type { NArray }
|
198
|
+
format 'text/plain', &:inspect
|
169
199
|
format 'text/latex' do |obj|
|
170
200
|
obj.dim == 2 ?
|
171
201
|
LaTeX.matrix(obj.transpose(1, 0), obj.shape[1], obj.shape[0]) :
|
@@ -227,37 +257,41 @@ module IRuby
|
|
227
257
|
|
228
258
|
match do |obj|
|
229
259
|
defined?(Magick::Image) && Magick::Image === obj ||
|
230
|
-
|
260
|
+
defined?(MiniMagick::Image) && MiniMagick::Image === obj
|
231
261
|
end
|
232
262
|
format 'image' do |obj|
|
233
263
|
format = obj.format || 'PNG'
|
234
|
-
[format == 'PNG' ? 'image/png' : 'image/jpeg', obj.to_blob {|i| i.format = format }]
|
264
|
+
[format == 'PNG' ? 'image/png' : 'image/jpeg', obj.to_blob { |i| i.format = format }]
|
235
265
|
end
|
236
266
|
|
237
|
-
|
238
|
-
|
239
|
-
obj.to_blob
|
267
|
+
match do |obj|
|
268
|
+
defined?(Vips::Image) && Vips::Image === obj
|
240
269
|
end
|
270
|
+
format do |obj|
|
271
|
+
# handles Vips::Error, vips_image_get: field "vips-loader" not found
|
272
|
+
loader = obj.get('vips-loader') rescue nil
|
273
|
+
if loader == 'jpegload'
|
274
|
+
['image/jpeg', obj.write_to_buffer('.jpg')]
|
275
|
+
else
|
276
|
+
# falls back to png for other/unknown types
|
277
|
+
['image/png', obj.write_to_buffer('.png')]
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
type { Gruff::Base }
|
282
|
+
format 'image/png', &:to_blob
|
241
283
|
|
242
284
|
respond_to :to_html
|
243
|
-
format 'text/html'
|
244
|
-
obj.to_html
|
245
|
-
end
|
285
|
+
format 'text/html', &:to_html
|
246
286
|
|
247
287
|
respond_to :to_latex
|
248
|
-
format 'text/latex'
|
249
|
-
obj.to_latex
|
250
|
-
end
|
288
|
+
format 'text/latex', &:to_latex
|
251
289
|
|
252
290
|
respond_to :to_tex
|
253
|
-
format 'text/latex'
|
254
|
-
obj.to_tex
|
255
|
-
end
|
291
|
+
format 'text/latex', &:to_tex
|
256
292
|
|
257
293
|
respond_to :to_javascript
|
258
|
-
format 'text/javascript'
|
259
|
-
obj.to_javascript
|
260
|
-
end
|
294
|
+
format 'text/javascript', &:to_javascript
|
261
295
|
|
262
296
|
respond_to :to_svg
|
263
297
|
format 'image/svg+xml' do |obj|
|
@@ -266,21 +300,17 @@ module IRuby
|
|
266
300
|
end
|
267
301
|
|
268
302
|
respond_to :to_iruby
|
269
|
-
format
|
270
|
-
obj.to_iruby
|
271
|
-
end
|
303
|
+
format(&:to_iruby)
|
272
304
|
|
273
|
-
match {|obj| obj.respond_to?(:path) && File.readable?(obj.path) }
|
305
|
+
match { |obj| obj.respond_to?(:path) && obj.method(:path).arity == 0 && File.readable?(obj.path) }
|
274
306
|
format do |obj|
|
275
|
-
mime =
|
307
|
+
mime = MIME::Types.of(obj.path).first.to_s
|
276
308
|
[mime, File.read(obj.path)] if SUPPORTED_MIMES.include?(mime)
|
277
309
|
end
|
278
310
|
|
279
311
|
type { Object }
|
280
|
-
priority
|
281
|
-
format 'text/plain'
|
282
|
-
obj.inspect
|
283
|
-
end
|
312
|
+
priority(-1000)
|
313
|
+
format 'text/plain', &:inspect
|
284
314
|
end
|
285
315
|
end
|
286
316
|
end
|