mork 0.0.1 → 0.0.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.
- data/.gitignore +3 -0
- data/Gemfile +1 -2
- data/Guardfile +10 -0
- data/config/grids.yml +42 -0
- data/lib/mork.rb +8 -4
- data/lib/mork/grid.rb +307 -0
- data/lib/mork/grid_const.rb +14 -0
- data/lib/mork/mimage.rb +86 -0
- data/lib/mork/mimage_list.rb +29 -0
- data/lib/mork/npatch.rb +51 -0
- data/lib/mork/report.rb +39 -0
- data/lib/mork/sheet.rb +144 -0
- data/lib/mork/sheet_pdf.rb +97 -0
- data/lib/mork/version.rb +1 -1
- data/mork.gemspec +9 -2
- data/spec/mork/grid_spec.rb +85 -0
- data/spec/mork/mimage_list_spec.rb +37 -0
- data/spec/mork/mimage_spec.rb +48 -0
- data/spec/mork/npatch_spec.rb +52 -0
- data/spec/mork/report_spec.rb +13 -0
- data/spec/mork/sheet_pdf_spec.rb +34 -0
- data/spec/mork/sheet_spec.rb +149 -0
- data/spec/samples/code_sample.pdf +85 -0
- data/spec/samples/code_sample.png +0 -0
- data/spec/samples/code_zero.pdf +79 -0
- data/spec/samples/info.yml +53 -0
- data/spec/samples/reg_mark.jpg +0 -0
- data/spec/samples/sample.pages +0 -0
- data/spec/samples/sample01.jpg +0 -0
- data/spec/samples/two_pages.pdf +0 -0
- data/spec/spec_helper.rb +34 -0
- metadata +199 -31
@@ -0,0 +1,37 @@
|
|
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
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Mork
|
4
|
+
describe Mimage do
|
5
|
+
let(:smp) { sample_img(:sample01) }
|
6
|
+
let(:mim) { Mimage.new(smp.filename) }
|
7
|
+
|
8
|
+
describe ".new" do
|
9
|
+
it "should create a Mimage from a string pointing to an existing bitmap file" do
|
10
|
+
mim.should be_a(Mimage)
|
11
|
+
end
|
12
|
+
it "should create a Mimage from an existing Magick::ImageList object" do
|
13
|
+
i = Magick::ImageList.new smp.filename
|
14
|
+
Mimage.new(i).should be_a(Mimage)
|
15
|
+
end
|
16
|
+
it "should create a Mimage from an existing Magick::Image object" do
|
17
|
+
i = Magick::ImageList.new smp.filename
|
18
|
+
Mimage.new(i.first).should be_a(Mimage)
|
19
|
+
end
|
20
|
+
it "should raise an error if called with a fixnum" do
|
21
|
+
lambda { Mimage.new 1 }.should raise_error
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#crop" do
|
26
|
+
it "should return a Mimage" do
|
27
|
+
mim.crop({x: 0, y: 0, w: 10, h: 10}).should be_a(Mimage)
|
28
|
+
end
|
29
|
+
it "should return a Mimage of the correct width" do
|
30
|
+
i = mim.crop({x: 0, y: 0, w: 20, h: 10})
|
31
|
+
i.width.should == 20
|
32
|
+
end
|
33
|
+
it "should return a Mimage of the correct height" do
|
34
|
+
i = mim.crop({x: 0, y: 0, w: 10, h: 10})
|
35
|
+
i.height.should == 10
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#crop!" do
|
40
|
+
it "should reduce the Mimage to the correct width" do
|
41
|
+
mim.crop!({x: 0, y: 0, w: 20, h: 10}).width.should == 20
|
42
|
+
end
|
43
|
+
it "should reduce the Mimage to the correct height" do
|
44
|
+
mim.crop!({x: 0, y: 0, w: 20, h: 10}).height.should == 10
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Mork
|
4
|
+
describe NPatch do
|
5
|
+
let(:rgm) { sample_img(:reg_mark) }
|
6
|
+
let(:mim) { Mimage.new(rgm.filename) }
|
7
|
+
|
8
|
+
describe ".new" do
|
9
|
+
it "should create an NPatch" do
|
10
|
+
NPatch.new(mim).should be_an(NPatch)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "#dark_centroid" do
|
15
|
+
it "should return the correct X" do
|
16
|
+
x, y = NPatch.new(mim).dark_centroid
|
17
|
+
x.should == rgm.info["centroid_x"]
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should return the correct Y" do
|
21
|
+
x, y = NPatch.new(mim).dark_centroid
|
22
|
+
y.should == rgm.info["centroid_y"]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# describe "#dark_centroid_on" do
|
29
|
+
# it "returns the actual xy offset of the tl registration mark" do
|
30
|
+
# x, y = mim.dark_centroid_on({x: 0, y: 0, w: 180, h: 180})
|
31
|
+
# x.should be_within(2).of(smp.reg_marks["tl_x"])
|
32
|
+
# y.should be_within(2).of(smp.reg_marks["tl_y"])
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# it "returns the actual xy offset of the tr registration mark" do
|
36
|
+
# x, y = mim.dark_centroid_on({x: smp.width-180, y: 0, w: 180, h: 180})
|
37
|
+
# x.should be_within(2).of(smp.reg_marks["tr_x"])
|
38
|
+
# y.should be_within(2).of(smp.reg_marks["tr_y"])
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# it "returns the actual xy offset of the br registration mark" do
|
42
|
+
# x, y = mim.dark_centroid_on({x: smp.width-180, y: smp.height-180, w: 180, h: 180})
|
43
|
+
# x.should be_within(2).of(smp.reg_marks["br_x"])
|
44
|
+
# y.should be_within(2).of(smp.reg_marks["br_y"])
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# it "returns the actual xy offset of the bl registration mark" do
|
48
|
+
# x, y = mim.dark_centroid_on({x: 0, y: smp.height-180, w: 180, h: 180})
|
49
|
+
# x.should be_within(2).of(smp.reg_marks["bl_x"])
|
50
|
+
# y.should be_within(2).of(smp.reg_marks["bl_y"])
|
51
|
+
# end
|
52
|
+
# end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Mork
|
4
|
+
describe SheetPDF do
|
5
|
+
it "should create a basic pdf" do
|
6
|
+
info = {
|
7
|
+
code: 18446744073709551615,
|
8
|
+
choices: [5] * 100,
|
9
|
+
header: {
|
10
|
+
name: "Bertini Giuseppe VR123456",
|
11
|
+
title: "Esame di Fondamenti Morfologici e Funzionali della Vita",
|
12
|
+
code: "119.27",
|
13
|
+
date: "18 gennaio 2013"
|
14
|
+
}
|
15
|
+
}
|
16
|
+
s = SheetPDF.new(Grid.new(:default), info)
|
17
|
+
s.save("tmp/f1.pdf")
|
18
|
+
|
19
|
+
info = {
|
20
|
+
code: 283764283738,
|
21
|
+
choices: [5] * 100,
|
22
|
+
header: {
|
23
|
+
name: "Francesco Gagliardi VR765432",
|
24
|
+
title: "Esame di Fondamenti Morfologici e Funzionali della Vita",
|
25
|
+
code: "119.28",
|
26
|
+
date: "18 gennaio 2013"
|
27
|
+
}
|
28
|
+
}
|
29
|
+
s = SheetPDF.new(Grid.new(:default), info)
|
30
|
+
s.save("tmp/f2.pdf")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Mork
|
4
|
+
describe Sheet do
|
5
|
+
context "describing marked choices" do
|
6
|
+
before(:all) do
|
7
|
+
fn = sample_img(:sample01).filename
|
8
|
+
@sheet = Sheet.new(fn, Grid.new)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "#marked?" do
|
12
|
+
it "should return true for a darkened choice" do
|
13
|
+
@sheet.marked?(0,0).should be_true
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should return false for a blank choice" do
|
17
|
+
@sheet.marked?(0,1).should be_false
|
18
|
+
end
|
19
|
+
|
20
|
+
it "prints the average whiteness of the first 40 sets of choices" do
|
21
|
+
40.times do |q|
|
22
|
+
t = (0..4).collect do |c|
|
23
|
+
@sheet.send(:shade_of, q, c).round
|
24
|
+
end
|
25
|
+
puts "#{q+1}: #{t.join(" ")}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#mark_array" do
|
31
|
+
it "should return an array of marked choices for each of the first 5 questions" do
|
32
|
+
@sheet.mark_array(5).should == [[0], [1], [2], [3], [4]]
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should return an array of marked choices for the specified question set" do
|
36
|
+
@sheet.mark_array([0, 1, 15, 16, 31]).should == [[0], [1], [0], [1], []]
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should return an array of @grid.max_questions length if called without arguments" do
|
40
|
+
@sheet.mark_array.length.should == 160
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#mark_logical_array" do
|
45
|
+
it "should return an array of booleans for each of the first questions" do
|
46
|
+
@sheet.mark_logical_array(5).should == [
|
47
|
+
[true, false, false, false, false],
|
48
|
+
[false, true, false, false, false],
|
49
|
+
[false, false, true, false, false],
|
50
|
+
[false, false, false, true, false],
|
51
|
+
[false, false, false, false, true],
|
52
|
+
]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
context "describing sheet codes" do
|
57
|
+
before(:all) do
|
58
|
+
@smp = sample_img(:code_sample)
|
59
|
+
@cshe = Sheet.new(@smp.filename, Grid.new)
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#dark_code_bit_shade" do
|
63
|
+
it "should be less than a certain amount" do
|
64
|
+
v = @cshe.dark_code_bit_shade
|
65
|
+
v.should < @cshe.send(:dark_threshold)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "#light_code_bit_shade" do
|
70
|
+
it "should be more than a certain amount" do
|
71
|
+
v = @cshe.light_code_bit_shade
|
72
|
+
v.should > @cshe.send(:dark_threshold)
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "#code_string" do
|
78
|
+
it "should read the bit string" do
|
79
|
+
@cshe.code_string.should == @smp.code_string
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "#code" do
|
84
|
+
it "should read the bit string and return the integer code" do
|
85
|
+
@cshe.code.should == @smp.code_int
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
context "highlighting stuff" do
|
91
|
+
it "should highlight all high bits in red" do
|
92
|
+
smp = sample_img(:code_sample)
|
93
|
+
s = Sheet.new(smp.filename, Grid.new)
|
94
|
+
CODE_BITS.times do |i|
|
95
|
+
if smp.code_int[i] == 1
|
96
|
+
s.highlight_code_bit i
|
97
|
+
end
|
98
|
+
end
|
99
|
+
s.write "tmp/bits.pdf"
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should highlight the dark calibration bit" do
|
103
|
+
fn = sample_img(:code_sample).filename
|
104
|
+
s = Sheet.new(fn, Grid.new)
|
105
|
+
s.highlight_dark_calibration_bit
|
106
|
+
s.write "tmp/dark_bit.pdf"
|
107
|
+
end
|
108
|
+
it "should highlight the light calibration bit" do
|
109
|
+
fn = sample_img(:code_sample).filename
|
110
|
+
s = Sheet.new(fn, Grid.new)
|
111
|
+
s.highlight_light_calibration_bit
|
112
|
+
s.write "tmp/light_bit.pdf"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context "multi-page pdf" do
|
117
|
+
before(:all) do
|
118
|
+
@smp = sample_img(:two_pages)
|
119
|
+
@mlist = MimageList.new(@smp.filename)
|
120
|
+
end
|
121
|
+
|
122
|
+
describe "reading the codes" do
|
123
|
+
it "should read the right code for the first page" do
|
124
|
+
s = Sheet.new(@mlist[0], Grid.new)
|
125
|
+
s.code.should == 18446744073709551615
|
126
|
+
end
|
127
|
+
it "should read the right code for the second page" do
|
128
|
+
s = Sheet.new(@mlist[1], Grid.new)
|
129
|
+
s.code.should == 283764283738
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe "getting the answers" do
|
134
|
+
it "should read the correct choices for the first page" do
|
135
|
+
s = Sheet.new(@mlist[0], Grid.new)
|
136
|
+
s.marked?( 0, 0).should be_true
|
137
|
+
s.marked?( 0, 1).should be_false
|
138
|
+
s.marked?(15, 3).should be_false
|
139
|
+
s.marked?(15, 4).should be_true
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should read the correct choices for the second page" do
|
143
|
+
s = Sheet.new(@mlist[1], Grid.new)
|
144
|
+
s.mark_array(15).should == [[0], [1], [2], [3], [4], [0], [1], [2, 3], [4], [1, 2, 3], [0], [1], [2], [3], [4]]
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
%PDF-1.3
|
2
|
+
%����
|
3
|
+
1 0 obj
|
4
|
+
<< /Creator <feff0050007200610077006e>
|
5
|
+
/Producer <feff0050007200610077006e>
|
6
|
+
>>
|
7
|
+
endobj
|
8
|
+
2 0 obj
|
9
|
+
<< /Type /Catalog
|
10
|
+
/Pages 3 0 R
|
11
|
+
>>
|
12
|
+
endobj
|
13
|
+
3 0 obj
|
14
|
+
<< /Type /Pages
|
15
|
+
/Count 1
|
16
|
+
/Kids [5 0 R]
|
17
|
+
>>
|
18
|
+
endobj
|
19
|
+
4 0 obj
|
20
|
+
<< /Length 1109
|
21
|
+
>>
|
22
|
+
stream
|
23
|
+
q
|
24
|
+
28.346 21.260 m
|
25
|
+
28.346 25.174 25.174 28.346 21.260 28.346 c
|
26
|
+
17.346 28.346 14.173 25.174 14.173 21.260 c
|
27
|
+
14.173 17.346 17.346 14.173 21.260 14.173 c
|
28
|
+
25.174 14.173 28.346 17.346 28.346 21.260 c
|
29
|
+
21.260 21.260 m
|
30
|
+
28.346 820.630 m
|
31
|
+
28.346 824.544 25.174 827.717 21.260 827.717 c
|
32
|
+
17.346 827.717 14.173 824.544 14.173 820.630 c
|
33
|
+
14.173 816.716 17.346 813.543 21.260 813.543 c
|
34
|
+
25.174 813.543 28.346 816.716 28.346 820.630 c
|
35
|
+
21.260 820.630 m
|
36
|
+
581.102 820.630 m
|
37
|
+
581.102 824.544 577.930 827.717 574.016 827.717 c
|
38
|
+
570.102 827.717 566.929 824.544 566.929 820.630 c
|
39
|
+
566.929 816.716 570.102 813.543 574.016 813.543 c
|
40
|
+
577.930 813.543 581.102 816.716 581.102 820.630 c
|
41
|
+
574.016 820.630 m
|
42
|
+
581.102 21.260 m
|
43
|
+
581.102 25.174 577.930 28.346 574.016 28.346 c
|
44
|
+
570.102 28.346 566.929 25.174 566.929 21.260 c
|
45
|
+
566.929 17.346 570.102 14.173 574.016 14.173 c
|
46
|
+
577.930 14.173 581.102 17.346 581.102 21.260 c
|
47
|
+
574.016 21.260 m
|
48
|
+
f
|
49
|
+
42.520 14.173 5.669 14.173 re
|
50
|
+
49.606 14.173 5.669 14.173 re
|
51
|
+
77.953 14.173 5.669 14.173 re
|
52
|
+
92.126 14.173 5.669 14.173 re
|
53
|
+
120.472 14.173 5.669 14.173 re
|
54
|
+
127.559 14.173 5.669 14.173 re
|
55
|
+
134.646 14.173 5.669 14.173 re
|
56
|
+
f
|
57
|
+
Q
|
58
|
+
|
59
|
+
endstream
|
60
|
+
endobj
|
61
|
+
5 0 obj
|
62
|
+
<< /Type /Page
|
63
|
+
/Parent 3 0 R
|
64
|
+
/MediaBox [0 0 595.2755905511815 841.889763779528]
|
65
|
+
/Contents 4 0 R
|
66
|
+
/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
|
67
|
+
>>
|
68
|
+
>>
|
69
|
+
endobj
|
70
|
+
xref
|
71
|
+
0 6
|
72
|
+
0000000000 65535 f
|
73
|
+
0000000015 00000 n
|
74
|
+
0000000109 00000 n
|
75
|
+
0000000158 00000 n
|
76
|
+
0000000215 00000 n
|
77
|
+
0000001376 00000 n
|
78
|
+
trailer
|
79
|
+
<< /Size 6
|
80
|
+
/Root 2 0 R
|
81
|
+
/Info 1 0 R
|
82
|
+
>>
|
83
|
+
startxref
|
84
|
+
1553
|
85
|
+
%%EOF
|
Binary file
|
@@ -0,0 +1,79 @@
|
|
1
|
+
%PDF-1.3
|
2
|
+
%����
|
3
|
+
1 0 obj
|
4
|
+
<< /Creator <feff0050007200610077006e>
|
5
|
+
/Producer <feff0050007200610077006e>
|
6
|
+
>>
|
7
|
+
endobj
|
8
|
+
2 0 obj
|
9
|
+
<< /Type /Catalog
|
10
|
+
/Pages 3 0 R
|
11
|
+
>>
|
12
|
+
endobj
|
13
|
+
3 0 obj
|
14
|
+
<< /Type /Pages
|
15
|
+
/Count 1
|
16
|
+
/Kids [5 0 R]
|
17
|
+
>>
|
18
|
+
endobj
|
19
|
+
4 0 obj
|
20
|
+
<< /Length 926
|
21
|
+
>>
|
22
|
+
stream
|
23
|
+
q
|
24
|
+
28.346 21.260 m
|
25
|
+
28.346 25.174 25.174 28.346 21.260 28.346 c
|
26
|
+
17.346 28.346 14.173 25.174 14.173 21.260 c
|
27
|
+
14.173 17.346 17.346 14.173 21.260 14.173 c
|
28
|
+
25.174 14.173 28.346 17.346 28.346 21.260 c
|
29
|
+
21.260 21.260 m
|
30
|
+
28.346 820.630 m
|
31
|
+
28.346 824.544 25.174 827.717 21.260 827.717 c
|
32
|
+
17.346 827.717 14.173 824.544 14.173 820.630 c
|
33
|
+
14.173 816.716 17.346 813.543 21.260 813.543 c
|
34
|
+
25.174 813.543 28.346 816.716 28.346 820.630 c
|
35
|
+
21.260 820.630 m
|
36
|
+
581.102 820.630 m
|
37
|
+
581.102 824.544 577.930 827.717 574.016 827.717 c
|
38
|
+
570.102 827.717 566.929 824.544 566.929 820.630 c
|
39
|
+
566.929 816.716 570.102 813.543 574.016 813.543 c
|
40
|
+
577.930 813.543 581.102 816.716 581.102 820.630 c
|
41
|
+
574.016 820.630 m
|
42
|
+
581.102 21.260 m
|
43
|
+
581.102 25.174 577.930 28.346 574.016 28.346 c
|
44
|
+
570.102 28.346 566.929 25.174 566.929 21.260 c
|
45
|
+
566.929 17.346 570.102 14.173 574.016 14.173 c
|
46
|
+
577.930 14.173 581.102 17.346 581.102 21.260 c
|
47
|
+
574.016 21.260 m
|
48
|
+
f
|
49
|
+
42.520 14.173 5.669 14.173 re
|
50
|
+
f
|
51
|
+
Q
|
52
|
+
|
53
|
+
endstream
|
54
|
+
endobj
|
55
|
+
5 0 obj
|
56
|
+
<< /Type /Page
|
57
|
+
/Parent 3 0 R
|
58
|
+
/MediaBox [0 0 595.2755905511815 841.889763779528]
|
59
|
+
/Contents 4 0 R
|
60
|
+
/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
|
61
|
+
>>
|
62
|
+
>>
|
63
|
+
endobj
|
64
|
+
xref
|
65
|
+
0 6
|
66
|
+
0000000000 65535 f
|
67
|
+
0000000015 00000 n
|
68
|
+
0000000109 00000 n
|
69
|
+
0000000158 00000 n
|
70
|
+
0000000215 00000 n
|
71
|
+
0000001192 00000 n
|
72
|
+
trailer
|
73
|
+
<< /Size 6
|
74
|
+
/Root 2 0 R
|
75
|
+
/Info 1 0 R
|
76
|
+
>>
|
77
|
+
startxref
|
78
|
+
1369
|
79
|
+
%%EOF
|