gost_frames 0.1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.rdoc +6 -0
- data/README.rdoc +14 -0
- data/Rakefile.rb +61 -0
- data/data/fonts/mipgost.ttf +0 -0
- data/examples/example_helper.rb +9 -0
- data/examples/generate_document/generate_document.rb +60 -0
- data/examples/generate_document/text_of_pages.txt +41 -0
- data/examples/merge/merge.rb +2 -0
- data/examples/merge/source_doc.pdf +0 -0
- data/lib/prawn/GOST/drawers.rb +346 -0
- data/lib/prawn/GOST/sections.rb +446 -0
- data/lib/prawn/GOST/settings.rb +2 -0
- data/lib/prawn/gost.rb +279 -0
- metadata +80 -0
data/LICENSE.rdoc
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
GostFrames is copyrighted free software produced by Alexey Pavlyukov along with
|
2
|
+
community contributions.
|
3
|
+
|
4
|
+
GostFrames library distributed under GPL license.
|
5
|
+
|
6
|
+
The font mipgost.ttf (in folder data/fonts/) distributed with an unknown to me free license. Source of the font http://dwg.ru/dnl/147.
|
data/README.rdoc
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
= GostFrames: Russian GOST Frames PDF Generation For Ruby
|
2
|
+
|
3
|
+
== English
|
4
|
+
GostFrames is a extension of Prawn PDF generation library (http://prawn.majesticseacreature.com)
|
5
|
+
for generation documents with Russian GOST standard frames.
|
6
|
+
Excuse me, but other documentation is written in Russian.
|
7
|
+
|
8
|
+
== Russian
|
9
|
+
|
10
|
+
GostFrames расширение библиотеки Prawn PDF (http://prawn.majesticseacreature.com)
|
11
|
+
для генерации документов в соответствии со стандартами ГОСТ.
|
12
|
+
|
13
|
+
|
14
|
+
|
data/Rakefile.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require "rake/rdoctask"
|
5
|
+
require "rake/gempackagetask"
|
6
|
+
|
7
|
+
GOST_FRAMES_VERSION = "0.1.0.0"
|
8
|
+
|
9
|
+
task :default => [:test]
|
10
|
+
|
11
|
+
desc "Run all tests"
|
12
|
+
Rake::TestTask.new do |test|
|
13
|
+
test.libs << "lib"
|
14
|
+
test.test_files = Dir[ "test/*_test.rb" ]
|
15
|
+
test.verbose = true
|
16
|
+
end
|
17
|
+
|
18
|
+
desc "genrates documentation"
|
19
|
+
Rake::RDocTask.new do |rdoc|
|
20
|
+
rdoc.rdoc_files.include( "README.textile",
|
21
|
+
"lib/" )
|
22
|
+
rdoc.main = "README.textile"
|
23
|
+
rdoc.rdoc_dir = "doc/html"
|
24
|
+
rdoc.title = "GostFrames Documentation"
|
25
|
+
rdoc.options = ['--charset=utf-8']
|
26
|
+
end
|
27
|
+
|
28
|
+
desc "run all examples"
|
29
|
+
task :examples do
|
30
|
+
mkdir_p "examples_output"
|
31
|
+
examples = Dir["examples/**/*.rb"]
|
32
|
+
t = Time.now
|
33
|
+
puts "Running Examples"
|
34
|
+
examples.each { |file| `ruby -Ilib #{file}` }
|
35
|
+
puts "Ran in #{Time.now - t} s"
|
36
|
+
`mv *.pdf examples_output`
|
37
|
+
end
|
38
|
+
|
39
|
+
spec = Gem::Specification.new do |s|
|
40
|
+
s.name = 'gost_frames'
|
41
|
+
s.version = GOST_FRAMES_VERSION
|
42
|
+
s.date = '2009-09-23'
|
43
|
+
|
44
|
+
s.summary = 'Library for creation page frames of Russian GOST standard.'
|
45
|
+
s.email = 'lexaficus@list.ru'
|
46
|
+
s.authors = ['Alexey Pavlyukov']
|
47
|
+
s.has_rdoc = false
|
48
|
+
s.rdoc_options = ["--main", "README.textile", "--title", "GostFrames Documentation"]
|
49
|
+
s.extra_rdoc_files = ["README.rdoc", "LICENSE.rdoc"]
|
50
|
+
s.rdoc_options = ["--charset=utf-8"]
|
51
|
+
s.require_paths = ["lib"]
|
52
|
+
s.add_dependency("prawn",">=0.4.0")
|
53
|
+
|
54
|
+
s.files = Dir.glob("{examples,lib,data}/**/**/*") + ["Rakefile.rb"] + s.extra_rdoc_files
|
55
|
+
s.test_files = Dir[ "test/*_test.rb" ]
|
56
|
+
end
|
57
|
+
|
58
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
59
|
+
pkg.need_zip = true
|
60
|
+
pkg.need_tar = true
|
61
|
+
end
|
Binary file
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "#{File.dirname(__FILE__)}/../example_helper.rb"
|
3
|
+
|
4
|
+
page_text = IO.readlines( "#{File.dirname(__FILE__)}/text_of_pages.txt", '----')
|
5
|
+
|
6
|
+
Prawn::Document.generate("generate_document.pdf", :skip_page_creation => true ) do
|
7
|
+
|
8
|
+
gost_initialize
|
9
|
+
gost_duplex
|
10
|
+
|
11
|
+
gost_set_font "#{File.dirname(__FILE__)}/../../data/fonts/mipgost.ttf" # download from http://dwg.ru/dnl/147
|
12
|
+
|
13
|
+
attribute2 "АВВГ.000000.000"
|
14
|
+
attribute11_1 "Иванов"
|
15
|
+
attribute11_2 "Петров"
|
16
|
+
attribute11_4 "Сидоров"
|
17
|
+
attribute1 [
|
18
|
+
" УНИВЕРСАЛЬНЫЙ СТАНОК ",
|
19
|
+
" НАРЕЗКИ КОЛБАСЫ "]
|
20
|
+
|
21
|
+
attribute8 "ООО \"Рога и Копыта\""
|
22
|
+
attribute19 ['1', '2', '3']
|
23
|
+
|
24
|
+
page_count = 7
|
25
|
+
page_counter = 0
|
26
|
+
attribute7 page_count
|
27
|
+
|
28
|
+
gost_page :gost_page_type => :title, :size => "A4", :layout => :portrait do
|
29
|
+
text page_text[page_counter]
|
30
|
+
end
|
31
|
+
|
32
|
+
gost_page :gost_page_type => :first_text, :size => "A4", :layout => :portrait do
|
33
|
+
attribute6 page_counter+= 1
|
34
|
+
text page_text[page_counter]
|
35
|
+
end
|
36
|
+
|
37
|
+
gost_page(:gost_page_type => :normal, :size => 'A4', :layout => :portrait) {
|
38
|
+
attribute6 page_counter+= 1
|
39
|
+
text page_text[page_counter]
|
40
|
+
}
|
41
|
+
|
42
|
+
gost_page(:gost_page_type => :normal, :size => 'A4', :layout => :landscape) {
|
43
|
+
attribute6 page_counter+= 1
|
44
|
+
text page_text[page_counter]
|
45
|
+
}
|
46
|
+
|
47
|
+
gost_page(:gost_page_type => :normal, :size => 'A3', :layout => :portrait) {
|
48
|
+
attribute6 page_counter+= 1
|
49
|
+
text page_text[page_counter]
|
50
|
+
}
|
51
|
+
|
52
|
+
gost_page(:gost_page_type => :normal, :size => 'A3', :layout => :landscape) {
|
53
|
+
attribute6 page_counter+= 1
|
54
|
+
text page_text[page_counter]
|
55
|
+
}
|
56
|
+
|
57
|
+
gost_change_list_page{
|
58
|
+
attribute6 page_counter+= 1
|
59
|
+
}
|
60
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
Материалл из WikiPedia (http://ru.wikipedia.org/wiki/%D0%95%D0%A1%D0%9A%D0%94)
|
3
|
+
|
4
|
+
Единая система конструкторской документации (ЕСКД)[1] — комплекс государственных стандартов,
|
5
|
+
устанавливающих взаимосвязанные правила,
|
6
|
+
требования и нормы по разработке, оформлению и обращению конструкторской документации[2],
|
7
|
+
разрабатываемой и применяемой на всех стадиях жизненного цикла изделия
|
8
|
+
(при проектировании, разработке, изготовлении, контроле, приемке, эксплуатации, ремонте, утилизации).
|
9
|
+
----
|
10
|
+
Основное назначение стандартов ЕСКД состоит в установлении единых оптимальных правил,
|
11
|
+
требований и норм выполнения, оформления и обращения конструкторской документации, которые обеспечивают[1]:
|
12
|
+
----
|
13
|
+
1. применение современных методов и средств на всех стадиях жизненного цикла изделия;
|
14
|
+
----
|
15
|
+
2. возможность взаимообмена конструкторской документацией без ее переоформления;
|
16
|
+
----
|
17
|
+
3. оптимальную комплектность конструкторской документации;
|
18
|
+
----
|
19
|
+
4. механизацию и автоматизацию обработки конструкторских документов и содержащейся в них информации;
|
20
|
+
----
|
21
|
+
5. высокое качество изделий;
|
22
|
+
----
|
23
|
+
6. наличие в конструкторской документации требований, обеспечивающих безопасность использования изделий для жизни и здоровья потребителей, окружающей среды, а также предотвращение причинения вреда имуществу;
|
24
|
+
----
|
25
|
+
7. возможность расширения унификации и стандартизации при проектировании изделий и разработке конструкторской документации;
|
26
|
+
----
|
27
|
+
8. возможность проведения сертификации изделий;
|
28
|
+
----
|
29
|
+
9. сокращение сроков и снижение трудоемкости подготовки производства;
|
30
|
+
----
|
31
|
+
10. правильную эксплуатацию изделий;
|
32
|
+
----
|
33
|
+
11. оперативную подготовку документации для быстрой переналадки действующего производства;
|
34
|
+
----
|
35
|
+
12. упрощение форм конструкторских документов и графических изображений;
|
36
|
+
----
|
37
|
+
13. возможность создания и ведения единой информационной базы;
|
38
|
+
----
|
39
|
+
14. возможность гармонизации стандартов ЕСКД с международными стандартами (ИСО, МЭК) в области конструкторской документации;
|
40
|
+
----
|
41
|
+
15. возможность информационного обеспечения поддержки жизненного цикла изделия.
|
Binary file
|
@@ -0,0 +1,346 @@
|
|
1
|
+
module GOST::Drawers
|
2
|
+
|
3
|
+
def gost_get_optimal_font_size(text, w, h)
|
4
|
+
|
5
|
+
coeff = w / width_of(text)
|
6
|
+
f_s = font_size * coeff
|
7
|
+
coeff *= [f_s, h].min / f_s
|
8
|
+
f_s = [f_s, h].min
|
9
|
+
# длина текста
|
10
|
+
t_w = width_of(text) * coeff
|
11
|
+
return { :f_s => f_s, :w => t_w , :h => h}
|
12
|
+
end
|
13
|
+
|
14
|
+
SimpleAttributeDrawer = lambda { |pdf, atr_value, options|
|
15
|
+
|
16
|
+
str = atr_value.to_s
|
17
|
+
|
18
|
+
if str.empty?
|
19
|
+
return
|
20
|
+
end
|
21
|
+
|
22
|
+
h = options[:h] - pdf.mm(1)
|
23
|
+
w = options[:w] - pdf.mm(1)
|
24
|
+
t_w = options[:orientation] == :vertical ? h : w
|
25
|
+
t_h = options[:orientation] == :vertical ? w : h
|
26
|
+
|
27
|
+
pos = options[:pos]
|
28
|
+
pos[0] += pdf.mm(0.5)
|
29
|
+
pos[1] += pdf.mm(0.5)
|
30
|
+
|
31
|
+
f_s = 12
|
32
|
+
|
33
|
+
|
34
|
+
if o_f_s = options[:font_size]
|
35
|
+
t_h = o_f_s
|
36
|
+
t_w = pdf.width_of(str) * o_f_s / pdf.font_size
|
37
|
+
f_s = o_f_s
|
38
|
+
else
|
39
|
+
t_s = pdf.gost_get_optimal_font_size str, t_w, t_h
|
40
|
+
|
41
|
+
f_s = t_s[:f_s]
|
42
|
+
t_w = t_s[:w]
|
43
|
+
t_h = t_s[:h]
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
if options[:orientation] == :vertical
|
50
|
+
posx = pos[0] + w - w/2.0 + t_h / 2.0
|
51
|
+
posy = pos[1] - h + h/2.0 - t_w/2.0
|
52
|
+
pdf.text(str, {:align => :center, :size => f_s, :at => [posx, posy], :rotate => 90})
|
53
|
+
else
|
54
|
+
posx = pos[0] + w/2.0 - t_w/2.0
|
55
|
+
posy = pos[1] - h + h/2.0 - f_s/2.0
|
56
|
+
pdf.text(str, {:align => :center, :size => f_s, :at => [posx, posy]})
|
57
|
+
end
|
58
|
+
|
59
|
+
}
|
60
|
+
|
61
|
+
|
62
|
+
AttributeDrawer = lambda { |pdf, atr_value, options|
|
63
|
+
|
64
|
+
case atr_value
|
65
|
+
when Array
|
66
|
+
w = options[:w]
|
67
|
+
h = options[:h] / atr_value.size
|
68
|
+
|
69
|
+
f_s = options[:font_size]
|
70
|
+
if ! f_s
|
71
|
+
font_sizes = []
|
72
|
+
atr_value.each { |val|
|
73
|
+
font_sizes << pdf.gost_get_optimal_font_size(val.to_s, w, h)[:f_s]
|
74
|
+
}
|
75
|
+
|
76
|
+
f_s = font_sizes.min
|
77
|
+
end
|
78
|
+
|
79
|
+
pos = options[:pos].dup
|
80
|
+
if (f_s * atr_value.size) < (options[:h] - f_s) then
|
81
|
+
h = f_s*1.1
|
82
|
+
pos[1] = pos[1] - options[:h] / 2.0 + h * atr_value.size / 2.0
|
83
|
+
end
|
84
|
+
|
85
|
+
atr_value.each { |val|
|
86
|
+
a_options = {:w => w, :h => h, :pos => pos.dup, :font_size => f_s}
|
87
|
+
SimpleAttributeDrawer.call pdf, val.to_s, a_options
|
88
|
+
pos[1] = pos[1] - h
|
89
|
+
}
|
90
|
+
else
|
91
|
+
SimpleAttributeDrawer.call pdf, atr_value.to_s, options
|
92
|
+
end
|
93
|
+
}
|
94
|
+
|
95
|
+
DefaultDrawer = lambda { |pdf, section, options|
|
96
|
+
|
97
|
+
ps = section[:pos].dup
|
98
|
+
w = section[:w]
|
99
|
+
h = section[:h]
|
100
|
+
|
101
|
+
if options[:align] == :left
|
102
|
+
ps[0] = ps[0] + w
|
103
|
+
w = -w
|
104
|
+
end
|
105
|
+
|
106
|
+
pdf.stroke do
|
107
|
+
pdf.polygon ps, [ps[0] + w, ps[1]]
|
108
|
+
pdf.polygon ps, [ps[0], ps[1] - h]
|
109
|
+
end
|
110
|
+
|
111
|
+
if lines = options[:lines]
|
112
|
+
lines.each { |type|
|
113
|
+
case type
|
114
|
+
when :bottom
|
115
|
+
p1 = [section[:pos][0], section[:pos][1] - section[:h]]
|
116
|
+
p2 = [p1[0] + section[:w], p1[1]]
|
117
|
+
pdf.stroke do
|
118
|
+
pdf.polygon p1, p2
|
119
|
+
end
|
120
|
+
end
|
121
|
+
}
|
122
|
+
end
|
123
|
+
|
124
|
+
text = section[:text]
|
125
|
+
|
126
|
+
if (attribute = section[:attribute]) && ! options[:no_attribute]
|
127
|
+
text = pdf.get_attribute(attribute.id2name)
|
128
|
+
end
|
129
|
+
|
130
|
+
f_s = options[:font_size]
|
131
|
+
f_s = pdf.mm(f_s) if f_s
|
132
|
+
|
133
|
+
if text
|
134
|
+
a_options = {:w => w.abs, :h => h, :pos => section[:pos].dup, :font_size => f_s}
|
135
|
+
AttributeDrawer.call pdf, text, a_options
|
136
|
+
end
|
137
|
+
}
|
138
|
+
|
139
|
+
|
140
|
+
Section4Drawer = lambda { |pdf, section, options|
|
141
|
+
options[:no_attribute] = true
|
142
|
+
DefaultDrawer.call(pdf, section, options)
|
143
|
+
|
144
|
+
ps = section[:pos].dup
|
145
|
+
w = section[:w]
|
146
|
+
h = section[:h]
|
147
|
+
step = pdf.mm(5)
|
148
|
+
top = ps[1] - step
|
149
|
+
h2 = h - step
|
150
|
+
|
151
|
+
pdf.stroke do
|
152
|
+
pdf.polygon [ps[0], top], [ps[0]+w, top]
|
153
|
+
pdf.polygon [ps[0] + step, top], [ps[0]+step, top - h2]
|
154
|
+
pdf.polygon [ps[0] + step*2, top], [ps[0]+step*2, top - h2]
|
155
|
+
end
|
156
|
+
|
157
|
+
lit_options = {:w => w.abs, :h => step, :pos => section[:pos].dup}
|
158
|
+
AttributeDrawer.call pdf, 'Лит.', lit_options
|
159
|
+
|
160
|
+
if attribute = section[:attribute]
|
161
|
+
atr_val = pdf.get_attribute(attribute.id2name)
|
162
|
+
if Array === atr_val
|
163
|
+
a_pos = [ps[0], top]
|
164
|
+
atr_val.each { |val|
|
165
|
+
a_options = {:w => step, :h => h2, :pos => a_pos.dup}
|
166
|
+
AttributeDrawer.call pdf, val, a_options
|
167
|
+
a_pos[0] = a_pos[0] + step
|
168
|
+
}
|
169
|
+
end
|
170
|
+
end
|
171
|
+
}
|
172
|
+
|
173
|
+
Section7Drawer_fpt = lambda { |pdf, section, options|
|
174
|
+
options[:no_attribute] = true
|
175
|
+
DefaultDrawer.call(pdf, section, options)
|
176
|
+
|
177
|
+
ps = section[:pos].dup
|
178
|
+
w = section[:w]
|
179
|
+
h = section[:h]
|
180
|
+
head_h = pdf.mm(5)
|
181
|
+
top = ps[1] - head_h
|
182
|
+
h2 = h - head_h
|
183
|
+
|
184
|
+
pdf.stroke do
|
185
|
+
pdf.polygon [ps[0], top], [ps[0]+w, top]
|
186
|
+
end
|
187
|
+
|
188
|
+
lit_options = {:w => w, :h => head_h, :pos => section[:pos].dup}
|
189
|
+
AttributeDrawer.call pdf, 'Лист', lit_options
|
190
|
+
|
191
|
+
if attribute = section[:attribute]
|
192
|
+
atr_val = pdf.get_attribute(attribute.id2name)
|
193
|
+
a_pos = [ps[0], top]
|
194
|
+
a_options = {:w => w, :h => h2, :pos => a_pos.dup}
|
195
|
+
AttributeDrawer.call pdf, atr_val, a_options
|
196
|
+
end
|
197
|
+
}
|
198
|
+
|
199
|
+
Section8Drawer_fpt = lambda { |pdf, section, options|
|
200
|
+
options[:no_attribute] = true
|
201
|
+
DefaultDrawer.call(pdf, section, options)
|
202
|
+
|
203
|
+
ps = section[:pos].dup
|
204
|
+
w = section[:w]
|
205
|
+
h = section[:h]
|
206
|
+
head_h = pdf.mm(5)
|
207
|
+
top = ps[1] - head_h
|
208
|
+
h2 = h - head_h
|
209
|
+
|
210
|
+
pdf.stroke do
|
211
|
+
pdf.polygon [ps[0], top], [ps[0]+w, top]
|
212
|
+
end
|
213
|
+
|
214
|
+
lit_options = {:w => w, :h => head_h, :pos => section[:pos].dup}
|
215
|
+
AttributeDrawer.call pdf, 'Листов', lit_options
|
216
|
+
|
217
|
+
if attribute = section[:attribute]
|
218
|
+
atr_val = pdf.get_attribute(attribute.id2name)
|
219
|
+
a_pos = [ps[0], top]
|
220
|
+
a_options = {:w => w, :h => h2, :pos => a_pos.dup}
|
221
|
+
AttributeDrawer.call pdf, atr_val, a_options
|
222
|
+
end
|
223
|
+
}
|
224
|
+
|
225
|
+
Section7Drawer = lambda { |pdf, section, options|
|
226
|
+
options[:no_attribute] = true
|
227
|
+
DefaultDrawer.call(pdf, section, options)
|
228
|
+
|
229
|
+
ps = section[:pos].dup
|
230
|
+
w = section[:w]
|
231
|
+
h = section[:h]
|
232
|
+
head_h = pdf.mm(7)
|
233
|
+
top = ps[1] - head_h
|
234
|
+
h2 = h - head_h
|
235
|
+
|
236
|
+
pdf.stroke do
|
237
|
+
pdf.polygon [ps[0], top], [ps[0]+w, top]
|
238
|
+
end
|
239
|
+
|
240
|
+
lit_options = {:w => w, :h => head_h, :pos => section[:pos].dup}
|
241
|
+
AttributeDrawer.call pdf, 'Лист', lit_options
|
242
|
+
|
243
|
+
if attribute = section[:attribute]
|
244
|
+
atr_val = pdf.get_attribute(attribute.id2name)
|
245
|
+
a_pos = [ps[0], top]
|
246
|
+
a_options = {:w => w, :h => h2, :pos => a_pos.dup}
|
247
|
+
AttributeDrawer.call pdf, atr_val, a_options
|
248
|
+
end
|
249
|
+
}
|
250
|
+
|
251
|
+
MultiLineSectionDrawer = lambda { |pdf, section, options|
|
252
|
+
options[:no_attribute] = true
|
253
|
+
DefaultDrawer.call(pdf, section, options)
|
254
|
+
|
255
|
+
if m_fields = options[:m_fields]
|
256
|
+
f_pos = section[:pos].dup
|
257
|
+
w = section[:w]
|
258
|
+
|
259
|
+
f_s = options[:font_size]
|
260
|
+
f_s = pdf.mm(f_s) if f_s
|
261
|
+
|
262
|
+
m_fields.each { |field|
|
263
|
+
|
264
|
+
f_size = pdf.mm(field[:size])
|
265
|
+
|
266
|
+
text = field[:text]
|
267
|
+
if attribute = field[:attribute]
|
268
|
+
if att_value = pdf.get_attribute(attribute.id2name)
|
269
|
+
text = att_value
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
if text
|
274
|
+
a_options = {:w => w, :h => f_size, :pos => f_pos.dup, :font_size => f_s}
|
275
|
+
AttributeDrawer.call pdf, text, a_options
|
276
|
+
end
|
277
|
+
|
278
|
+
f_pos[1] -= f_size
|
279
|
+
pdf.stroke do
|
280
|
+
pdf.polygon f_pos, [f_pos[0]+w, f_pos[1]]
|
281
|
+
end
|
282
|
+
|
283
|
+
}
|
284
|
+
end
|
285
|
+
}
|
286
|
+
|
287
|
+
MultiLineVertSectionDrawer = lambda { |pdf, section, options|
|
288
|
+
options[:no_attribute] = true
|
289
|
+
DefaultDrawer.call(pdf, section, options)
|
290
|
+
|
291
|
+
if lines = options[:lines]
|
292
|
+
lines.each { |type|
|
293
|
+
case type
|
294
|
+
when :bottom
|
295
|
+
p1 = [section[:pos][0], section[:pos][1] - section[:h]]
|
296
|
+
p2 = [p1[0] + section[:w], p1[1]]
|
297
|
+
pdf.stroke do
|
298
|
+
pdf.polygon p1, p2
|
299
|
+
end
|
300
|
+
end
|
301
|
+
}
|
302
|
+
end
|
303
|
+
|
304
|
+
if m_fields = options[:m_fields]
|
305
|
+
f_pos = section[:pos].dup
|
306
|
+
h = section[:h]
|
307
|
+
|
308
|
+
f_s = options[:font_size]
|
309
|
+
f_s = pdf.mm(f_s) if f_s
|
310
|
+
|
311
|
+
m_fields.each { |field|
|
312
|
+
|
313
|
+
f_size = pdf.mm(field[:size])
|
314
|
+
|
315
|
+
text = field[:text]
|
316
|
+
if attribute = field[:attribute]
|
317
|
+
if att_value = pdf.get_attribute(attribute.id2name)
|
318
|
+
text = att_value
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
if text
|
323
|
+
a_options = {:w => f_size, :h => h, :pos => f_pos.dup, :orientation => :vertical, :font_size => f_s}
|
324
|
+
AttributeDrawer.call pdf, text, a_options
|
325
|
+
end
|
326
|
+
|
327
|
+
f_pos[0] += f_size
|
328
|
+
pdf.stroke do
|
329
|
+
pdf.polygon f_pos, [f_pos[0], f_pos[1] - h]
|
330
|
+
end
|
331
|
+
|
332
|
+
}
|
333
|
+
end
|
334
|
+
}
|
335
|
+
|
336
|
+
# class GostSection4Drawer
|
337
|
+
# def draw(section, pdf, options = {})
|
338
|
+
# GostSectionDrawer.new.draw(section, pdf, options)
|
339
|
+
|
340
|
+
# pdf.bounding_box ps, :width => w, :height => step do
|
341
|
+
# pdf.section_text "Лит."
|
342
|
+
# end
|
343
|
+
# end
|
344
|
+
# end
|
345
|
+
|
346
|
+
end
|
@@ -0,0 +1,446 @@
|
|
1
|
+
module GOST::Sections
|
2
|
+
require 'prawn/GOST/drawers'
|
3
|
+
include GOST::Drawers
|
4
|
+
# :align относительно какого края отсчитывать по умолчанию правого
|
5
|
+
# :w ширина, мм
|
6
|
+
# :h высота, мм
|
7
|
+
# :pos [x, y] - позиция левого верхнего угла в мм
|
8
|
+
# :drawer специфический отрисовщик, по умолчанию GostSectionDrawer
|
9
|
+
# :dep зависимость от другой секции
|
10
|
+
# :noreq необязательная секция
|
11
|
+
# :drawer_opt опции для отрисовщика
|
12
|
+
|
13
|
+
GOST_SECTIONS_19_25 = {
|
14
|
+
:section23 => {:w => 12, :h => 35, :pos => [-12, 145], :align => :left,
|
15
|
+
:drawer => MultiLineVertSectionDrawer,
|
16
|
+
:drawer_opt => {
|
17
|
+
:m_fields => [
|
18
|
+
{ :size=>5, :text => 'Подп. и дата' },
|
19
|
+
{ :size=>7 }
|
20
|
+
]
|
21
|
+
}
|
22
|
+
},
|
23
|
+
|
24
|
+
:section22 => {:w => 12, :h => 25, :pos => [-12, 110], :align => :left,
|
25
|
+
:drawer => MultiLineVertSectionDrawer,
|
26
|
+
:drawer_opt => {
|
27
|
+
:m_fields => [
|
28
|
+
{ :size=>5, :text => 'Инв. № дубл.' },
|
29
|
+
{ :size=>7 }
|
30
|
+
]
|
31
|
+
}
|
32
|
+
},
|
33
|
+
|
34
|
+
:section21 => {:w => 12, :h => 25, :pos => [-12, 85], :align => :left,
|
35
|
+
:drawer => MultiLineVertSectionDrawer,
|
36
|
+
:drawer_opt => {
|
37
|
+
:m_fields => [
|
38
|
+
{ :size=>5, :text => 'Взам. инв. №' },
|
39
|
+
{ :size=>7 }
|
40
|
+
]
|
41
|
+
}
|
42
|
+
},
|
43
|
+
|
44
|
+
:section20 => {:w => 12, :h => 35, :pos => [-12, 60], :align => :left,
|
45
|
+
:drawer => MultiLineVertSectionDrawer,
|
46
|
+
:drawer_opt => {
|
47
|
+
:m_fields => [
|
48
|
+
{ :size=>5, :text => 'Подп. и дата' },
|
49
|
+
{ :size=>7 }
|
50
|
+
]
|
51
|
+
}
|
52
|
+
},
|
53
|
+
|
54
|
+
:section19 => {:w => 12, :h => 25, :pos => [-12, 25], :align => :left,
|
55
|
+
:drawer => MultiLineVertSectionDrawer,
|
56
|
+
:drawer_opt => {
|
57
|
+
:m_fields => [
|
58
|
+
{ :size=>5, :text => 'Инв. № подл.' },
|
59
|
+
{ :size=>7 }
|
60
|
+
],
|
61
|
+
:lines => [:bottom]
|
62
|
+
}
|
63
|
+
},
|
64
|
+
|
65
|
+
:section25 => {:w => 12, :h => 60, :pos => [-12, 287], :align => :left,
|
66
|
+
:drawer => MultiLineVertSectionDrawer,
|
67
|
+
:draw_request => true,
|
68
|
+
:drawer_opt => {
|
69
|
+
:m_fields => [
|
70
|
+
{ :size=>5, :text => 'Перв. примен.' },
|
71
|
+
{ :size=>7 }
|
72
|
+
]
|
73
|
+
}
|
74
|
+
},
|
75
|
+
|
76
|
+
:section24 => {:w => 12, :h => 60, :pos => [-12, 227], :align => :left,
|
77
|
+
:drawer => MultiLineVertSectionDrawer,
|
78
|
+
:draw_request => true,
|
79
|
+
:drawer_opt => {
|
80
|
+
:m_fields => [
|
81
|
+
{ :size=>5, :text => 'Справ. №' },
|
82
|
+
{ :size=>7 }
|
83
|
+
],
|
84
|
+
:lines => [:bottom]
|
85
|
+
}
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
|
90
|
+
GOST_SECTIONS_FIRST_PAGE = {
|
91
|
+
:section1 => {:w=> 70, :h => 25, :pos => [-120, 40], :attribute => :attribute1 },
|
92
|
+
:section2 => {:w=> 120, :h => 15, :pos => [-120, 55], :attribute => :attribute2 },
|
93
|
+
:section3 => {:w=> 70, :h => 15, :pos => [-120, 15]},
|
94
|
+
:section4 => {:w=> 15, :h => 20, :pos => [-50, 40], :attribute => :attribute19 },
|
95
|
+
:section5 => {:w=> 17, :h => 20, :pos => [-35, 40]},
|
96
|
+
:section6 => {:w=> 18, :h => 20, :pos => [-18, 40]},
|
97
|
+
:section7 => {:w=> 20, :h => 5, :pos => [-50, 20]},
|
98
|
+
:section8 => {:w=> 30, :h => 5, :pos => [-30, 20], :attribute => :attribute7 },
|
99
|
+
:section9 => {:w=> 50, :h=>15, :pos => [-50, 15], :attribute => :attribute8 },
|
100
|
+
:section10 => {},
|
101
|
+
:section11 => {},
|
102
|
+
:section12 => {},
|
103
|
+
:section13 => {},
|
104
|
+
:section14 => {},
|
105
|
+
:section15 => {},
|
106
|
+
:section16 => {},
|
107
|
+
:section17 => {},
|
108
|
+
:section18 => {},
|
109
|
+
:section26 => {}
|
110
|
+
}
|
111
|
+
|
112
|
+
GOST_SECTIONS_FIRST_PAGE.update(GOST_SECTIONS_19_25)
|
113
|
+
|
114
|
+
GOST_SECTIONS_FIRST_TEXT_PAGE = {
|
115
|
+
:section1 => {:w=> 70, :h => 25, :pos => [-120, 25], :attribute => :attribute1 },
|
116
|
+
:section2 => {:w=> 120, :h => 15, :pos => [-120, 40], :attribute => :attribute2 },
|
117
|
+
:section4 => {:w=> 15, :h => 10, :pos => [-50, 25], :drawer => Section4Drawer, :attribute => :attribute19 },
|
118
|
+
:section7 => {:w=> 15, :h => 10, :pos => [-35, 25], :drawer => Section7Drawer_fpt, :attribute => :attribute6 },
|
119
|
+
:section8 => {:w=> 20, :h => 10, :pos => [-20, 25], :drawer => Section8Drawer_fpt, :attribute => :attribute7 },
|
120
|
+
:section9 => {:w=> 50, :h=> 15, :pos => [-50, 15], :attribute => :attribute8 },
|
121
|
+
:section13 => {:w => 10, :h => 25, :pos => [-130, 25], :drawer => MultiLineSectionDrawer,
|
122
|
+
:drawer_opt => {
|
123
|
+
:m_fields => [
|
124
|
+
{ :size=>5 },
|
125
|
+
{ :size=>5 },
|
126
|
+
{ :size=>5 },
|
127
|
+
{ :size=>5 },
|
128
|
+
{ :size=>5 }
|
129
|
+
]
|
130
|
+
}
|
131
|
+
},
|
132
|
+
|
133
|
+
:section12 => {:w => 15, :h => 25, :pos => [-145, 25], :drawer => MultiLineSectionDrawer,
|
134
|
+
:drawer_opt => {
|
135
|
+
:m_fields => [
|
136
|
+
{ :size=>5 },
|
137
|
+
{ :size=>5 },
|
138
|
+
{ :size=>5 },
|
139
|
+
{ :size=>5 },
|
140
|
+
{ :size=>5 }
|
141
|
+
]
|
142
|
+
}
|
143
|
+
},
|
144
|
+
|
145
|
+
:section11 => {:w => 23, :h => 25, :pos => [-168, 25], :drawer => MultiLineSectionDrawer,
|
146
|
+
:drawer_opt => {
|
147
|
+
:m_fields => [
|
148
|
+
{ :size=>5, :attribute => :attribute11_1 },
|
149
|
+
{ :size=>5, :attribute => :attribute11_2 },
|
150
|
+
{ :size=>5, :attribute => :attribute11_3 },
|
151
|
+
{ :size=>5, :attribute => :attribute11_4 },
|
152
|
+
{ :size=>5, :attribute => :attribute11_5 }
|
153
|
+
]
|
154
|
+
}
|
155
|
+
},
|
156
|
+
|
157
|
+
:section10 => {:w => 17, :h => 25, :pos => [-185, 25], :drawer => MultiLineSectionDrawer,
|
158
|
+
:drawer_opt => {
|
159
|
+
:m_fields => [
|
160
|
+
{ :size=>5, :text => 'Разраб.' },
|
161
|
+
{ :size=>5, :text => 'Пров.' },
|
162
|
+
{ :size=>5 },
|
163
|
+
{ :size=>5, :text => 'Н.контр.' },
|
164
|
+
{ :size=>5, :text => 'Утв.' }
|
165
|
+
]
|
166
|
+
}
|
167
|
+
},
|
168
|
+
|
169
|
+
:section18 => {:w => 10, :h => 15, :pos => [-130, 40], :drawer => MultiLineSectionDrawer,
|
170
|
+
:drawer_opt => {
|
171
|
+
:m_fields => [
|
172
|
+
{ :size=>5 },
|
173
|
+
{ :size=>5 },
|
174
|
+
{ :size=>5, :text => 'Дата' }
|
175
|
+
]
|
176
|
+
}
|
177
|
+
},
|
178
|
+
|
179
|
+
:section17 => {:w => 15, :h => 15, :pos => [-145, 40], :drawer => MultiLineSectionDrawer,
|
180
|
+
:drawer_opt => {
|
181
|
+
:m_fields => [
|
182
|
+
{ :size=>5 },
|
183
|
+
{ :size=>5 },
|
184
|
+
{ :size=>5, :text => 'Подп.' }
|
185
|
+
]
|
186
|
+
}
|
187
|
+
},
|
188
|
+
|
189
|
+
:section16 => {:w => 23, :h => 15, :pos => [-168, 40], :drawer => MultiLineSectionDrawer,
|
190
|
+
:drawer_opt => {
|
191
|
+
:m_fields => [
|
192
|
+
{ :size=>5 },
|
193
|
+
{ :size=>5 },
|
194
|
+
{ :size=>5, :text => '№ докум.' }
|
195
|
+
]
|
196
|
+
}
|
197
|
+
},
|
198
|
+
|
199
|
+
:section15 => {:w => 10, :h => 15, :pos => [-178, 40], :drawer => MultiLineSectionDrawer,
|
200
|
+
:drawer_opt => {
|
201
|
+
:m_fields => [
|
202
|
+
{ :size=>5 },
|
203
|
+
{ :size=>5, :attribute => :attribute6 },
|
204
|
+
{ :size=>5, :text => 'Лист' }
|
205
|
+
]
|
206
|
+
}
|
207
|
+
},
|
208
|
+
|
209
|
+
:section14 => {:w => 7, :h => 15, :pos => [-185, 40], :drawer => MultiLineSectionDrawer,
|
210
|
+
:drawer_opt => {
|
211
|
+
:m_fields => [
|
212
|
+
{ :size=>5 },
|
213
|
+
{ :size=>5 },
|
214
|
+
{ :size=>5, :text => 'Изм.' }
|
215
|
+
]
|
216
|
+
}
|
217
|
+
}
|
218
|
+
}
|
219
|
+
|
220
|
+
GOST_SECTIONS_FIRST_TEXT_PAGE.update(GOST_SECTIONS_19_25)
|
221
|
+
|
222
|
+
GOST_SECTIONS_EVEN_PAGE = {
|
223
|
+
:section2 => {:w=> 110, :h => 15, :pos => [10, 15], :attribute => :attribute2, :align => :left },
|
224
|
+
:section7 => {:w=> 10, :h => 15, :pos => [0, 15], :drawer => Section7Drawer, :attribute => :attribute6, :align => :left },
|
225
|
+
|
226
|
+
:section18 => {:w => 10, :h => 15, :pos => [175, 15], :drawer => MultiLineSectionDrawer, :align => :left,
|
227
|
+
:drawer_opt => {
|
228
|
+
:m_fields => [
|
229
|
+
{ :size=>5 },
|
230
|
+
{ :size=>5 },
|
231
|
+
{ :size=>5, :text => 'Дата' }
|
232
|
+
]
|
233
|
+
}
|
234
|
+
},
|
235
|
+
|
236
|
+
:section17 => {:w => 15, :h => 15, :pos => [160, 15], :drawer => MultiLineSectionDrawer, :align => :left,
|
237
|
+
:drawer_opt => {
|
238
|
+
:m_fields => [
|
239
|
+
{ :size=>5 },
|
240
|
+
{ :size=>5 },
|
241
|
+
{ :size=>5, :text => 'Подп.' }
|
242
|
+
]
|
243
|
+
}
|
244
|
+
},
|
245
|
+
|
246
|
+
:section16 => {:w => 23, :h => 15, :pos => [137, 15], :drawer => MultiLineSectionDrawer, :align => :left,
|
247
|
+
:drawer_opt => {
|
248
|
+
:m_fields => [
|
249
|
+
{ :size=>5 },
|
250
|
+
{ :size=>5 },
|
251
|
+
{ :size=>5, :text => '№ докум.' }
|
252
|
+
]
|
253
|
+
}
|
254
|
+
},
|
255
|
+
|
256
|
+
:section15 => {:w => 10, :h => 15, :pos => [127, 15], :drawer => MultiLineSectionDrawer, :align => :left,
|
257
|
+
:drawer_opt => {
|
258
|
+
:m_fields => [
|
259
|
+
{ :size=>5 },
|
260
|
+
{ :size=>5 },
|
261
|
+
{ :size=>5, :text => 'Лист' }
|
262
|
+
]
|
263
|
+
}
|
264
|
+
},
|
265
|
+
|
266
|
+
:section14 => {:w => 7, :h => 15, :pos => [120, 15], :drawer => MultiLineSectionDrawer, :align => :left,
|
267
|
+
:drawer_opt => {
|
268
|
+
:m_fields => [
|
269
|
+
{ :size=>5 },
|
270
|
+
{ :size=>5 },
|
271
|
+
{ :size=>5, :text => 'Изм.' }
|
272
|
+
]
|
273
|
+
}
|
274
|
+
}
|
275
|
+
}
|
276
|
+
|
277
|
+
GOST_SECTIONS_NORMAL_PAGE = {
|
278
|
+
:section2 => {:w=> 110, :h => 15, :pos => [-120, 15], :attribute => :attribute2 },
|
279
|
+
:section7 => {:w=> 10, :h => 15, :pos => [-10, 15], :drawer => Section7Drawer, :attribute => :attribute6 },
|
280
|
+
|
281
|
+
:section18 => {:w => 10, :h => 15, :pos => [-130, 15], :drawer => MultiLineSectionDrawer,
|
282
|
+
:drawer_opt => {
|
283
|
+
:m_fields => [
|
284
|
+
{ :size=>5 },
|
285
|
+
{ :size=>5 },
|
286
|
+
{ :size=>5, :text => 'Дата' }
|
287
|
+
]
|
288
|
+
}
|
289
|
+
},
|
290
|
+
|
291
|
+
:section17 => {:w => 15, :h => 15, :pos => [-145, 15], :drawer => MultiLineSectionDrawer,
|
292
|
+
:drawer_opt => {
|
293
|
+
:m_fields => [
|
294
|
+
{ :size=>5 },
|
295
|
+
{ :size=>5 },
|
296
|
+
{ :size=>5, :text => 'Подп.' }
|
297
|
+
]
|
298
|
+
}
|
299
|
+
},
|
300
|
+
|
301
|
+
:section16 => {:w => 23, :h => 15, :pos => [-168, 15], :drawer => MultiLineSectionDrawer,
|
302
|
+
:drawer_opt => {
|
303
|
+
:m_fields => [
|
304
|
+
{ :size=>5 },
|
305
|
+
{ :size=>5 },
|
306
|
+
{ :size=>5, :text => '№ докум.' }
|
307
|
+
]
|
308
|
+
}
|
309
|
+
},
|
310
|
+
|
311
|
+
:section15 => {:w => 10, :h => 15, :pos => [-178, 15], :drawer => MultiLineSectionDrawer,
|
312
|
+
:drawer_opt => {
|
313
|
+
:m_fields => [
|
314
|
+
{ :size=>5 },
|
315
|
+
{ :size=>5 },
|
316
|
+
{ :size=>5, :text => 'Лист' }
|
317
|
+
]
|
318
|
+
}
|
319
|
+
},
|
320
|
+
|
321
|
+
:section14 => {:w => 7, :h => 15, :pos => [-185, 15], :drawer => MultiLineSectionDrawer,
|
322
|
+
:drawer_opt => {
|
323
|
+
:m_fields => [
|
324
|
+
{ :size=>5 },
|
325
|
+
{ :size=>5 },
|
326
|
+
{ :size=>5, :text => 'Изм.' }
|
327
|
+
]
|
328
|
+
}
|
329
|
+
}
|
330
|
+
}
|
331
|
+
|
332
|
+
GOST_SECTIONS_NORMAL_PAGE.update(GOST_SECTIONS_19_25)
|
333
|
+
|
334
|
+
GOST_SECTIONS_TITLE_PAGE = { }
|
335
|
+
GOST_SECTIONS_TITLE_PAGE.update(GOST_SECTIONS_19_25)
|
336
|
+
|
337
|
+
GOST_ADA_SPECIFICATION = {
|
338
|
+
|
339
|
+
:zone => {:w => 8, :h => 15, :pos => [0, 0], :align => :left, :valign => :top,
|
340
|
+
:drawer => MultiLineVertSectionDrawer,
|
341
|
+
:drawer_opt => {
|
342
|
+
:font_size => 5,
|
343
|
+
:lines => [:bottom],
|
344
|
+
:m_fields => [
|
345
|
+
{ :size=>8, :text => 'Зона' }
|
346
|
+
]
|
347
|
+
}
|
348
|
+
},
|
349
|
+
|
350
|
+
:poz_oboz => {:w => 20, :h => 15, :pos => [8, 0], :align => :left, :valign => :top,
|
351
|
+
:drawer_opt => {
|
352
|
+
:font_size => 5,
|
353
|
+
:lines => [:bottom]
|
354
|
+
},
|
355
|
+
:text => ['Поз.', 'обозна-', 'чение']
|
356
|
+
},
|
357
|
+
|
358
|
+
:name => {:w => 110, :h => 15, :pos => [28, 0], :align => :left, :valign => :top,
|
359
|
+
:drawer_opt => {
|
360
|
+
:font_size => 5,
|
361
|
+
:lines => [:bottom]
|
362
|
+
},
|
363
|
+
:text => 'Наименование'
|
364
|
+
},
|
365
|
+
|
366
|
+
:count => {:w => 10, :h => 15, :pos => [138, 0], :align => :left, :valign => :top,
|
367
|
+
:drawer_opt => {
|
368
|
+
:font_size => 5,
|
369
|
+
:lines => [:bottom]
|
370
|
+
},
|
371
|
+
:text => 'Кол'
|
372
|
+
},
|
373
|
+
|
374
|
+
:note => {:w => 37, :h => 15, :pos => [148, 0], :align => :left, :valign => :top,
|
375
|
+
:drawer_opt => {
|
376
|
+
:font_size => 5,
|
377
|
+
:lines => [:bottom]
|
378
|
+
},
|
379
|
+
:text => 'Примечание'
|
380
|
+
},
|
381
|
+
}
|
382
|
+
|
383
|
+
GOST_CHANGE_LIST_SPECIFICATION = {
|
384
|
+
|
385
|
+
:header => {:w => 185, :h => 15, :pos => [0, 0], :align => :left, :valign => :top,
|
386
|
+
:drawer => MultiLineSectionDrawer,
|
387
|
+
:drawer_opt => {
|
388
|
+
:font_size => 8,
|
389
|
+
:lines => [:bottom],
|
390
|
+
:m_fields => [
|
391
|
+
{ :size=>15, :text => 'ЛИСТ РЕГИСТРАЦИИ ИЗМЕНЕНИЙ' }
|
392
|
+
]
|
393
|
+
}
|
394
|
+
},
|
395
|
+
|
396
|
+
:s1 => {:w => 10, :h => 35, :pos => [0, -15], :align => :left, :valign => :top,
|
397
|
+
:drawer => MultiLineVertSectionDrawer,
|
398
|
+
:drawer_opt => {
|
399
|
+
:font_size => 6,
|
400
|
+
:lines => [:bottom],
|
401
|
+
:m_fields => [
|
402
|
+
{ :size=>10, :text => 'Изм.' }
|
403
|
+
]
|
404
|
+
}
|
405
|
+
},
|
406
|
+
:s2 => {:w => 80, :h => 10, :pos => [10, -15], :align => :left, :valign => :top,
|
407
|
+
:drawer => MultiLineSectionDrawer,
|
408
|
+
:drawer_opt => {
|
409
|
+
:font_size => 6,
|
410
|
+
#:lines => [:bottom],
|
411
|
+
:m_fields => [
|
412
|
+
{ :size=>10, :text => 'Номера листов (страниц)' }
|
413
|
+
]
|
414
|
+
}
|
415
|
+
},
|
416
|
+
|
417
|
+
:s3 => {:w => 80, :h => 25, :pos => [10, -25], :align => :left, :valign => :top,
|
418
|
+
:drawer => MultiLineVertSectionDrawer,
|
419
|
+
:drawer_opt => {
|
420
|
+
:font_size => 6,
|
421
|
+
:lines => [:bottom],
|
422
|
+
:m_fields => [
|
423
|
+
{ :size=>20, :text => ['изме-','ненных'] },
|
424
|
+
{ :size=>20, :text => ['заме','ненных'] },
|
425
|
+
{ :size=>20, :text => ['новых'] },
|
426
|
+
{ :size=>20, :text => ['аннулир','ованных'] }
|
427
|
+
]
|
428
|
+
}
|
429
|
+
},
|
430
|
+
|
431
|
+
:s4 => {:w => 95, :h => 35, :pos => [90, -15], :align => :left, :valign => :top,
|
432
|
+
:drawer => MultiLineVertSectionDrawer,
|
433
|
+
:drawer_opt => {
|
434
|
+
:font_size => 6,
|
435
|
+
:lines => [:bottom],
|
436
|
+
:m_fields => [
|
437
|
+
{ :size=>20, :text => ['Всего', 'листов', '(стра-', 'ниц)', 'в докум.'] },
|
438
|
+
{ :size=>20, :text => ['Номер', 'докум.'] },
|
439
|
+
{ :size=>25, :text => ['Входящий', '№ сопро-', 'водитель-', 'ного', 'докум.', 'и дата'] },
|
440
|
+
{ :size=>15, :text => ['Под-', 'пись'] },
|
441
|
+
{ :size=>15, :text => ['Дата'] },
|
442
|
+
]
|
443
|
+
}
|
444
|
+
},
|
445
|
+
}
|
446
|
+
end
|
data/lib/prawn/gost.rb
ADDED
@@ -0,0 +1,279 @@
|
|
1
|
+
module GOST
|
2
|
+
|
3
|
+
require 'prawn/GOST/sections'
|
4
|
+
include Sections
|
5
|
+
|
6
|
+
def gost_set_font(fnt)
|
7
|
+
puts "FONTTTT #{fnt}"
|
8
|
+
@gost_font = fnt
|
9
|
+
end
|
10
|
+
|
11
|
+
def GOST.mm(x)
|
12
|
+
return x * 72.0 / 25.4
|
13
|
+
end
|
14
|
+
#mm to pt
|
15
|
+
def mm(x)
|
16
|
+
return GOST::mm(x)
|
17
|
+
end
|
18
|
+
|
19
|
+
def gost_page(options = {}, &block)
|
20
|
+
|
21
|
+
@gost_in_page_constructor = true
|
22
|
+
|
23
|
+
@gost_cur_sections = GOST_SECTIONS_NORMAL_PAGE
|
24
|
+
@gost_cur_attributes = {}
|
25
|
+
|
26
|
+
options[:left_margin]= mm 20
|
27
|
+
options[:right_margin]= mm 5
|
28
|
+
|
29
|
+
options[:top_margin]= mm 5
|
30
|
+
options[:bottom_margin]= mm 5
|
31
|
+
|
32
|
+
page_type = options[:gost_page_type]
|
33
|
+
page_type = :auto if ! page_type
|
34
|
+
|
35
|
+
if page_type == :auto
|
36
|
+
if page_count == 0
|
37
|
+
page_type = :first_text
|
38
|
+
else
|
39
|
+
if @gost_duplex
|
40
|
+
page_type = (page_count % 2) == 0 ? :normal : :even
|
41
|
+
else
|
42
|
+
page_type = :normal
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
case page_type
|
49
|
+
when :even
|
50
|
+
options[:left_margin]= mm 5
|
51
|
+
options[:right_margin]= mm 20
|
52
|
+
options[:top_margin]= mm 5
|
53
|
+
options[:bottom_margin]= mm 5
|
54
|
+
@gost_cur_sections = GOST_SECTIONS_EVEN_PAGE
|
55
|
+
when :first_text
|
56
|
+
@gost_cur_sections = GOST_SECTIONS_FIRST_TEXT_PAGE
|
57
|
+
when :first
|
58
|
+
@gost_cur_sections = GOST_SECTIONS_FIRST_PAGE
|
59
|
+
when :title
|
60
|
+
@gost_cur_sections = GOST_SECTIONS_TITLE_PAGE
|
61
|
+
else
|
62
|
+
@gost_cur_sections = GOST_SECTIONS_NORMAL_PAGE
|
63
|
+
end
|
64
|
+
|
65
|
+
start_new_page(options)
|
66
|
+
stroke do
|
67
|
+
polygon bounds.bottom_left, bounds.bottom_right, bounds.top_right, bounds.top_left, bounds.bottom_left
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
rect = gost_calc_bounds(@gost_cur_sections)
|
72
|
+
pos = [rect[:left], rect[:top]]
|
73
|
+
w = rect[:right] - rect[:left]
|
74
|
+
h = rect[:top] - rect[:bottom]
|
75
|
+
|
76
|
+
|
77
|
+
font(@gost_font.dup) if @gost_font
|
78
|
+
|
79
|
+
bounding_box(pos, :width => w, :height => h, &block)
|
80
|
+
|
81
|
+
font(@gost_font) if @gost_font
|
82
|
+
gost_draw_sections(@gost_cur_sections)
|
83
|
+
|
84
|
+
@gost_in_page_constructor = false
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
def gost_component_list_page(data = [], &block)
|
89
|
+
|
90
|
+
gost_page(:size => "A4", :layout => :portrait, :gost_page_type => :auto) {
|
91
|
+
gost_draw_sections(GOST_ADA_SPECIFICATION)
|
92
|
+
l_w = line_width
|
93
|
+
line_width mm(0.2)
|
94
|
+
pos = bounds.top_left
|
95
|
+
bottom = bounds.bottom + mm(8)
|
96
|
+
w = bounds.width
|
97
|
+
pos[1] -= mm(15)
|
98
|
+
while pos[1] > bottom
|
99
|
+
stroke do
|
100
|
+
line pos, [pos[0] + w, pos[1]]
|
101
|
+
end
|
102
|
+
pos[1] -= mm(8)
|
103
|
+
end
|
104
|
+
|
105
|
+
line_width l_w
|
106
|
+
|
107
|
+
x_coord = [mm(8), mm(28), mm(138), mm(148)]
|
108
|
+
|
109
|
+
stroke do
|
110
|
+
x_coord.each { |x|
|
111
|
+
p1 = [bounds.left + x, bounds.top - mm(15)]
|
112
|
+
p2 = [p1[0], bounds.bottom]
|
113
|
+
line p1, p2
|
114
|
+
}
|
115
|
end
|
116
|
+
|
117
|
+
yield self
|
118
|
+
}
|
119
|
+
end
|
120
|
+
|
121
|
+
def gost_change_list_page(data = [], &block)
|
122
|
+
|
123
|
+
gost_page(:size => "A4", :layout => :portrait, :gost_page_type => :normal) {
|
124
|
+
gost_draw_sections(GOST_CHANGE_LIST_SPECIFICATION)
|
125
|
+
|
126
|
+
l_w = line_width
|
127
|
+
line_width mm(0.2)
|
128
|
+
pos = bounds.top_left
|
129
|
+
bottom = bounds.bottom + mm(8)
|
130
|
+
w = bounds.width
|
131
|
+
pos[1] -= mm(15+35)
|
132
|
+
while pos[1] > bottom
|
133
|
+
stroke do
|
134
|
+
line pos, [pos[0] + w, pos[1]]
|
135
|
+
end
|
136
|
+
pos[1] -= mm(8.9)
|
137
|
+
end
|
138
|
+
|
139
|
+
line_width l_w
|
140
|
+
|
141
|
+
x_coord = [mm(10), mm(30), mm(50), mm(70), mm(90), mm(110), mm(130), mm(155), mm(170)]
|
142
|
+
|
143
|
+
stroke do
|
144
|
+
x_coord.each { |x|
|
145
|
+
p1 = [bounds.left + x, bounds.top - mm(15+35)]
|
146
|
+
p2 = [p1[0], bounds.bottom]
|
147
|
+
line p1, p2
|
148
|
+
}
|
149
|
+
end
|
150
|
+
|
151
|
+
yield self
|
152
|
+
}
|
153
|
+
end
|
154
|
+
|
155
|
+
|
156
|
+
alias prawn_method_missing method_missing;
|
157
|
+
|
158
|
+
def gost_initialize
|
159
|
+
@gost_global_attributes = {}
|
160
|
+
@gost_cur_attributes = {}
|
161
|
+
@gost_duplex = false
|
162
|
+
@gost_in_page_constructor = false
|
163
|
+
end
|
164
|
+
|
165
|
+
def method_missing(sym, *args, &block)
|
166
|
+
if mh = /attribute\d+(?:_\d+)?/.match(sym.id2name)
|
167
|
+
gost_attribute(sym, *args)
|
168
|
+
else
|
169
|
+
prawn_method_missing sym, *args, &block
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def gost_duplex
|
174
|
+
@gost_duplex = true
|
175
|
+
end
|
176
|
+
|
177
|
+
def get_attribute(name)
|
178
|
+
if @gost_in_page_constructor && (val = @gost_cur_attributes[name])
|
179
|
+
return val
|
180
|
+
else
|
181
|
+
return @gost_global_attributes[name]
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
protected
|
186
|
+
def gost_attribute(sym, *args)
|
187
|
+
if args.empty?
|
188
|
+
return get_attribute(sym.id2name)
|
189
|
+
else
|
190
|
+
attributes = @gost_in_page_constructor ? @gost_cur_attributes : @gost_global_attributes
|
191
|
+
attributes[sym.id2name] = args.size == 1 ? args[0] : args
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def sec_descr2pt(section)
|
196
|
+
sec_descr = section.dup
|
197
|
+
pos = sec_descr[:pos].dup
|
198
|
+
pos[0] = mm(pos[0])
|
199
|
+
pos[1] = mm(pos[1])
|
200
|
+
|
201
|
+
if section[:align] == :left
|
202
|
+
pos[0] = bounds.left + pos[0]
|
203
|
+
else
|
204
|
+
pos[0] = bounds.right + pos[0]
|
205
|
+
end
|
206
|
+
|
207
|
+
if section[:valign] == :top
|
208
|
+
pos[1] = bounds.top + pos[1]
|
209
|
+
else
|
210
|
+
pos[1] = bounds.bottom + pos[1]
|
211
|
+
end
|
212
|
+
|
213
|
+
sec_descr[:pos] = pos
|
214
|
+
sec_descr[:w] = mm(sec_descr[:w])
|
215
|
+
sec_descr[:h] = mm(sec_descr[:h])
|
216
|
+
|
217
|
+
if f_s = sec_descr[:font_size]
|
218
|
+
sec_descr[:font_size] = mm(f_s)
|
219
|
+
end
|
220
|
+
|
221
|
+
return sec_descr
|
222
|
+
end
|
223
|
+
|
224
|
+
def gost_draw_sections(sections)
|
225
|
+
|
226
|
+
l_w = line_width
|
227
|
+
line_width mm(0.5)
|
228
|
+
|
229
|
+
sections.each { |sec_code, section|
|
230
|
+
if Hash === section
|
231
|
+
drawer_proc = section[:drawer] ? section[:drawer] : DefaultDrawer
|
232
|
+
options = {}
|
233
|
+
|
234
|
+
if opts = section[:drawer_opt]
|
235
|
+
options.update opts
|
236
|
+
end
|
237
|
+
|
238
|
+
options[:align] = section[:pos][0] >= 0 ? :left : :right
|
239
|
+
|
240
|
+
drawer_proc.call(self, sec_descr2pt(section), options) unless section[:draw_request]
|
241
|
+
#drawer = drawer_class.new()
|
242
|
+
#drawer.draw(section.dup, self) if section && !section.empty?
|
243
|
+
end
|
244
|
+
}
|
245
|
+
|
246
|
+
line_width l_w
|
247
|
+
end
|
248
|
+
|
249
|
+
|
250
|
+
|
251
|
+
def gost_calc_bounds(sections)
|
252
|
+
left = bounds.left
|
253
|
+
right = bounds.right
|
254
|
+
top = bounds.top
|
255
|
+
bottom = bounds.bottom
|
256
|
+
|
257
|
+
sections.each { |sec_code, section|
|
258
|
+
if Hash === section
|
259
|
+
sect = sec_descr2pt(section)
|
260
|
+
|
261
|
+
posx = sect[:align] == :left ? sect[:pos][0] + sect[:w] : sect[:pos][0]
|
262
|
+
posy = sect[:valign] == :top ? sect[:pos][1] - sect[:h] : sect[:pos][1]
|
263
|
+
|
264
|
+
if (posx > left) && (posx < right) && (posy < top) && (posy > bottom)
|
265
|
+
if sect[:valign] == :top
|
266
|
+
top = posy
|
267
|
+
else
|
268
|
+
bottom = posy
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
}
|
273
|
+
return {:left => left, :right => right, :top => top, :bottom => bottom}
|
274
|
+
end
|
275
|
+
|
276
|
+
end
|
277
|
+
|
278
|
+
class Prawn::Document
|
279
|
+
include GOST
|
280
|
+
end
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gost_frames
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alexey Pavlyukov
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-09-23 00:00:00 +04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: prawn
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.4.0
|
24
|
+
version:
|
25
|
+
description:
|
26
|
+
email: lexaficus@list.ru
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README.rdoc
|
33
|
+
- LICENSE.rdoc
|
34
|
+
files:
|
35
|
+
- examples/merge
|
36
|
+
- examples/merge/merge.rb
|
37
|
+
- examples/merge/source_doc.pdf
|
38
|
+
- examples/example_helper.rb
|
39
|
+
- examples/generate_document
|
40
|
+
- examples/generate_document/generate_document.rb
|
41
|
+
- examples/generate_document/text_of_pages.txt
|
42
|
+
- lib/prawn
|
43
|
+
- lib/prawn/gost.rb
|
44
|
+
- lib/prawn/GOST
|
45
|
+
- lib/prawn/GOST/sections.rb
|
46
|
+
- lib/prawn/GOST/drawers.rb
|
47
|
+
- lib/prawn/GOST/settings.rb
|
48
|
+
- data/fonts
|
49
|
+
- data/fonts/mipgost.ttf
|
50
|
+
- Rakefile.rb
|
51
|
+
- README.rdoc
|
52
|
+
- LICENSE.rdoc
|
53
|
+
has_rdoc: false
|
54
|
+
homepage:
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options:
|
57
|
+
- --charset=utf-8
|
58
|
+
require_paths:
|
59
|
+
- lib
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: "0"
|
65
|
+
version:
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: "0"
|
71
|
+
version:
|
72
|
+
requirements: []
|
73
|
+
|
74
|
+
rubyforge_project:
|
75
|
+
rubygems_version: 1.3.1
|
76
|
+
signing_key:
|
77
|
+
specification_version: 2
|
78
|
+
summary: Library for creation page frames of Russian GOST standard.
|
79
|
+
test_files: []
|
80
|
+
|