iruby 0.5.0 → 0.7.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1576475a17c04bbdc5080fede4710cf609c9cfb1268f692e8a11653095c2902b
4
- data.tar.gz: 46c737c267739a44dc2a7a9d4ccd5c8d3fcf89fda1b4163e74d941bd0740ec44
3
+ metadata.gz: 97c4aaa733ee27b0adb838ebed8d38cd67f857ef2466aa055105943df8647845
4
+ data.tar.gz: be54a5310326f5e052f07a2bb0625acb823618ab9b0a85dc0dedae01a86ebbc9
5
5
  SHA512:
6
- metadata.gz: 0225f7c54c11dc9668d6bbceff3dac9ba6e1d32e041355ab429b7f6b0bc204f8050f3420dfede65474614c259e7dba346db051f5414be5fb1fd2dffd9b5de894
7
- data.tar.gz: 803cbe952a48614e1d7aeefef51f772c4420aeb07bf63a679384147fe12f10469380d733834126d206342a2c6a01d7d57d6202b8d64bd90921cd3825684d22c3
6
+ metadata.gz: 19cb3579f143fa0b720bb1fddc1e50b17b910ba2484bd794e9d382e6b3d029675d8bda801f77b19a26afae69a9038f9779a8f50a93d4ae51dadfde53dd3168f0
7
+ data.tar.gz: 2f1adf37fb436345d110c87352bad3725ffba0068740c13e16bcd3f4be7132a9a8968bcecda43c257613d4ccd08ab7592c9bae27d60501ac393c54a0f86519cd
@@ -1,8 +1,14 @@
1
1
  name: CI
2
2
 
3
3
  on:
4
- - push
5
- - pull_request
4
+ push:
5
+ branches:
6
+ - master
7
+ pull_request:
8
+ types:
9
+ - opened
10
+ - synchronize
11
+ - reopened
6
12
 
7
13
  jobs:
8
14
  test:
@@ -35,6 +41,7 @@ jobs:
35
41
 
36
42
  - name: Install requirements on ubuntu
37
43
  run: |
44
+ sudo apt update
38
45
  sudo apt install -y --no-install-recommends \
39
46
  libczmq-dev \
40
47
  python3 \
data/CHANGES.md ADDED
@@ -0,0 +1,226 @@
1
+ # 0.7.2 (2021-06-23)
2
+
3
+ ## Bug Fixes
4
+
5
+ * Fix IRuby.table for Ruby >= 2.7 https://github.com/SciRuby/iruby/pull/305 (@topofocus)
6
+ * Fix PlainBackend to include modules https://github.com/SciRuby/iruby/issues/303 (@UliKuch, @mrkn)
7
+
8
+ # 0.7.1 (2021-06-21)
9
+
10
+ ## Enhancements
11
+
12
+ * Add support of `to_iruby_mimebundle` format method https://github.com/SciRuby/iruby/pull/304 (@mrkn)
13
+
14
+ ## Bug Fixes
15
+
16
+ * Prevent unintentional display the result of Session#send (@mrkn)
17
+ * Update display formatter for Gruff::Base to prevent warning (@mrkn)
18
+
19
+ # 0.7.0 (2021-05-28)
20
+
21
+ ## Enhancements
22
+
23
+ * The default backend is changed to IRB (@mrkn)
24
+ * Add IRuby::Kernel#switch_backend! method (@mrkn)
25
+
26
+ ## Bug Fixes
27
+
28
+ * Fix the handling of image/svg+xml https://github.com/SciRuby/iruby/pull/300, https://github.com/SciRuby/iruby/pull/301 (@kojix2)
29
+
30
+ # 0.6.1 (2021-05-26)
31
+
32
+ ## Bug Fixes
33
+
34
+ * Follow the messages and hooks orders during execute_request processing (@mrkn)
35
+
36
+ # 0.6.0 (2021-05-25)
37
+
38
+ ## Bug Fixes
39
+
40
+ * Fix the handling of application/javascript https://github.com/SciRuby/iruby/issues/292, https://github.com/SciRuby/iruby/pull/294 (@kylekyle, @mrkn)
41
+
42
+ ## Enhancements
43
+
44
+ * Add the `initialized` event in `IRuby::Kernel` class https://github.com/SciRuby/iruby/pull/168, https://github.com/SciRuby/iruby/pull/296 (@Yuki-Inoue, @mrkn)
45
+ * Add the following four events https://github.com/SciRuby/iruby/pull/295 (@mrkn):
46
+ * `pre-execute` -- occurs before every code execution
47
+ * `pre-run-cell` -- occurs before every non-silent code execution
48
+ * `post-execute` -- occurs after every code execution
49
+ * `post-run-cell` -- occurs after every non-silent code execution
50
+ * Replace Bond with IRB in PlainBackend https://github.com/SciRuby/iruby/pull/276, https://github.com/SciRuby/iruby/pull/297 (@cfis, @mrkn)
51
+
52
+ # 0.5.0 (2021-03-25)
53
+
54
+ ## Bug Fixes
55
+
56
+ * Fix Jupyter console crashes issue https://github.com/SciRuby/iruby/pull/210 (@kojix2)
57
+ * Fix syntax highlighting issue on Jpyter Lab https://github.com/SciRuby/iruby/issues/224 (@kojix2)
58
+ * Fix interoperability issue with ruby-git https://github.com/SciRuby/iruby/pull/139 (@habemus-papadum)
59
+ * Fix the issue of `$stderr.write` that cannot handle multiple arguments https://github.com/SciRuby/iruby/issues/206 (@kojix2)
60
+ * Remove a buggy `inspect_request` implementation https://github.com/SciRuby/iruby/pull/119 (@LunarLanding)
61
+ * Fix uninitialized constant `Fiddle` caused in initialization phase https://github.com/SciRuby/iruby/issues/264 (@MatthewSteen, @kjoix2)
62
+ * Fix the issue on displaying a table https://github.com/SciRuby/iruby/pull/281 (@ankane)
63
+
64
+ ## Enhancements
65
+
66
+ * Add `IRuby.clear_output` method https://github.com/SciRuby/iruby/pull/220 (@kojix2)
67
+ * Make backtrace on exception simplify and more appropriate for code in a cell https://github.com/SciRuby/iruby/pull/249 (@zheng-yongping)
68
+ * Make syntax error message more appropriate https://github.com/SciRuby/iruby/pull/251 (@zheng-yongping)
69
+ * Remove top-level `In` and `Out` constants https://github.com/SciRuby/iruby/pull/229 (@kojix2)
70
+ * Use text/plain for the default format of `Numo::NArray` objects https://github.com/SciRuby/iruby/pull/255 (@kojix2)
71
+ * Use ffi-rzmq as the default ZeroMQ adapter https://github.com/SciRuby/iruby/pull/256 (@kojix2)
72
+ * Drop rbczmq support https://github.com/SciRuby/iruby/pull/260 (@rstammer)
73
+ * Add ruby-vips image support https://github.com/SciRuby/iruby/pull/279 (@ankane)
74
+ * Replace mimemagic with mime-types https://github.com/SciRuby/iruby/pull/291 (@mrkn)
75
+
76
+ # 0.4.0 (2019-07-31)
77
+
78
+ (TBD)
79
+
80
+ # 0.3 (2017-03-26)
81
+
82
+ ## Bug Fixes
83
+
84
+ * Disable Jupyter keyboard manager for all popups made using IRuby.popup (@kylekyle).
85
+ * Fix Iruby/Input date values bug that set date fields to whatever the last date value was (@kylekyle).
86
+ * Fix a bug where time strings put into prompter would give an 'out of range' error (@kylekyle).
87
+
88
+ ## Enhancements
89
+
90
+ * Improvements to IRuby dependency detection using `Bundler::Dependencies#specs` (@kou).
91
+ * Use less memory forcing pry to store only the last 3 commands in memory (@kylekyle).
92
+ * Use bigger z-index that is used accross all browsers (@kylekyle).
93
+ * Ability to input date values as DateTime objects in IRuby/Input (@kylekyle).
94
+ * Add option to have check boxes checked by default (@kylekyle).
95
+ * Option for multi-select in drop down menus in the prompter (@kylekyle).
96
+ * Add support for multiple widgets using `IRuby::Input::Multiple` (@kylekyle).
97
+ * Calender icon for date selector icon (@kylekyle).
98
+ * Add support for Numo/NArray (@zalt50).
99
+ * Text now only completes after a space (@zalt50).
100
+ * Remove the DONTWAIT flag when receiving a message (@cloud-oak).
101
+ * Add support for CZTop (@kou).
102
+
103
+ # 0.2.9 (2016-05-02)
104
+
105
+ ## Bug Fixes
106
+
107
+ * Fix an error where a NoMethodError was being raised where a table rendered using an Array of Hashes has more than `maxcols` columns. (@CGamesPlay)
108
+ * Patch PryBackend to throw unterminated string and unexpected end-of-file syntax errors (@kylekyle)
109
+
110
+ ## Enhnacements
111
+
112
+ * Add an IRuby::Input class which provides widgets for getting inputs from users. (@kylekyle)
113
+ * Add data_uri dependency (@kylekyle)
114
+ * Added a clear_output display function (@mrkn)
115
+ * Doc fixes for installation (@kozo2, @generall)
116
+
117
+ # 0.2.8 (2015-12-06)
118
+
119
+ * Add compatibility with ffi-rzmq
120
+ * Windows support
121
+
122
+ # 0.2.7 (2015-07-02)
123
+
124
+ * Fix problem with autoloaded constants in Display, problem with sciruby gem
125
+
126
+ # 0.2.6 (2015-06-21)
127
+
128
+ * Check registered kernel and Gemfile to prevent gem loading problems
129
+ * Support to_tex method for the rendering
130
+
131
+ # 0.2.5 (2015-06-07)
132
+
133
+ * Fix #29, empty signatures
134
+ * Move iruby utils to IRuby::Utils module
135
+ * Add IRuby.tex alias for IRuby.latex
136
+ * Remove example notebooks from gem
137
+
138
+ # 0.2.4 (2015-06-02)
139
+
140
+ * Better exception handling
141
+ * Fix ctrl-C issue #17
142
+ * Fix timeout issue #19
143
+
144
+ # 0.2.3 (2015-05-31)
145
+
146
+ * Fix notebook indentation
147
+ * Fix tab completion for multiple lines
148
+
149
+ # 0.2.2 (2015-05-26)
150
+
151
+ * Support history variables In, Out, _, _i etc
152
+ * Internal refactoring and minor bugfixes
153
+
154
+ # 0.2.1 (2015-05-26)
155
+
156
+ * Copy Ruby logo to kernel specification
157
+
158
+ # 0.2.0 (2015-05-25)
159
+
160
+ * Dropped IPython2 support
161
+ * Dropped Ruby < 2.0.0 support
162
+ * Supports and requires now IPython3/Jupyter
163
+ * Switch from ffi-rzmq to rbczmq
164
+ * Added IRuby::Conn (experimental, to be used by widgets)
165
+ * iruby register/unregister commands to register IRuby kernel in Jupyter
166
+
167
+ # 0.1.13 (2014-08-19)
168
+
169
+ * Improved IRuby.table, supports :maxrows and :maxcols
170
+ * IRuby#javascript workaround (https://github.com/ipython/ipython/issues/6259)
171
+
172
+ # 0.1.12 (2014-08-01)
173
+
174
+ * IRuby#table add option maxrows
175
+ * powerful display system with format and datatype registry, see #25
176
+ * Add IRuby#javascript
177
+ * Add IRuby#svg
178
+
179
+ # 0.1.11 (2014-07-08)
180
+
181
+ * Push binding if pry binding stack is empty
182
+
183
+ # 0.1.10 (2014-07-08)
184
+
185
+ * Fix #19 (pp)
186
+ * Handle exception when symlink cannot be created
187
+ * Fix dependencies and Pry backend
188
+
189
+ # 0.1.9 (2014-02-28)
190
+
191
+ * Check IPython version
192
+
193
+ # 0.1.7/0.1.8
194
+
195
+ * Bugfixes #11, #12, #13
196
+
197
+ # 0.1.6 (2013-10-11)
198
+
199
+ * Print Matrix and GSL::Matrix as LaTeX
200
+ * Add check for Pry version
201
+
202
+ # 0.1.5 (2013-10-03)
203
+
204
+ * Implement a rich display system
205
+ * Fix error output
206
+
207
+ # 0.1.4 (2013-10-03)
208
+
209
+ * Extract display handler from kernel
210
+ * Always return a text/plain response
211
+
212
+ # 0.1.3 (2013-10-03)
213
+
214
+ * Implement missing request handlers
215
+ * Detect if Bundler is running and set kernel_cmd appropriately
216
+ * Improve Pry integration
217
+ * Add support for the gems gnuplot, gruff, rmagick and mini_magick
218
+
219
+ # 0.1.2 (2013-10-02)
220
+
221
+ * Support for Pry added
222
+ * Launch `iruby console` if plain `iruby` is started
223
+
224
+ # 0.1.0 (2013-10-02)
225
+
226
+ * Cleanup and rewrite of some parts
data/README.md CHANGED
@@ -31,8 +31,8 @@ If both ffi-rzmq and cztop are installed, ffi-rzmq is used. If you prefer cztop,
31
31
  export IRUBY_SESSION_ADAPTER="cztop"
32
32
  ```
33
33
 
34
- * We recommend the [Pry](https://github.com/pry/pry) backend for full functionality.
35
- * If you want to install the latest version of IRuby from the source code, try [specific_install](https://github.com/rdp/specific_install).
34
+ * [Pry][Pry], if you want to use [Pry][Pry] instead of IRB for the code execution backend
35
+ * If you want to install the development version of IRuby from the source code, try [specific_install](https://github.com/rdp/specific_install).
36
36
 
37
37
  ```
38
38
  gem specific_install https://github.com/SciRuby/iruby
@@ -148,6 +148,19 @@ If you have already used IRuby with a different version, you need to generate a
148
148
  $ iruby register --force
149
149
  ```
150
150
 
151
+ ## Backends
152
+
153
+ There are two backends: PlainBackend and PryBackend.
154
+
155
+ * PlainBackend is the default backend. It uses [IRB](https://github.com/ruby/irb).
156
+ * PryBackend uses [Pry][Pry].
157
+
158
+ You can switch the backend to PryBackend by running the code below.
159
+
160
+ ```ruby
161
+ IRuby::Kernel.instance.switch_backend!(:pry)
162
+ ```
163
+
151
164
  ## Notebooks
152
165
 
153
166
  Take a look at the [example notebook](http://nbviewer.ipython.org/urls/raw.github.com/SciRuby/sciruby-notebooks/master/getting_started.ipynb)
@@ -167,3 +180,5 @@ In February 2021, [IRuby became the canonical repository](https://github.com/Sci
167
180
  Copyright (c) IRuby contributors and the Ruby Science Foundation.
168
181
 
169
182
  Licensed under the [MIT](LICENSE) license.
183
+
184
+ [Pry]: https://github.com/pry/pry
data/iruby.gemspec CHANGED
@@ -17,9 +17,9 @@ Gem::Specification.new do |s|
17
17
 
18
18
  s.required_ruby_version = '>= 2.3.0'
19
19
 
20
- s.add_dependency 'bond', '~> 0.5'
21
20
  s.add_dependency 'data_uri', '~> 0.1'
22
21
  s.add_dependency 'ffi-rzmq'
22
+ s.add_dependency 'irb'
23
23
  s.add_dependency 'mime-types', '>= 3.3.1'
24
24
  s.add_dependency 'multi_json', '~> 1.11'
25
25
 
data/lib/iruby.rb CHANGED
@@ -1,12 +1,16 @@
1
+ require 'fileutils'
1
2
  require 'mime/types'
2
3
  require 'multi_json'
3
4
  require 'securerandom'
4
5
  require 'openssl'
5
6
  require 'tempfile'
6
7
  require 'set'
8
+ require 'stringio'
7
9
 
8
10
  require 'iruby/version'
9
11
  require 'iruby/jupyter'
12
+ require 'iruby/event_manager'
13
+ require 'iruby/logger'
10
14
  require 'iruby/kernel'
11
15
  require 'iruby/backend'
12
16
  require 'iruby/ostream'
data/lib/iruby/backend.rb CHANGED
@@ -3,7 +3,7 @@ module IRuby
3
3
 
4
4
  module History
5
5
  def eval(code, store_history)
6
- b = TOPLEVEL_BINDING
6
+ b = eval_binding
7
7
 
8
8
  b.local_variable_set(:_ih, In) unless b.local_variable_defined?(:_ih)
9
9
  b.local_variable_set(:_oh, Out) unless b.local_variable_defined?(:_oh)
@@ -36,17 +36,38 @@ module IRuby
36
36
  prepend History
37
37
 
38
38
  def initialize
39
- require 'bond'
40
- Bond.start(debug: true)
41
- @eval_path = '(iruby)'
39
+ require 'irb'
40
+ require 'irb/completion'
41
+ IRB.setup(nil)
42
+ @main = TOPLEVEL_BINDING.eval("self").dup
43
+ init_main_object(@main)
44
+ @workspace = IRB::WorkSpace.new(@main)
45
+ @irb = IRB::Irb.new(@workspace)
46
+ @eval_path = @irb.context.irb_path
47
+ IRB.conf[:MAIN_CONTEXT] = @irb.context
48
+ end
49
+
50
+ def eval_binding
51
+ @workspace.binding
42
52
  end
43
53
 
44
54
  def eval(code, store_history)
45
- TOPLEVEL_BINDING.eval(code, @eval_path, 1)
55
+ @irb.context.evaluate(code, 0)
56
+ @irb.context.last_value
46
57
  end
47
58
 
48
59
  def complete(code)
49
- Bond.agent.call(code, code)
60
+ IRB::InputCompletor::CompletionProc.call(code)
61
+ end
62
+
63
+ private
64
+
65
+ def init_main_object(main)
66
+ wrapper_module = Module.new
67
+ main.extend(wrapper_module)
68
+ main.define_singleton_method(:include) do |*args|
69
+ wrapper_module.include(*args)
70
+ end
50
71
  end
51
72
  end
52
73
 
@@ -64,6 +85,10 @@ module IRuby
64
85
  reset
65
86
  end
66
87
 
88
+ def eval_binding
89
+ TOPLEVEL_BINDING
90
+ end
91
+
67
92
  def eval(code, store_history)
68
93
  Pry.current_line = 1
69
94
  @pry.last_result = nil
@@ -96,7 +121,7 @@ module IRuby
96
121
  end
97
122
 
98
123
  def reset
99
- @pry = Pry.new(output: $stdout, target: TOPLEVEL_BINDING)
124
+ @pry = Pry.new(output: $stdout, target: eval_binding)
100
125
  end
101
126
  end
102
127
  end
data/lib/iruby/command.rb CHANGED
@@ -1,7 +1,4 @@
1
- require 'iruby/jupyter'
2
-
3
- require 'fileutils'
4
- require 'multi_json'
1
+ require 'iruby'
5
2
 
6
3
  module IRuby
7
4
  class Command
@@ -92,7 +89,6 @@ Try `ipython help` for more information.
92
89
  end
93
90
 
94
91
  def run_kernel
95
- require 'iruby/logger'
96
92
  IRuby.logger = MultiLogger.new(*Logger.new(STDOUT))
97
93
  STDOUT.sync = true # FIXME: This can make the integration test.
98
94
 
@@ -131,7 +127,7 @@ Try `ipython help` for more information.
131
127
  check_registered_kernel
132
128
  check_bundler {|e| STDERR.puts "Could not load bundler: #{e.message}" }
133
129
 
134
- Kernel.exec('ipython', *@args)
130
+ Process.exec('ipython', *@args)
135
131
  end
136
132
 
137
133
  def check_registered_kernel
data/lib/iruby/display.rb CHANGED
@@ -1,10 +1,30 @@
1
+ require "set"
2
+
1
3
  module IRuby
2
4
  module Display
5
+ DEFAULT_MIME_TYPE_FORMAT_METHODS = {
6
+ "text/html" => :to_html,
7
+ "text/markdown" => :to_markdown,
8
+ "image/svg+xml" => :to_svg,
9
+ "image/png" => :to_png,
10
+ "appliation/pdf" => :to_pdf,
11
+ "image/jpeg" => :to_jpeg,
12
+ "text/latex" => [:to_latex, :to_tex],
13
+ # NOTE: Do not include the entry of "application/json" because
14
+ # all objects can respond to `to_json` due to json library
15
+ # "application/json" => :to_json,
16
+ "application/javascript" => :to_javascript,
17
+ nil => :to_iruby,
18
+ "text/plain" => :inspect
19
+ }.freeze
20
+
3
21
  class << self
22
+ # @private
4
23
  def convert(obj, options)
5
24
  Representation.new(obj, options)
6
25
  end
7
26
 
27
+ # @private
8
28
  def display(obj, options = {})
9
29
  obj = convert(obj, options)
10
30
  options = obj.options
@@ -20,23 +40,48 @@ module IRuby
20
40
  raise 'Invalid mime type' unless exact_mime.include?('/')
21
41
  end
22
42
 
23
- data = {}
24
-
25
- # Render additional representation
26
- render(data, obj, exact_mime, fuzzy_mime)
27
-
28
- # IPython always requires a text representation
29
- render(data, obj, 'text/plain', nil) unless data['text/plain']
43
+ data = render_mimebundle(obj, exact_mime, fuzzy_mime)
44
+
45
+ # Render by additional formatters
46
+ render_by_registry(data, obj, exact_mime, fuzzy_mime)
47
+
48
+ # Render by to_xxx methods
49
+ DEFAULT_MIME_TYPE_FORMAT_METHODS.each do |mime, methods|
50
+ next if mime.nil? && !data.empty? # for to_iruby
51
+
52
+ next if mime && data.key?(mime) # do not overwrite
53
+
54
+ method = Array(methods).find {|m| obj.respond_to?(m) }
55
+ next if method.nil?
56
+
57
+ result = obj.send(method)
58
+ case mime
59
+ when nil # to_iruby
60
+ case result
61
+ when nil
62
+ # do nothing
63
+ next
64
+ when Array
65
+ mime, result = result
66
+ else
67
+ warn(("Ignore the result of to_iruby method of %p because " +
68
+ "it does not return a pair of mime-type and formatted representation") % obj)
69
+ next
70
+ end
71
+ end
72
+ data[mime] = result
73
+ end
30
74
 
31
75
  # As a last resort, interpret string representation of the object
32
76
  # as the given mime type.
33
- if exact_mime && data.none? { |m, _| exact_mime == m }
77
+ if exact_mime && !data.key?(exact_mime)
34
78
  data[exact_mime] = protect(exact_mime, obj)
35
79
  end
36
80
 
37
81
  data
38
82
  end
39
83
 
84
+ # @private
40
85
  def clear_output(wait = false)
41
86
  IRuby::Kernel.instance.session.send(:publish, :clear_output, wait: wait)
42
87
  end
@@ -44,10 +89,39 @@ module IRuby
44
89
  private
45
90
 
46
91
  def protect(mime, data)
47
- MIME::Type.new(mime).ascii? ? data.to_s : [data.to_s].pack('m0')
92
+ ascii?(mime) ? data.to_s : [data.to_s].pack('m0')
48
93
  end
49
94
 
50
- def render(data, obj, exact_mime, fuzzy_mime)
95
+ # Each of the following mime types must be a text type,
96
+ # but mime-types library tells us it is a non-text type.
97
+ FORCE_TEXT_TYPES = Set[
98
+ "application/javascript",
99
+ "image/svg+xml"
100
+ ].freeze
101
+
102
+ def ascii?(mime)
103
+ if FORCE_TEXT_TYPES.include?(mime)
104
+ true
105
+ else
106
+ MIME::Type.new(mime).ascii?
107
+ end
108
+ end
109
+
110
+ private def render_mimebundle(obj, exact_mime, fuzzy_mime)
111
+ data = {}
112
+ if obj.respond_to?(:to_iruby_mimebundle)
113
+ include_mime = [exact_mime].compact
114
+ formats, metadata = obj.to_iruby_mimebundle(include: include_mime)
115
+ formats.each do |mime, value|
116
+ if fuzzy_mime.nil? || mime.include?(fuzzy_mime)
117
+ data[mime] = value
118
+ end
119
+ end
120
+ end
121
+ data
122
+ end
123
+
124
+ private def render_by_registry(data, obj, exact_mime, fuzzy_mime)
51
125
  # Filter matching renderer by object type
52
126
  renderer = Registry.renderer.select { |r| r.match?(obj) }
53
127
 
@@ -68,6 +142,8 @@ module IRuby
68
142
  # Return first render result which has the right mime type
69
143
  renderer.each do |r|
70
144
  mime, result = r.render(obj)
145
+ next if data.key?(mime)
146
+
71
147
  if mime && result && (!exact_mime || exact_mime == mime) && (!fuzzy_mime || mime.include?(fuzzy_mime))
72
148
  data[mime] = protect(mime, result)
73
149
  break
@@ -78,6 +154,19 @@ module IRuby
78
154
  end
79
155
  end
80
156
 
157
+ private def render_by_to_iruby(data, obj)
158
+ if obj.respond_to?(:to_iruby)
159
+ result = obj.to_iruby
160
+ mime, rep = case result
161
+ when Array
162
+ result
163
+ else
164
+ [nil, result]
165
+ end
166
+ data[mime] = rep
167
+ end
168
+ end
169
+
81
170
  class Representation
82
171
  attr_reader :object, :options
83
172
 
@@ -100,6 +189,60 @@ module IRuby
100
189
  end
101
190
  end
102
191
 
192
+ class FormatMatcher
193
+ def initialize(&block)
194
+ @block = block
195
+ end
196
+
197
+ def call(obj)
198
+ @block.(obj)
199
+ end
200
+
201
+ def inspect
202
+ "#{self.class.name}[%p]" % @block
203
+ end
204
+ end
205
+
206
+ class RespondToFormatMatcher < FormatMatcher
207
+ def initialize(name)
208
+ super() {|obj| obj.respond_to?(name) }
209
+ @name = name
210
+ end
211
+
212
+ attr_reader :name
213
+
214
+ def inspect
215
+ "#{self.class.name}[respond_to?(%p)]" % name
216
+ end
217
+ end
218
+
219
+ class TypeFormatMatcher < FormatMatcher
220
+ def initialize(class_block)
221
+ super() do |obj|
222
+ begin
223
+ self.klass === obj
224
+ # We have to rescue all exceptions since constant autoloading could fail with a different error
225
+ rescue Exception
226
+ false
227
+ end
228
+ end
229
+ @class_block = class_block
230
+ end
231
+
232
+ def klass
233
+ @class_block.()
234
+ end
235
+
236
+ def inspect
237
+ klass = begin
238
+ @class_block.()
239
+ rescue Exception
240
+ @class_block
241
+ end
242
+ "#{self.class.name}[%p]" % klass
243
+ end
244
+ end
245
+
103
246
  class Renderer
104
247
  attr_reader :match, :mime, :priority
105
248
 
@@ -127,37 +270,22 @@ module IRuby
127
270
  @renderer ||= []
128
271
  end
129
272
 
130
- SUPPORTED_MIMES = %w[
131
- text/plain
132
- text/html
133
- text/latex
134
- application/json
135
- application/javascript
136
- image/png
137
- image/jpeg
138
- image/svg+xml
139
- ]
140
-
141
273
  def match(&block)
142
- @match = block
274
+ @match = FormatMatcher.new(&block)
143
275
  priority 0
144
276
  nil
145
277
  end
146
278
 
147
279
  def respond_to(name)
148
- match { |obj| obj.respond_to?(name) }
280
+ @match = RespondToFormatMatcher.new(name)
281
+ priority 0
282
+ nil
149
283
  end
150
284
 
151
285
  def type(&block)
152
- match do |obj|
153
- begin
154
- block.call === obj
155
- # We have to rescue all exceptions since constant autoloading could fail with a different error
156
- rescue Exception
157
- rescue #NameError
158
- false
159
- end
160
- end
286
+ @match = TypeFormatMatcher.new(block)
287
+ priority 0
288
+ nil
161
289
  end
162
290
 
163
291
  def priority(p)
@@ -255,13 +383,24 @@ module IRuby
255
383
  end
256
384
  end
257
385
 
386
+ format_magick_image = ->(obj) do
387
+ format = obj.format || 'PNG'
388
+ [
389
+ format == 'PNG' ? 'image/png' : 'image/jpeg',
390
+ obj.to_blob {|i| i.format = format }
391
+ ]
392
+ end
393
+
258
394
  match do |obj|
259
395
  defined?(Magick::Image) && Magick::Image === obj ||
260
396
  defined?(MiniMagick::Image) && MiniMagick::Image === obj
261
397
  end
398
+ format 'image', &format_magick_image
399
+
400
+ type { Gruff::Base }
262
401
  format 'image' do |obj|
263
- format = obj.format || 'PNG'
264
- [format == 'PNG' ? 'image/png' : 'image/jpeg', obj.to_blob { |i| i.format = format }]
402
+ image = obj.to_image
403
+ format_magick_image.(obj.to_image)
265
404
  end
266
405
 
267
406
  match do |obj|
@@ -278,39 +417,19 @@ module IRuby
278
417
  end
279
418
  end
280
419
 
281
- type { Gruff::Base }
282
- format 'image/png', &:to_blob
283
-
284
- respond_to :to_html
285
- format 'text/html', &:to_html
286
-
287
- respond_to :to_latex
288
- format 'text/latex', &:to_latex
289
-
290
- respond_to :to_tex
291
- format 'text/latex', &:to_tex
292
-
293
- respond_to :to_javascript
294
- format 'text/javascript', &:to_javascript
295
-
296
- respond_to :to_svg
420
+ type { Rubyvis::Mark }
297
421
  format 'image/svg+xml' do |obj|
298
- obj.render if defined?(Rubyvis) && Rubyvis::Mark === obj
422
+ obj.render
299
423
  obj.to_svg
300
424
  end
301
425
 
302
- respond_to :to_iruby
303
- format(&:to_iruby)
304
-
305
426
  match { |obj| obj.respond_to?(:path) && obj.method(:path).arity == 0 && File.readable?(obj.path) }
306
427
  format do |obj|
307
428
  mime = MIME::Types.of(obj.path).first.to_s
308
- [mime, File.read(obj.path)] if SUPPORTED_MIMES.include?(mime)
429
+ if mime && DEFAULT_MIME_TYPE_FORMAT_METHODS.key?(mime)
430
+ [mime, File.read(obj.path)]
431
+ end
309
432
  end
310
-
311
- type { Object }
312
- priority(-1000)
313
- format 'text/plain', &:inspect
314
433
  end
315
434
  end
316
435
  end