mork 0.15.0 → 0.16.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 +4 -4
- data/lib/mork/grid.rb +1 -1
- data/lib/mork/magicko.rb +7 -2
- data/lib/mork/npatch.rb +6 -6
- data/lib/mork/sheet_pdf.rb +1 -1
- data/lib/mork/version.rb +1 -1
- data/mork.code-workspace +24 -0
- data/mork.gemspec +2 -2
- data/spec/mork/npatch_spec.rb +11 -11
- data/spec/mork/sheet_omr_spec.rb +147 -1
- data/spec/samples/cost/cost3.jpg +0 -0
- data/spec/samples/cost/layout.yml +58 -0
- data/spec/samples/info.yml +16 -0
- metadata +10 -12
- data/mork.sublime-project +0 -9
- data/mork.sublime-workspace +0 -5292
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e8f49c72fbe2291aa94e5d4c01555faa89f62fb0d1e5d188afb4352a32e202a0
|
|
4
|
+
data.tar.gz: 6500951d34d59c8c4d2c15b2a42a32b253811e08a469315b880cbb1d42282a55
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 99e1f1dda6522ed67b19f07eb3dd619fda3edfb6439d0ec754b72b8871066aabc23a65dc8977928632929730db4a4eb0cf98a29157d817f106e3fa76426ab118
|
|
7
|
+
data.tar.gz: 18f2350a49975b3682bc4ac334388a58b66c8cd624f4ec3722a71623932e8cdefa86bf283e084b9a2cab2195f52e43c0012b74429a3e4bdf4fa1fe30fa893c9f
|
data/lib/mork/grid.rb
CHANGED
|
@@ -10,7 +10,7 @@ module Mork
|
|
|
10
10
|
# Calling Grid.new without arguments creates the default boilerplate Grid
|
|
11
11
|
def initialize(options=nil)
|
|
12
12
|
@params = default_grid
|
|
13
|
-
if File.
|
|
13
|
+
if File.exist?('layout.yml')
|
|
14
14
|
@params.deeper_merge! symbolize YAML.load_file('layout.yml')
|
|
15
15
|
end
|
|
16
16
|
case options
|
data/lib/mork/magicko.rb
CHANGED
|
@@ -145,8 +145,13 @@ module Mork
|
|
|
145
145
|
# into an array of bytes
|
|
146
146
|
def read_bytes(params=nil)
|
|
147
147
|
d = @density ? "-density #{@density}" : nil
|
|
148
|
-
|
|
149
|
-
|
|
148
|
+
cmd = "magick -depth 8 #{d} #{@path} #{params} gray:-"
|
|
149
|
+
stdout, stderr, status = Open3.capture3(cmd)
|
|
150
|
+
if status.success?
|
|
151
|
+
stdout.unpack('C*')
|
|
152
|
+
else
|
|
153
|
+
fail IOError, "ImageMagick command failed: #{stderr}"
|
|
154
|
+
end
|
|
150
155
|
end
|
|
151
156
|
|
|
152
157
|
# perspective points: brings the found registration area centers to the
|
data/lib/mork/npatch.rb
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
require 'narray'
|
|
1
|
+
require 'numo/narray'
|
|
2
2
|
|
|
3
3
|
module Mork
|
|
4
4
|
# @private
|
|
5
|
-
# NPatch handles low-level computations on pixels by leveraging NArray
|
|
5
|
+
# NPatch handles low-level computations on pixels by leveraging Numo::NArray
|
|
6
6
|
class NPatch
|
|
7
7
|
# NPatch.new(source, width, height) constructs an NPatch object
|
|
8
8
|
# from the `source` linear array of bytes, to be reshaped as a
|
|
9
9
|
# `width` by `height` matrix
|
|
10
10
|
def initialize(source, width, height)
|
|
11
|
-
|
|
12
|
-
@patch
|
|
11
|
+
# Numo::NArray uses row-major order, so we reshape and transpose
|
|
12
|
+
@patch = Numo::SFloat.cast(source).reshape(height, width).transpose
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def average(coord)
|
|
@@ -21,8 +21,8 @@ module Mork
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def centroid
|
|
24
|
-
xp = @patch.sum(1).to_a
|
|
25
|
-
yp = @patch.sum(0).to_a
|
|
24
|
+
xp = @patch.sum(axis: 1).to_a
|
|
25
|
+
yp = @patch.sum(axis: 0).to_a
|
|
26
26
|
return xp.find_index(xp.min), yp.find_index(yp.min), @patch.stddev
|
|
27
27
|
end
|
|
28
28
|
end
|
data/lib/mork/sheet_pdf.rb
CHANGED
data/lib/mork/version.rb
CHANGED
data/mork.code-workspace
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"folders": [
|
|
3
|
+
{
|
|
4
|
+
"path": "."
|
|
5
|
+
}
|
|
6
|
+
],
|
|
7
|
+
"settings": {
|
|
8
|
+
"sqltools.connections": [
|
|
9
|
+
{
|
|
10
|
+
"mysqlOptions": {
|
|
11
|
+
"authProtocol": "default"
|
|
12
|
+
},
|
|
13
|
+
"previewLimit": 50,
|
|
14
|
+
"server": "localhost",
|
|
15
|
+
"port": 3306,
|
|
16
|
+
"driver": "MySQL",
|
|
17
|
+
"name": "HGuide",
|
|
18
|
+
"database": "hguide_development",
|
|
19
|
+
"username": "root",
|
|
20
|
+
"password": ""
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
}
|
data/mork.gemspec
CHANGED
|
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
|
|
|
11
11
|
s.homepage = 'https://github.com/giuseb/mork'
|
|
12
12
|
s.summary = %q{Optical mark recognition of multiple-choice tests and surveys}
|
|
13
13
|
s.description = %q{Optical mark recognition of multiple-choice tests and surveys. Low-level ruby library to generate response sheets in PDF form and to automatically score manually filled-out forms.}
|
|
14
|
-
s.required_ruby_version = '>=
|
|
14
|
+
s.required_ruby_version = '>= 3.4.0'
|
|
15
15
|
|
|
16
16
|
s.files = `git ls-files`.split("\n")
|
|
17
17
|
s.test_files = `git ls-files -- {spec}/*`.split("\n")
|
|
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
|
|
|
19
19
|
s.require_paths = ["lib"]
|
|
20
20
|
|
|
21
21
|
# dependencies:
|
|
22
|
-
s.add_dependency 'narray' ,
|
|
22
|
+
s.add_dependency 'numo-narray' , '~> 0.9'
|
|
23
23
|
s.add_dependency 'mini_magick' , '~> 4.10'
|
|
24
24
|
s.add_dependency 'prawn' , '~> 2.2'
|
|
25
25
|
s.add_dependency 'deep_merge' , '~> 1.2'
|
data/spec/mork/npatch_spec.rb
CHANGED
|
@@ -5,20 +5,20 @@ module Mork
|
|
|
5
5
|
describe '#centroid' do
|
|
6
6
|
it 'computes centers for rm0X' do
|
|
7
7
|
np = make 'spec/samples/rm01.jpeg', 134, 104
|
|
8
|
-
expect(np.centroid[0]).to
|
|
9
|
-
expect(np.centroid[1]).to
|
|
8
|
+
expect(np.centroid[0]).to be_within(1).of(50)
|
|
9
|
+
expect(np.centroid[1]).to be_within(1).of(60)
|
|
10
10
|
np = make 'spec/samples/rm02.jpeg', 114, 117
|
|
11
|
-
expect(np.centroid[0]).to
|
|
12
|
-
expect(np.centroid[1]).to
|
|
11
|
+
expect(np.centroid[0]).to be_within(1).of(69)
|
|
12
|
+
expect(np.centroid[1]).to be_within(1).of(71)
|
|
13
13
|
np = make 'spec/samples/rm03.jpeg', 124, 105
|
|
14
|
-
expect(np.centroid[0]).to
|
|
15
|
-
expect(np.centroid[1]).to
|
|
14
|
+
expect(np.centroid[0]).to be_within(1).of(71)
|
|
15
|
+
expect(np.centroid[1]).to be_within(1).of(61)
|
|
16
16
|
np = make 'spec/samples/rm04.jpeg', 144, 117
|
|
17
|
-
expect(np.centroid[0]).to
|
|
18
|
-
expect(np.centroid[1]).to
|
|
17
|
+
expect(np.centroid[0]).to be_within(1).of(84)
|
|
18
|
+
expect(np.centroid[1]).to be_within(1).of(52)
|
|
19
19
|
np = make 'spec/samples/rm05.jpeg', 144, 117
|
|
20
|
-
expect(np.centroid[0]).to
|
|
21
|
-
expect(np.centroid[1]).to
|
|
20
|
+
expect(np.centroid[0]).to be_within(1).of(84)
|
|
21
|
+
expect(np.centroid[1]).to be_within(1).of(52)
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
@@ -37,7 +37,7 @@ module Mork
|
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def make(fname, w, h)
|
|
40
|
-
b = IO.read("|
|
|
40
|
+
b = IO.read("|magick #{fname} gray:-").unpack 'C*'
|
|
41
41
|
NPatch.new b, w, h
|
|
42
42
|
end
|
|
43
43
|
|
data/spec/mork/sheet_omr_spec.rb
CHANGED
|
@@ -13,7 +13,7 @@ module Mork
|
|
|
13
13
|
describe 'trying to process a corrupted file' do
|
|
14
14
|
it 'throws an IO error' do
|
|
15
15
|
fn = sample_img('corrupted-pdf').image_path
|
|
16
|
-
expect { SheetOMR.new fn}.to raise_error(IOError, '
|
|
16
|
+
expect { SheetOMR.new fn}.to raise_error(IOError, 'Unknown problem with image file')
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
end
|
|
@@ -163,6 +163,152 @@ module Mork
|
|
|
163
163
|
end
|
|
164
164
|
end
|
|
165
165
|
|
|
166
|
+
context 'using Cost3' do
|
|
167
|
+
let(:img) { sample_img 'cost3' }
|
|
168
|
+
let(:fn) { File.basename(img.image_path) }
|
|
169
|
+
let(:omr) { SheetOMR.new img.image_path, layout: img.grid_path }
|
|
170
|
+
|
|
171
|
+
context 'object creation' do
|
|
172
|
+
describe '#new' do
|
|
173
|
+
it 'creates a SheetOMR object' do
|
|
174
|
+
expect(omr).to be_a SheetOMR
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
it 'registers the image correctly' do
|
|
178
|
+
expect(omr.valid?).to be_truthy
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
context 'querying and modifying the object' do
|
|
183
|
+
describe '#status' do
|
|
184
|
+
it 'returns the valid (:ok) registration status for each corner' do
|
|
185
|
+
expect(omr.status).to eq({ tl: :ok, tr: :ok, br: :ok, bl: :ok })
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
describe '#set_choices' do
|
|
190
|
+
it 'returns true if all goes well' do
|
|
191
|
+
expect(omr.set_choices([10])).to be_truthy
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
it 'raises an Argument error if the choices argument is invalid' do
|
|
195
|
+
expect { omr.set_choices('a string').to raise_error ArgumentError }
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
context 'analyzing the barcode' do
|
|
201
|
+
describe '#barcode' do
|
|
202
|
+
it 'returns the integer form of the barcode' do
|
|
203
|
+
expect(omr.barcode).to eq img.barcode_int
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
describe '#barcode_string' do
|
|
208
|
+
it 'returns the binary string version of the barcode' do
|
|
209
|
+
expect(omr.barcode_string).to eq img.barcode_str
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
context 'analyzing response cells' do
|
|
215
|
+
describe '#marked?' do
|
|
216
|
+
it 'returns true if the given cell was marked, false otherwise' do
|
|
217
|
+
expect(omr.marked? 0, 0).to be_truthy
|
|
218
|
+
expect(omr.marked? 0, 1).to be_falsy
|
|
219
|
+
expect(omr.marked? 99, 2).to be_truthy
|
|
220
|
+
expect(omr.marked? 99, 3).to be_falsy
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
describe '#marked_choices' do
|
|
225
|
+
it 'returns an array of marked choices as position indexes' do
|
|
226
|
+
omr.set_choices [5] * 100
|
|
227
|
+
expect(omr.marked_choices ).to eq [[0],[1],[1],[3],[3],[1],[0],[4],[0],[4],[1],[0],[0],[3],[4],[0],[0],[4],[2],[1],[2],[3],[1],[1],[3],[0],[1],[0],[1],[0],[3],[4],[4],[2],[2],[0],[2],[1],[2],[0],[4],[3],[3],[0],[4],[1],[4],[0],[1],[1],[2],[3],[0],[1],[4],[2],[0],[0],[2],[4],[4],[4],[1],[0],[3],[4],[2],[1],[1],[4],[0],[0],[3],[1],[1],[1],[4],[0],[1],[3],[0],[4],[1],[3],[4],[4],[0],[1],[1],[0],[1],[4],[1],[4],[3],[3],[0],[4],[4],[2]]
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
it 'returns marked choices only for existing choice cells' do
|
|
231
|
+
omr.set_choices [5, 4, 3, 2, 1]
|
|
232
|
+
expect(omr.marked_choices).to eq [[0], [1], [1], [], []]
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
describe '#marked_letters' do
|
|
237
|
+
it 'returns an array of characters for the marked choices' do
|
|
238
|
+
omr.set_choices [5] * 100
|
|
239
|
+
charr = img.mark_chars.split('').map { |c| [c] }
|
|
240
|
+
expect(omr.marked_letters).to eq charr
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
context 'creating overlays and saving resulting JPEGs' do
|
|
246
|
+
it 'highlights registration' do
|
|
247
|
+
omr.save_registration "spec/out/CG-registration.jpeg"
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
it 'highlights the barcode' do
|
|
251
|
+
omr.overlay :highlight, :barcode
|
|
252
|
+
omr.save "spec/out/CG-highlight-barcode.jpeg"
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
it 'highlights all requested choice cells' do
|
|
256
|
+
omr.set_choices [5] * 32
|
|
257
|
+
omr.overlay :highlight, :all
|
|
258
|
+
omr.save "spec/out/CG-highlight-all.jpeg"
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
it 'highlights all possible choice cells' do
|
|
262
|
+
omr.set_choices [5] * 30 # this will be ignored
|
|
263
|
+
omr.overlay :highlight, :max
|
|
264
|
+
omr.save "spec/out/CG-highlight-max.jpeg"
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
it 'highlights marked cells' do
|
|
268
|
+
omr.overlay :highlight, :marked
|
|
269
|
+
omr.save "spec/out/CG-highlight-marked.jpeg"
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
it 'highlights marked cells (as default overlay)' do
|
|
273
|
+
omr.overlay :highlight
|
|
274
|
+
omr.save "spec/out/CG-highlight-marked-def.jpeg"
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
it 'highlights arbitrary cells' do
|
|
278
|
+
omr.overlay :highlight, [[1,2], [], [0,1,2,3,4], [3]]
|
|
279
|
+
omr.save "spec/out/CG-highlight-some.jpeg"
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
it 'highlights and crosses marked cells' do
|
|
283
|
+
omr.overlay :highlight
|
|
284
|
+
omr.overlay :check
|
|
285
|
+
omr.save "spec/out/CG-highlight-and-cross.jpeg"
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
it 'checks marked cells' do
|
|
289
|
+
omr.overlay :check
|
|
290
|
+
omr.save "spec/out/CG-check-marked.jpeg"
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
it 'outlines marked cells' do
|
|
294
|
+
omr.overlay :outline
|
|
295
|
+
omr.save "spec/out/CG-outline-marked.jpeg"
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
context 'requesting invalid responses and choices' do
|
|
300
|
+
it 'raises an ArgumentError if the maximum number of responses is exceeded' do
|
|
301
|
+
one_too_many = [[0]] * 121
|
|
302
|
+
expect { omr.overlay(:check, one_too_many)}.to raise_error(ArgumentError)
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
it 'raises an ArgumentError if the maximum number of choices is exceeded' do
|
|
306
|
+
one_too_many = [[5]]
|
|
307
|
+
expect { omr.overlay(:check, one_too_many)}.to raise_error(ArgumentError)
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
|
|
166
312
|
context 'systematic tests' do
|
|
167
313
|
let(:bila) { 'CCEBEBCEEACCDCABDBEBCADEADDCCCACCACDBBDAECDDABDEEBCEEDCBAAADEEEEDCADEABCBDECCCCDDDCABBECAADADBBEEABA'.split '' }
|
|
168
314
|
let(:bila0) { SheetOMR.new 'spec/samples/syst/bila0.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
|
Binary file
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
page_size:
|
|
2
|
+
width: 210
|
|
3
|
+
height: 297
|
|
4
|
+
reg_marks:
|
|
5
|
+
margin: 10
|
|
6
|
+
radius: 3
|
|
7
|
+
crop: 20
|
|
8
|
+
offset: 3
|
|
9
|
+
blur: 2
|
|
10
|
+
dilate: 5
|
|
11
|
+
header:
|
|
12
|
+
name:
|
|
13
|
+
top: 5
|
|
14
|
+
left: 15
|
|
15
|
+
width: 160
|
|
16
|
+
height: 7
|
|
17
|
+
size: 14
|
|
18
|
+
title:
|
|
19
|
+
top: 15
|
|
20
|
+
left: 15
|
|
21
|
+
width: 160
|
|
22
|
+
height: 12
|
|
23
|
+
size: 12
|
|
24
|
+
code:
|
|
25
|
+
top: 35
|
|
26
|
+
left: 130
|
|
27
|
+
width: 57
|
|
28
|
+
height: 10
|
|
29
|
+
size: 14
|
|
30
|
+
align: right
|
|
31
|
+
signature:
|
|
32
|
+
top: 30
|
|
33
|
+
left: 15
|
|
34
|
+
width: 120
|
|
35
|
+
height: 15
|
|
36
|
+
size: 7
|
|
37
|
+
box: true
|
|
38
|
+
items:
|
|
39
|
+
# threshold: 0.75
|
|
40
|
+
top: 55
|
|
41
|
+
left: 11
|
|
42
|
+
columns: 4
|
|
43
|
+
column_width: 44
|
|
44
|
+
rows: 30
|
|
45
|
+
x_spacing: 7
|
|
46
|
+
y_spacing: 7
|
|
47
|
+
cell_width: 6
|
|
48
|
+
cell_height: 5
|
|
49
|
+
max_cells: 5
|
|
50
|
+
font_size: 9
|
|
51
|
+
number_width: 8
|
|
52
|
+
number_margin: 2
|
|
53
|
+
barcode:
|
|
54
|
+
bits: 40
|
|
55
|
+
left: 15
|
|
56
|
+
width: 3
|
|
57
|
+
height: 2.5
|
|
58
|
+
spacing: 4
|
data/spec/samples/info.yml
CHANGED
|
@@ -14,6 +14,22 @@ jdoe1:
|
|
|
14
14
|
br: [1178, 1704]
|
|
15
15
|
bl: [55, 1702]
|
|
16
16
|
|
|
17
|
+
cost3:
|
|
18
|
+
image_path: spec/samples/cost/cost3.jpg
|
|
19
|
+
grid_path: spec/samples/cost/layout.yml
|
|
20
|
+
nchoices: 5
|
|
21
|
+
nitems: 100
|
|
22
|
+
barcode_int: 11886
|
|
23
|
+
barcode_str: '00000000000000000000000010111001101110'
|
|
24
|
+
width: 1240
|
|
25
|
+
height: 1754
|
|
26
|
+
mark_array: [[0],[1],[1],[3],[3],[1],[0],[4],[0],[4],[1],[0],[0],[3],[4],[0],[0],[4],[2],[1],[2],[3],[1],[1],[3],[0],[1],[0],[1],[0],[3],[4],[4],[2],[2],[0],[2],[1],[2],[0],[4],[3],[3],[0],[4],[1],[4],[0],[1],[1],[2],[3],[0],[1],[4],[2],[0],[0],[2],[4],[4],[4],[1],[0],[3],[4],[2],[1],[1],[4],[0],[0],[3],[1],[1],[1],[4],[0],[1],[3],[0],[4],[1],[3],[4],[4],[0],[1],[1],[0],[1],[4],[1],[4],[3],[3],[0],[4],[4],[2]]
|
|
27
|
+
mark_chars: 'ABBDDBAEAEBAADEAAECBCDBBDABABADEECCACBCAEDDAEBEABBCDABECAACEEEBADECBBEAADBBBEABDAEBDEEABBABEBEDDAEEC'
|
|
28
|
+
tl: [63, 67]
|
|
29
|
+
tr: [1182, 68]
|
|
30
|
+
br: [1178, 1704]
|
|
31
|
+
bl: [55, 1702]
|
|
32
|
+
|
|
17
33
|
reg-mark:
|
|
18
34
|
image_path: spec/samples/reg_mark.jpg
|
|
19
35
|
centroid-x: 92
|
metadata
CHANGED
|
@@ -1,29 +1,28 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mork
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.16.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Giuseppe Bertini
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name: narray
|
|
13
|
+
name: numo-narray
|
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
|
16
15
|
requirements:
|
|
17
16
|
- - "~>"
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '0.
|
|
18
|
+
version: '0.9'
|
|
20
19
|
type: :runtime
|
|
21
20
|
prerelease: false
|
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
22
|
requirements:
|
|
24
23
|
- - "~>"
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '0.
|
|
25
|
+
version: '0.9'
|
|
27
26
|
- !ruby/object:Gem::Dependency
|
|
28
27
|
name: mini_magick
|
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -194,9 +193,8 @@ files:
|
|
|
194
193
|
- lib/mork/sheet_omr.rb
|
|
195
194
|
- lib/mork/sheet_pdf.rb
|
|
196
195
|
- lib/mork/version.rb
|
|
196
|
+
- mork.code-workspace
|
|
197
197
|
- mork.gemspec
|
|
198
|
-
- mork.sublime-project
|
|
199
|
-
- mork.sublime-workspace
|
|
200
198
|
- spec/mork/coord_spec.rb
|
|
201
199
|
- spec/mork/grid_omr_spec.rb
|
|
202
200
|
- spec/mork/grid_spec.rb
|
|
@@ -213,6 +211,8 @@ files:
|
|
|
213
211
|
- spec/samples/boxy.yml
|
|
214
212
|
- spec/samples/content.yml
|
|
215
213
|
- spec/samples/corrupt.pdf
|
|
214
|
+
- spec/samples/cost/cost3.jpg
|
|
215
|
+
- spec/samples/cost/layout.yml
|
|
216
216
|
- spec/samples/grid.yml
|
|
217
217
|
- spec/samples/grid160.yml
|
|
218
218
|
- spec/samples/grid_omr_layout.yml
|
|
@@ -269,7 +269,6 @@ homepage: https://github.com/giuseb/mork
|
|
|
269
269
|
licenses:
|
|
270
270
|
- MIT
|
|
271
271
|
metadata: {}
|
|
272
|
-
post_install_message:
|
|
273
272
|
rdoc_options: []
|
|
274
273
|
require_paths:
|
|
275
274
|
- lib
|
|
@@ -277,15 +276,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
277
276
|
requirements:
|
|
278
277
|
- - ">="
|
|
279
278
|
- !ruby/object:Gem::Version
|
|
280
|
-
version:
|
|
279
|
+
version: 3.4.0
|
|
281
280
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
282
281
|
requirements:
|
|
283
282
|
- - ">="
|
|
284
283
|
- !ruby/object:Gem::Version
|
|
285
284
|
version: '0'
|
|
286
285
|
requirements: []
|
|
287
|
-
rubygems_version: 3.
|
|
288
|
-
signing_key:
|
|
286
|
+
rubygems_version: 3.7.2
|
|
289
287
|
specification_version: 4
|
|
290
288
|
summary: Optical mark recognition of multiple-choice tests and surveys
|
|
291
289
|
test_files: []
|