mork 0.11.2 → 0.12.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9d0ebacb869817da04d196475aa4d6f10d77c12b
4
- data.tar.gz: dae81bb4231fa70a5dcd82d1197ab6de28ca5fa9
3
+ metadata.gz: b30b33a147b248a73592bcea2dd9ff4d7952a4fb
4
+ data.tar.gz: e85ca2b34c0b579ec8bf7a3885331ac9ef74c62b
5
5
  SHA512:
6
- metadata.gz: 7d89b369b98ad6691e0e731391e75e03370c4dd181fdbef7f2e16ffc6c8994654b4388ea98b4e180deeef206c2a552def7690e54fb4e00db1c3411b3b38aa756
7
- data.tar.gz: 7cee35519e306d92b2e320d9cbada5d529089992842b3d17b0cfa41399211cdd5f19a7f78fbf1af9bfe991f5ffbb0898d37134eb2d85aa887ef1dfae012e435a
6
+ metadata.gz: 0649c313f2db3af8d358c03787c0c773c4962cd40ea245758b1bfcb40bec331568c05523371410e81dc4e845ab370d42028331bb685241538856c4875c213e57
7
+ data.tar.gz: 283fe8d57acd7451bca93920e1049218c1b6574c2944e5c8711dd43a2dbc25a096d802bf2929bcd91719c86efbfb44fe603043e1af60ac33a6375e9be54c2efa
@@ -65,14 +65,6 @@ module Mork
65
65
  private
66
66
  #====================#
67
67
 
68
- # recursively turn hash keys into symbols. pasted from
69
- # http://stackoverflow.com/questions/800122/best-way-to-convert-strings-to-symbols-in-hash
70
- # def symbolize(obj)
71
- # return obj.inject({}){|memo,(k,v)| memo[k.to_sym] = symbolize(v); memo} if obj.is_a? Hash
72
- # return obj.inject([]){|memo,v | memo << symbolize(v); memo} if obj.is_a? Array
73
- # return obj
74
- # end
75
-
76
68
  # cell_y(q)
77
69
  #
78
70
  # the distance from the registration frame to the top edge
@@ -129,5 +121,12 @@ module Mork
129
121
  def page_height() @params[:page_size][:height].to_f end
130
122
  def reg_margin() @params[:reg_marks][:margin].to_f end
131
123
  def reg_radius() @params[:reg_marks][:radius].to_f end
124
+ def uid_digits() @params[:uid][:digits].to_i end
125
+ def uid_x() @params[:uid][:left].to_f end
126
+ def uid_y() @params[:uid][:top].to_f end
127
+ def uid_width() @params[:uid][:width].to_f end
128
+ def uid_height() @params[:uid][:height].to_f end
129
+ def uid_cell_width() @params[:uid][:cell_width].to_f end
130
+ def uid_cell_height() @params[:uid][:cell_height].to_f end
132
131
  end
133
132
  end
@@ -55,6 +55,17 @@ module Mork
55
55
  width: 3,
56
56
  height: 3,
57
57
  spacing: 4
58
+ },
59
+ # student's unique id
60
+ uid: {
61
+ digits: 6,
62
+ left: 150,
63
+ top: 30,
64
+ width: 50,
65
+ height: 40,
66
+ cell_width: 4,
67
+ cell_height: 3,
68
+ box: true
58
69
  }
59
70
  }
60
71
  end
@@ -26,8 +26,18 @@ module Mork
26
26
  # ===========================================
27
27
  # = Returning Coord sets for area locations =
28
28
  # ===========================================
29
+ def choice_cell_areas
30
+ @choice_cell_areas ||= begin
31
+ max_questions.times.map do |q|
32
+ max_choices_per_question.times.map do |c|
33
+ coord cell_x(q,c), cell_y(q), cell_width, cell_height
34
+ end
35
+ end
36
+ end
37
+ end
38
+
29
39
  def choice_cell_area(q, c)
30
- coord cell_x(q,c), cell_y(q), cell_width, cell_height
40
+ choice_cell_areas[q][c]
31
41
  end
32
42
 
33
43
  def calibration_cell_areas
@@ -78,52 +88,3 @@ module Mork
78
88
  end
79
89
  end
80
90
  end
81
-
82
- # # the 4 values needed to locate a single registration mark
83
- #
84
- # def rm_search_area(corner, i)
85
- # {
86
- # x: (ppu_x * rmx(corner, i)).round,
87
- # y: (ppu_y * rmy(corner, i)).round,
88
- # w: (ppu_x * (reg_search + reg_radius * i)).round,
89
- # h: (ppu_y * (reg_search + reg_radius * i)).round
90
- # }
91
- # end
92
-
93
- # # finding the x position of the registration area based on iteration
94
- # def rmx(corner, i)
95
- # case corner
96
- # when :tl; reg_off
97
- # when :tr; page_width - reg_search - reg_off - reg_radius * i
98
- # when :br; page_width - reg_search - reg_off - reg_radius * i
99
- # when :bl; reg_off
100
- # end
101
- # end
102
-
103
- # # finding the y position of the registration area based on iteration
104
- # def rmy(corner, i)
105
- # case corner
106
- # when :tl; reg_off
107
- # when :tr; reg_off
108
- # when :br; page_height - reg_search - reg_off - reg_radius * i
109
- # when :bl; page_height - reg_search - reg_off - reg_radius * i
110
- # end
111
- # end
112
-
113
- # def rm_edgy_x() (ppu_x * reg_radius).round + 5 end
114
- # def rm_edgy_y() (ppu_y * reg_radius).round + 5 end
115
- # def rm_max_search_area_side() (ppu_x * page_width / 4).round end
116
-
117
- # def cell_corner_size
118
- # d = choice_cell_area(0,0)
119
- # (d[:w]-d[:h]).abs
120
- # end
121
-
122
- # # GET RID OF THIS!
123
- # def barcode_bit_areas(bitstring = '1' * barcode_bits)
124
- # areas = []
125
- # bitstring.reverse.each_char.with_index do |c, i|
126
- # areas << barcode_bit_area(i+1) if c=='1'
127
- # end
128
- # areas
129
- # end
@@ -70,6 +70,27 @@ module Mork
70
70
  @cround ||= [width_of_cell, height_of_cell].min / 2
71
71
  end
72
72
 
73
+ # UIDs
74
+ def width_of_uid
75
+ uid_cell_width.mm
76
+ end
77
+
78
+ def height_of_uid
79
+ uid_cell_height.mm
80
+ end
81
+
82
+ def uid_spacing_x
83
+ (uid_width / 11).mm
84
+ end
85
+
86
+ def uid_spacing_y
87
+ (uid_height / (uid_digits+1)).mm
88
+ end
89
+
90
+ def uround
91
+ @uround ||= [width_of_uid, height_of_uid].min / 2
92
+ end
93
+
73
94
  def missing_header?(k)
74
95
  @params[:header][k].nil?
75
96
  end
@@ -144,37 +144,3 @@ module Mork
144
144
  end
145
145
  end
146
146
  end
147
-
148
- # def patch(shape: nil, wid: width, hei: height)
149
- # s = "|convert #{@path} #{shape} gray:-"
150
- # bytes = IO.read(s).unpack 'C*'
151
- # NPatch.new bytes, wid, hei
152
- # end
153
-
154
- # # raw_patch returns an array containing the pixels of the original image
155
- # def raw_patch
156
- # @raw_pixels ||= patch
157
- # end
158
-
159
- # def exec_mm_cmd(c, pp)
160
- # c.distort(:perspective, pps(pp)) if pp
161
- # @cmd.each { |cmd| c.send(*cmd) }
162
- # end
163
-
164
- # def highlight_cells(coords)
165
- # @cmd << [:stroke, 'none']
166
- # @cmd << [:fill, 'rgba(255, 255, 0, 0.3)']
167
- # coords.each do |c|
168
- # @cmd << [:draw, "roundrectangle #{c.choice_cell}"]
169
- # end
170
- # end
171
-
172
- # def outline(coords)
173
- # @cmd << [:stroke, 'green']
174
- # @cmd << [:strokewidth, '2']
175
- # @cmd << [:fill, 'none']
176
- # coords.each do |c|
177
- # @cmd << [:draw, "roundrectangle #{c.choice_cell}"]
178
- # end
179
- # end
180
-
@@ -12,7 +12,8 @@ module Mork
12
12
  def initialize(path, grom)
13
13
  @mack = Magicko.new path
14
14
  @grom = grom.set_page_size @mack.width, @mack.height
15
- @choxq = [grom.max_choices_per_question] * grom.max_questions
15
+ # @choxq = [grom.max_choices_per_question] * grom.max_questions
16
+ @choxq = [(0...@grom.max_choices_per_question).to_a] * grom.max_questions
16
17
  @rm = {} # registration mark centers
17
18
  @valid = register
18
19
  end
@@ -30,18 +31,24 @@ module Mork
30
31
  }
31
32
  end
32
33
 
33
- def set_ch(cho)
34
- @choxq = cho
34
+ def set_ch(choxq)
35
+ @choxq = choxq.map { |ncho| (0...ncho).to_a }
35
36
  # if set_ch is called more than once, discard memoization
36
- @marked_choices = nil
37
+ @marked_choices = @choice_mean_darkness = nil
38
+ end
39
+
40
+ def choice_mean_darkness
41
+ @choice_mean_darkness ||= begin
42
+ itemator(@choxq) { |q,c| reg_pixels.average @grom.choice_cell_area(q, c) }
43
+ end
37
44
  end
38
45
 
39
46
  def marked
40
47
  @marked_choices ||= begin
41
- @choxq.map.with_index do |ncho, q|
48
+ choice_mean_darkness.map do |cho|
42
49
  [].tap do |choices|
43
- ncho.times do |c|
44
- choices << c if shade_of(q, c) < choice_threshold
50
+ cho.map.with_index do |drk, c|
51
+ choices << c if drk < choice_threshold
45
52
  end
46
53
  end
47
54
  end
@@ -50,7 +57,7 @@ module Mork
50
57
 
51
58
  def barcode_bits
52
59
  @barcode_bits ||= begin
53
- @grom.barcode_bits.times.collect do |b|
60
+ @grom.barcode_bits.times.map do |b|
54
61
  reg_pixels.average(@grom.barcode_bit_area b+1) < barcode_threshold
55
62
  end
56
63
  end
@@ -65,10 +72,9 @@ module Mork
65
72
  when :marked
66
73
  choice_cell_areas marked
67
74
  when :all
68
- all_choice_cell_areas
75
+ choice_cell_areas @choxq
69
76
  when :max
70
- choice_cell_areas [@grom.max_choices_per_question] * @grom.max_questions
71
- # @grom.max_questions.times.map { |i| (0...@grom.max_choices_per_question).to_a }
77
+ @grom.choice_cell_areas.flatten
72
78
  when Array
73
79
  choice_cell_areas where
74
80
  else
@@ -96,13 +102,9 @@ module Mork
96
102
  private #
97
103
  # ============================================================#
98
104
 
99
- def itemator(items=@choxq)
100
- items.map.with_index do |cho, q|
101
- if cho.is_a? Fixnum
102
- cho.times.map { |c| yield q, c }
103
- else
104
- cho.map { |c| yield q, c }
105
- end
105
+ def itemator(cells)
106
+ cells.map.with_index do |cho, q|
107
+ cho.map { |c| yield q, c }
106
108
  end
107
109
  end
108
110
 
@@ -110,41 +112,24 @@ module Mork
110
112
  itemator(cells) { |q,c| @grom.choice_cell_area q, c }.flatten
111
113
  end
112
114
 
113
- def all_choice_cell_areas
114
- @all_choice_cell_areas ||= choice_cell_areas(@choxq)
115
- end
116
-
117
115
  def each_corner
118
116
  [:tl, :tr, :br, :bl].each { |c| yield c }
119
117
  end
120
118
 
121
- def shade_of(q,c)
122
- choice_cell_averages[q][c]
123
- end
124
-
125
- def choice_cell_averages
126
- @choice_cell_averages ||= begin
127
- itemator { |q, c| reg_pixels.average @grom.choice_cell_area(q, c) }
128
- end
129
- end
130
-
131
119
  def choice_threshold
132
120
  @choice_threshold ||= begin
133
- (cal_cell_mean-darkest_cell_mean) * @grom.choice_threshold + darkest_cell_mean
121
+ dcm = choice_mean_darkness.flatten.min
122
+ (cal_cell_mean-dcm) * @grom.choice_threshold + dcm
134
123
  end
135
124
  end
136
125
 
137
- def barcode_threshold
138
- @barcode_threshold ||= (paper_white + ink_black) / 2
139
- end
140
-
141
126
  def cal_cell_mean
142
127
  m = @grom.calibration_cell_areas.collect { |c| reg_pixels.average c }
143
128
  m.inject(:+) / m.length.to_f
144
129
  end
145
130
 
146
- def darkest_cell_mean
147
- choice_cell_averages.flatten.min
131
+ def barcode_threshold
132
+ @barcode_threshold ||= (paper_white + ink_black) / 2
148
133
  end
149
134
 
150
135
  def ink_black
@@ -159,12 +144,6 @@ module Mork
159
144
  @reg_pixels ||= NPatch.new @mack.registered_bytes(@rm), @mack.width, @mack.height
160
145
  end
161
146
 
162
- def coordinates_of(cells)
163
- cells.collect.each_with_index do |q, i|
164
- q.collect { |c| @grom.choice_cell_area(i, c) }
165
- end.flatten
166
- end
167
-
168
147
  # find the XY coordinates of the 4 registration marks,
169
148
  # plus the stdev of the search area as quality control
170
149
  def register
@@ -185,93 +164,3 @@ module Mork
185
164
  end
186
165
  end
187
166
  end
188
-
189
- # def corner
190
- # @corner_size ||= @grom.cell_corner_size
191
- # end
192
-
193
- # 1000.times do |i|
194
- # @rmsa[corner] = @grom.rm_search_area(corner, i)
195
- # # puts "================================================================"
196
- # # puts "Corner #{corner} - Iteration #{i} - Coo #{@rmsa[corner].inspect}"
197
- # cx, cy = raw_pixels.dark_centroid @rmsa[corner]
198
- # if cx.nil?
199
- # status = :no_contrast
200
- # elsif (cx < @grom.rm_edgy_x) or
201
- # (cy < @grom.rm_edgy_y) or
202
- # (cy > @rmsa[corner][:h] - @grom.rm_edgy_y) or
203
- # (cx > @rmsa[corner][:w] - @grom.rm_edgy_x)
204
- # status = :edgy
205
- # else
206
- # return {status: :ok, x: cx + @rmsa[corner][:x], y: cy + @rmsa[corner][:y]}
207
- # end
208
- # return {status: status, x: nil, y: nil} if @rmsa[corner][:w] > @grom.rm_max_search_area_side
209
- # end
210
-
211
- # TAKE OUT
212
- # def highlight_reg_area
213
- # @mack.highlight_rect [@rmsa[:tl], @rmsa[:tr], @rmsa[:br], @rmsa[:bl]]
214
- # return unless valid?
215
- # @mack.join [@rm[:tl], @rm[:tr], @rm[:br], @rm[:bl]]
216
- # end
217
-
218
- # def raw_pixels
219
- # @mack.raw_patch
220
- # end
221
-
222
- # def outline(cells)
223
- # return if cells.empty?
224
- # @mack.outline coordinates_of(cells)
225
- # end
226
-
227
- # # highlight_cells(cells, roundedness)
228
- # #
229
- # # partially transparent yellow on top of choice cells
230
- # def highlight_cells(cells)
231
- # return if cells.empty?
232
- # @mack.highlight_cells coordinates_of(cells)
233
- # end
234
-
235
- # def highlight_all_choices
236
- # cells = (0...@grom.max_questions).collect { |i| (0...@grom.max_choices_per_question).to_a }
237
- # highlight_cells cells
238
- # end
239
-
240
- # def highlight_barcode(bitstring)
241
- # @mack.highlight_rect @grom.barcode_bit_areas bitstring
242
- # end
243
-
244
- # def highlight_rm_centers
245
- # each_corner { |c| @mack.plus @rm[c][:x], @rm[c][:y], 20 }
246
- # end
247
-
248
- # def highlight_rm_areas
249
- # each_corner { |c| @mack.highlight_area @grom.rm_crop_area(c) }
250
- # end
251
-
252
- # def cross(cells)
253
- # return if cells.empty?
254
- # cells = [cells] if cells.is_a? Hash
255
- # @mack.cross coordinates_of(cells)
256
- # end
257
-
258
- # def barcode_bit?(i)
259
- # reg_pixels.average(@grom.barcode_bit_area i+1) < barcode_threshold
260
- # end
261
-
262
- # puts "TL: #{@rm[:tl].inspect}"
263
- # puts "TR: #{@rm[:tr].inspect}"
264
- # puts "BR: #{@rm[:br].inspect}"
265
- # puts "BL: #{@rm[:bl].inspect}"
266
-
267
- # puts "REG #{@grom.rm_blur} - #{@grom.rm_dilate} - C #{c.inspect}"
268
-
269
- # def marked_int
270
- # marked.map do |q|
271
- # [].tap do |choices|
272
- # q.each_with_index do |choice, idx|
273
- # choices << idx if choice
274
- # end
275
- # end
276
- # end
277
- # end
@@ -27,33 +27,3 @@ module Mork
27
27
  end
28
28
  end
29
29
  end
30
-
31
- # def dark_centroid(c = nil)
32
- # p = crop c
33
- # sufficient_contrast?(p) or return
34
- # xp = p.sum(1).to_a
35
- # yp = p.sum(0).to_a
36
- # # find the intensity trough
37
- # ctr_x = xp.find_index(xp.min)
38
- # ctr_y = yp.find_index(yp.min)
39
- # # puts "Centroid: #{ctr_x}, #{ctr_y} - MinX #{xp.min/xp.length}, MaxX #{xp.max/xp.length}, MinY #{yp.min/yp.length}, MaxY #{yp.max/yp.length}"
40
- # return ctr_x, ctr_y
41
- # end
42
-
43
- # def crop(c)
44
- # raise "crop HELL" if c.nil?
45
- # p = NArray.float c.w, c.h
46
- # p[true,true] = @patch[c.x_rng, c.y_rng]
47
- # p
48
- # end
49
-
50
- # def sufficient_contrast?(p)
51
- # # puts "Contrast: #{p.stddev}"
52
- # # tested with the few examples: spec/samples/rm0x.jpeg
53
- # p.stddev > 20
54
- # end
55
-
56
- # def length
57
- # # is this only going to be used for testing purposes?
58
- # @patch.length
59
- # end
@@ -1,6 +1,5 @@
1
1
  require 'mork/grid_omr'
2
2
  require 'mork/mimage'
3
- require 'mork/mimage_list'
4
3
 
5
4
  module Mork
6
5
  # Optical mark recognition of a response sheet that was: 1) generated
@@ -193,132 +192,3 @@ module Mork
193
192
  end
194
193
  end
195
194
  end
196
-
197
-
198
- # # write_raw(output_path_file_name)
199
- # #
200
- # # writes out a copy of the source image before registration;
201
- # # the output image will also contain any previously applied overlays
202
- # # if the argument is omitted, the image is created in-place,
203
- # # i.e. the original source image is overwritten.
204
- # def write_raw(fname=nil)
205
- # @mim.write(fname, false)
206
- # end
207
-
208
- # # Array of arrays of marked choices.
209
- # #
210
- # # @param questions [Fixnum, Range, or Array] look for the first n questions
211
- # # If the argument is omitted, all available choices are evaluated.
212
- # # @return [Array] The list of marked choices as an array (one element per
213
- # # question) of arrays (the indices of all marked choices for the question)
214
- # def mark_array(questions = nil)
215
- # return if not_registered
216
- # x = question_range questions
217
- # byebug
218
- # x.collect do |q|
219
- # [].tap do |cho|
220
- # (0...@grom.max_choices_per_question).each do |c|
221
- # cho << c if marked?(q, c)
222
- # end
223
- # end
224
- # end
225
- # end
226
-
227
- # # Array of arrays of the characters corresponding to marked choices.
228
- # # At this time, only the latin sequence 'A, B, C...' is supported.
229
- # #
230
- # # @param questions [Fixnum, Range, Array] same as for `mark_array`
231
- # # @return [Array] The list of marked choices as an array (one element per
232
- # # question) of arrays (the indices of all marked choices for the question)
233
- # def mark_char_array(questions = nil)
234
- # return if not_registered
235
- # question_range(questions).collect do |q|
236
- # [].tap do |cho|
237
- # (0...@grom.max_choices_per_question).each do |c|
238
- # cho << (65+c).chr if marked?(q, c)
239
- # end
240
- # end
241
- # end
242
- # end
243
-
244
- # # Array of logical arrays of marked choices
245
- # #
246
- # # @param [Fixnum, Range, Array]
247
- # def mark_logical_array(r = nil)
248
- # return if not_registered
249
- # question_range(r).collect do |q|
250
- # (0...@grom.max_choices_per_question).collect {|c| marked?(q, c)}
251
- # end
252
- # end
253
-
254
- # def question_range(r)
255
- # # TODO: help text: although not API, people need to know this!
256
- # if r.nil?
257
- # (0...@nitems.length)
258
- # elsif r.is_a? Fixnum
259
- # (0...r)
260
- # elsif r.is_a? Array
261
- # r
262
- # else
263
- # raise "Invalid argument"
264
- # end
265
- # end
266
-
267
- # def outline(cells)
268
- # return if not_registered
269
- # raise "Invalid ‘cells’ argument" unless cells.kind_of? Array
270
- # @mim.outline cells
271
- # end
272
-
273
- # def cross(cells)
274
- # return if not_registered
275
- # raise "Invalid ‘cells’ argument" unless cells.kind_of? Array
276
- # @mim.cross cells
277
- # end
278
-
279
- # def cross_marked
280
- # return if not_registered
281
- # @mim.cross mark_array
282
- # end
283
-
284
- # def highlight_all_choices
285
- # return if not_registered
286
- # @mim.highlight_all_choices
287
- # end
288
-
289
- # def highlight_marked
290
- # return if not_registered
291
- # @mim.highlight_cells mark_array
292
- # end
293
-
294
- # def highlight_barcode
295
- # return if not_registered
296
- # @mim.highlight_barcode barcode_string
297
- # end
298
-
299
- # def barcode_bit_string(i)
300
- # @mim.barcode_bit?(i) ? "1" : "0"
301
- # end
302
-
303
- # def validate_choices(ch=nil)
304
- # return false unless valid?
305
- # cho = case ch
306
- # when NilClass; [@mc] * @mq
307
- # when Fixnum; [@mc] * [[ch, @mq].min, 1].max
308
- # when Array; ch
309
- # else raise ArgumentError, 'Invalid choice set'
310
- # end
311
- # @marked_choices = @mim.marked cho
312
- # true
313
- # end
314
-
315
- # # Marked choices as boolean values
316
- # #
317
- # # @return [Array] an array of arrays of true/false values corresponding to
318
- # # marked vs unmarked choice cells.
319
- # def marked_logicals
320
- # return if not_registered
321
- # # this is the only marking function calling the mimage object
322
- # @marked_choices ||= @mim.marked
323
- # end
324
-
@@ -145,6 +145,23 @@ module Mork
145
145
  end
146
146
  end
147
147
 
148
+ def create_uid_stamps
149
+ create_stamp('uid') do
150
+ 10.times do |i|
151
+ offx = uid_spacing_x * i
152
+ stroke_rounded_rectangle [offx, 0],
153
+ @grip.width_of_uid,
154
+ @grip.height_of_uid,
155
+ @grip.uround
156
+ text_box i, at: [offx, 0],
157
+ width: @grip.width_of_uid,
158
+ height: @grip.height_of_uid,
159
+ align: :center,
160
+ valign: :center
161
+ end
162
+ end
163
+ end
164
+
148
165
  def create_choice_stamps
149
166
  ch_len.flatten.uniq.each do |t|
150
167
  create_stamp("s#{t}") do
@@ -1,3 +1,3 @@
1
1
  module Mork
2
- VERSION = '0.11.2'
2
+ VERSION = '0.12.0'
3
3
  end
@@ -8,6 +8,18 @@ module Mork
8
8
  let(:img) { sample_img 'jdoe1' }
9
9
  let(:fn) { File.basename(img.image_path) }
10
10
  let(:mim) { Mimage.new img.image_path, GridOMR.new(img.grid_path) }
11
+ describe '#choice_mean_darkness' do
12
+ it 'returns all choices as darkness averaga' do
13
+ d = mim.choice_mean_darkness
14
+ d.each do |q|
15
+ p = q.map do |c|
16
+ c.round
17
+ end.join ' '
18
+ # puts p
19
+ end
20
+ end
21
+ end
22
+
11
23
  describe 'basics' do
12
24
  it 'should be valid' do
13
25
  expect(mim.valid?).to be_truthy
@@ -19,7 +19,7 @@ module Mork
19
19
 
20
20
  describe '#set_choices' do
21
21
  it 'returns true if all goes well' do
22
- expect(omr.set_choices(10)).to be_truthy
22
+ expect(omr.set_choices([10])).to be_truthy
23
23
  end
24
24
  end
25
25
 
@@ -98,7 +98,7 @@ module Mork
98
98
 
99
99
  it 'highlights all possible choice cells' do
100
100
  omr.set_choices [5] * 30
101
- omr.overlay :highlight, :max
101
+ omr.overlay :highlight, :max
102
102
  omr.save "spec/out/highlight/max-#{fn}"
103
103
  end
104
104
 
@@ -118,6 +118,11 @@ module Mork
118
118
  omr.save "spec/out/mark/part-#{fn}"
119
119
  end
120
120
 
121
+ it 'outlines arbitrary cells' do
122
+ omr.overlay :outline, [[1,2], [], [0,1,2,3,4], [3]]
123
+ omr.save "spec/out/outline/some-#{fn}"
124
+ end
125
+
121
126
  it 'outlines and crosses marked cells' do
122
127
  omr.overlay :outline, standard_mark_array(24)
123
128
  omr.overlay :check
@@ -38,3 +38,12 @@ barcode:
38
38
  width: 3 # width of each barcode bit
39
39
  height: 3 # height of each barcode bit from the registration frame bottom side
40
40
  spacing: 4 # horizontal distance between adjacent barcode bit centers
41
+ uid:
42
+ digits: 6
43
+ left: 150
44
+ top: 30
45
+ width: 50
46
+ height: 40
47
+ cell_width: 4
48
+ cell_height: 3
49
+ box: true
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mork
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.2
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Giuseppe Bertini
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-19 00:00:00.000000000 Z
11
+ date: 2016-06-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: narray
@@ -189,7 +189,6 @@ files:
189
189
  - lib/mork/grid_pdf.rb
190
190
  - lib/mork/magicko.rb
191
191
  - lib/mork/mimage.rb
192
- - lib/mork/mimage_list.rb
193
192
  - lib/mork/npatch.rb
194
193
  - lib/mork/sheet_omr.rb
195
194
  - lib/mork/sheet_pdf.rb
@@ -200,7 +199,6 @@ files:
200
199
  - spec/mork/grid_omr_spec.rb
201
200
  - spec/mork/grid_spec.rb
202
201
  - spec/mork/magicko_spec.rb
203
- - spec/mork/mimage_list_spec.rb
204
202
  - spec/mork/mimage_spec.rb
205
203
  - spec/mork/npatch_spec.rb
206
204
  - spec/mork/sheet_omr_spec.rb
@@ -1,32 +0,0 @@
1
- # require 'RMagick'
2
-
3
- module Mork
4
- # @private
5
- # The class MimageList, currently abandoned
6
- class MimageList
7
- def initialize(fname)
8
- raise "Initializing a MimageList requires a string" unless fname.class == String
9
- if File.extname(fname) == '.pdf'
10
- @images = Magick::ImageList.new(fname) { self.density = 200 }
11
- else
12
- @images = Magick::ImageList.new(fname)
13
- end
14
- end
15
-
16
- def shift
17
- Mimage.new @images.shift
18
- end
19
-
20
- def [] (i)
21
- # puts "I: #{i}"
22
- # puts @images[i].inspect
23
- Mimage.new @images[i]
24
- end
25
-
26
- def each
27
- @images.each do |i|
28
- yield Mimage.new i
29
- end
30
- end
31
- end
32
- end
@@ -1,37 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module Mork
4
- # describe MimageList do
5
- # before(:all) do
6
- # tpg = sample_img(:two_pages)
7
- # @mlist = MimageList.new(tpg.filename)
8
- # end
9
- #
10
- # describe ".new" do
11
- # it "should raise an error unless called with a string" do
12
- # lambda {
13
- # MimageList.new(666)
14
- # }.should raise_error
15
- # end
16
- # end
17
- #
18
- # describe "[]" do
19
- # it "should return the 1st mimage in the stack" do
20
- # @mlist[0].should be_a(Mimage)
21
- # end
22
- #
23
- # it "should return the last mimage in the stack" do
24
- # @mlist[1].should be_a(Mimage)
25
- # end
26
- # end
27
- #
28
- # describe "each" do
29
- # it "should loop over all images" do
30
- # @mlist.each do |m|
31
- # puts m.inspect
32
- # m.should be_a(Mimage)
33
- # end
34
- # end
35
- # end
36
- # end
37
- end