dinbrief 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +8 -0
- data/Gemfile +4 -0
- data/README.textile +147 -0
- data/Rakefile +1 -0
- data/dinbrief.gemspec +24 -0
- data/example/example.png +0 -0
- data/example/hello.rb +53 -0
- data/example/metaminded.png +0 -0
- data/example/more_serious.rb +86 -0
- data/example/signature.png +0 -0
- data/lib/dinbrief.rb +16 -0
- data/lib/dinbrief/letter.rb +47 -0
- data/lib/dinbrief/letter/constants.rb +135 -0
- data/lib/dinbrief/letter/design_elements.rb +69 -0
- data/lib/dinbrief/letter/typeset_methods.rb +104 -0
- data/lib/dinbrief/letter_builder.rb +26 -0
- data/lib/dinbrief/version.rb +3 -0
- metadata +74 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.textile
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
h1. DIN Brief gem for prawn.
|
2
|
+
|
3
|
+
h2. Mission Objective
|
4
|
+
|
5
|
+
This gem tries to make producing letters from Ruby apps simpler. The resulting letter mostly meet the <a href="http://de.wikipedia.org/wiki/DIN_5008" target="_blank">DIN 2008</a> standard.
|
6
|
+
|
7
|
+
It is (mainly) a semantic DSL on top of <a href="http://prawn.majesticseacreature.com/" target="_blank">Prawn 1.x</a>.
|
8
|
+
|
9
|
+
The name <i>dinbrief</i> was chosen as a tribute to the <a href="http://ctan.org/tex-archive/macros/latex/contrib/dinbrief" target="_blank">dinbrief LaTeX package</a>, which it replaces in my projects.
|
10
|
+
|
11
|
+
h2. Example
|
12
|
+
|
13
|
+
To get the headers and footers right for your company, you should subclass <tt>Dinbrief::Letter</tt>:
|
14
|
+
|
15
|
+
<pre>
|
16
|
+
class MyLetter < Dinbrief::Letter
|
17
|
+
# define a header
|
18
|
+
def header
|
19
|
+
image(File.join("my_logo_.png"),
|
20
|
+
:at => [0.mm, 35.mm],
|
21
|
+
:fit => [80.mm, 22.mm]
|
22
|
+
)
|
23
|
+
text_box(%{My Company
|
24
|
+
Some Road 23
|
25
|
+
12345 Rubycity
|
26
|
+
|
27
|
+
www.my-company.com
|
28
|
+
},
|
29
|
+
:at => [105.mm, 35.mm],
|
30
|
+
:width => 85.mm,
|
31
|
+
:align => :left,
|
32
|
+
:size => 10.pt
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
# define a footer
|
37
|
+
def footer
|
38
|
+
text_box(%{My Company Ltd. – Some Road 23 – 12345 Rubycity
|
39
|
+
more infos as requred by law
|
40
|
+
},
|
41
|
+
:at => [20.mm, 12.mm],
|
42
|
+
:width => 140.mm,
|
43
|
+
:align => :center,
|
44
|
+
:size => 8.pt,
|
45
|
+
)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
</pre>
|
49
|
+
|
50
|
+
(Note: If you don't implement these functions you'll get some sample header and footer with additional information.)
|
51
|
+
|
52
|
+
Then, you can use this class to actually typeset your letters:
|
53
|
+
|
54
|
+
<pre>
|
55
|
+
MyLetter.letter('more_serious.pdf') do |db|
|
56
|
+
db.return_address 'metaminded UG – Ulmer Straße 176 – 73233 Aalen'
|
57
|
+
db.oursign "PH"
|
58
|
+
db.yoursign "DHH"
|
59
|
+
db.yourmessage "24.12.2011"
|
60
|
+
db.name "Dr. Peter Horn"
|
61
|
+
db.phone "05604 - 919937"
|
62
|
+
db.fax "05604 - 919938"
|
63
|
+
db.email "ph@metaminded.com"
|
64
|
+
db.address "David Heinemeier-Hansson\n37signals, LLC\n30 North Racine Avenue #200\nChicago, Illinois 60607\nUSA"
|
65
|
+
db.subject "Thanks a lot for giving us Rails"
|
66
|
+
db.body <<-TEXT
|
67
|
+
Dear David and all you colleagues,
|
68
|
+
|
69
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
70
|
+
|
71
|
+
...
|
72
|
+
|
73
|
+
Curabitur ullamcorper ultricies nisi. Nam eget dui.
|
74
|
+
|
75
|
+
Best Regards,
|
76
|
+
TEXT
|
77
|
+
end
|
78
|
+
</pre>
|
79
|
+
|
80
|
+
But, as always, things may be more complicated, and you may want to add fancy pdf things or generate the letter (from, e.g., an order object), so you can give a block to the body:
|
81
|
+
|
82
|
+
<pre>
|
83
|
+
MyLetter.letter('more_serious.pdf') do |db|
|
84
|
+
db.return_address 'metaminded UG – Ulmer Straße 176 – 73233 Aalen'
|
85
|
+
# ... as above ...
|
86
|
+
db.subject "Thanks a lot for giving us Rails"
|
87
|
+
db.body do |letter|
|
88
|
+
letter.text %{Dear David and all you colleagues,
|
89
|
+
|
90
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
91
|
+
|
92
|
+
To impress people, I add a useless table:
|
93
|
+
}
|
94
|
+
|
95
|
+
letter.table [["Animal", "Programming Language", "coincidence"],
|
96
|
+
["Penguin", "C", "213" ],
|
97
|
+
["Platypus", "ObjC", "143" ],
|
98
|
+
["Cat", "Ruby", "47" ],
|
99
|
+
["Dog", "Python", "23" ],
|
100
|
+
["Olm", "PHP", "876" ]
|
101
|
+
]
|
102
|
+
|
103
|
+
letter.text %{
|
104
|
+
Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum.
|
105
|
+
|
106
|
+
Curabitur ullamcorper ultricies nisi. Nam eget dui.
|
107
|
+
|
108
|
+
Best Regards,
|
109
|
+
}
|
110
|
+
|
111
|
+
letter.image("signature.png", :fit => [3.cm, 3.cm])
|
112
|
+
end
|
113
|
+
end
|
114
|
+
</pre>
|
115
|
+
|
116
|
+
The result then looks a little bit like this:
|
117
|
+
|
118
|
+
<img src="https://github.com/provideal/dinbrief/raw/master/example/example.png" />
|
119
|
+
|
120
|
+
Almost every property of an element is defined in <tt>lib/dinbrief/letter/constants.rb</tt>, and can be overridden in your subclass.
|
121
|
+
|
122
|
+
h2. Disclaimer
|
123
|
+
|
124
|
+
This is pretty much work-in-progress-without-reasonable-documentation. So if you use it, don't complain ;)
|
125
|
+
|
126
|
+
Nevertheless, bug reports and improvements are highly appreciated:
|
127
|
+
|
128
|
+
h2. Contributing to dinbrief
|
129
|
+
|
130
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
131
|
+
* Check out the <a href="https://github.com/provideal/dinbrief/issues">issue tracker</a> to make sure someone already hasn't requested it and/or contributed it
|
132
|
+
* Fork the project
|
133
|
+
* Start a feature/bugfix branch
|
134
|
+
* Commit and push until you are happy with your contribution
|
135
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
136
|
+
* Feel free to send a pull request if you think others (me, for example) would like to have your change incorporated into future versions of dinbrief.
|
137
|
+
|
138
|
+
h2. License
|
139
|
+
|
140
|
+
Copyright (c) 2011-2012 Peter Horn, <a href="http://www.metaminded.com" target="_blank">metaminded UG</a>
|
141
|
+
|
142
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
143
|
+
|
144
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
145
|
+
|
146
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
147
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/dinbrief.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "dinbrief/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "dinbrief"
|
7
|
+
s.version = Dinbrief::VERSION
|
8
|
+
s.authors = ["Peter Horn"]
|
9
|
+
s.email = ["peter.horn@provideal.net"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{DIN Letter gem for Prawn}
|
12
|
+
s.description = %q{DIN Brief gem for Prawn. Creating letters that confirm to the DIN specifications. For Ruby.}
|
13
|
+
|
14
|
+
s.rubyforge_project = "dinbrief"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
s.add_development_dependency "prawn", "1.0.0.rc1"
|
23
|
+
# s.add_runtime_dependency "rest-client"
|
24
|
+
end
|
data/example/example.png
ADDED
Binary file
|
data/example/hello.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'dinbrief'
|
4
|
+
|
5
|
+
Dinbrief.letter('hello.pdf') do |db|
|
6
|
+
db.return_address 'metaminded UG – Ulmer Straße 176 – 73233 Aalen'
|
7
|
+
db.oursign "PH"
|
8
|
+
db.yoursign "DHH"
|
9
|
+
db.yourmessage "24.12.2011"
|
10
|
+
db.name "Dr. Peter Horn"
|
11
|
+
db.phone "05604 - 919937"
|
12
|
+
db.fax "05604 - 919938"
|
13
|
+
db.email "ph@metaminded.com"
|
14
|
+
db.address "David Heinemeier-Hansson\n37signals, LLC\n30 North Racine Avenue #200\nChicago, Illinois 60607\nUSA"
|
15
|
+
db.subject "Thanks a lot for giving us Rails"
|
16
|
+
db.body <<-TEXT
|
17
|
+
Dear David and all you colleagues,
|
18
|
+
|
19
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
20
|
+
|
21
|
+
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
22
|
+
|
23
|
+
Adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco.
|
24
|
+
|
25
|
+
Laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
26
|
+
|
27
|
+
Reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
28
|
+
|
29
|
+
Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt.
|
30
|
+
|
31
|
+
Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum.
|
32
|
+
|
33
|
+
Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna.
|
34
|
+
|
35
|
+
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
36
|
+
|
37
|
+
Adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco.
|
38
|
+
|
39
|
+
Laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
40
|
+
|
41
|
+
Reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
42
|
+
|
43
|
+
Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt.
|
44
|
+
|
45
|
+
Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum.
|
46
|
+
|
47
|
+
Curabitur ullamcorper ultricies nisi. Nam eget dui.
|
48
|
+
|
49
|
+
Best Regards,
|
50
|
+
|
51
|
+
TEXT
|
52
|
+
end
|
53
|
+
|
Binary file
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'dinbrief'
|
4
|
+
|
5
|
+
#
|
6
|
+
# Firstly, subclass Dinbrief::Letter to get the header/footer
|
7
|
+
# stuff sorted out.
|
8
|
+
#
|
9
|
+
class MyLetter < Dinbrief::Letter
|
10
|
+
# define a header
|
11
|
+
def header
|
12
|
+
image(File.join(File.dirname(__FILE__), "metaminded.png"),
|
13
|
+
:at => [0.mm, 35.mm],
|
14
|
+
:fit => [80.mm, 22.mm]
|
15
|
+
)
|
16
|
+
text_box(%{metaminded UG (haftungsbeschränkt)
|
17
|
+
Ulmer Str. 124
|
18
|
+
im Wi.Z
|
19
|
+
73431 Aalen
|
20
|
+
|
21
|
+
www.metaminded.com
|
22
|
+
},
|
23
|
+
:at => [105.mm, 35.mm],
|
24
|
+
:width => 85.mm,
|
25
|
+
:align => :left,
|
26
|
+
:size => 10.pt
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
# define a footer
|
31
|
+
def footer
|
32
|
+
text_box(%{metaminded UG (haftungsbeschränkt) – Ulmer Str. 124 – 73431 Aalen
|
33
|
+
Handelsregisternummer: HRB 724169 – Registergericht: Amtsgericht Ulm/Donau – USt.ID.: DE267558458
|
34
|
+
Geschäftsführer: Dr. Peter Horn
|
35
|
+
},
|
36
|
+
:at => [20.mm, 12.mm],
|
37
|
+
:width => 140.mm,
|
38
|
+
:align => :center,
|
39
|
+
:size => 8.pt,
|
40
|
+
)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# then, use this subclass to render the actual letter
|
46
|
+
#
|
47
|
+
MyLetter.letter('more_serious.pdf') do |db|
|
48
|
+
db.return_address 'metaminded UG – Ulmer Straße 176 – 73233 Aalen'
|
49
|
+
db.oursign "PH"
|
50
|
+
db.yoursign "DHH"
|
51
|
+
db.yourmessage "24.12.2011"
|
52
|
+
db.name "Dr. Peter Horn"
|
53
|
+
db.phone "05604 - 919937"
|
54
|
+
db.fax "05604 - 919938"
|
55
|
+
db.email "ph@metaminded.com"
|
56
|
+
db.address "David Heinemeier-Hansson\n37signals, LLC\n30 North Racine Avenue #200\nChicago, Illinois 60607\nUSA"
|
57
|
+
db.subject "Thanks a lot for giving us Rails"
|
58
|
+
db.body do |letter|
|
59
|
+
letter.text %{Dear David and all you colleagues,
|
60
|
+
|
61
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
62
|
+
|
63
|
+
To impress people, I add a useless table:
|
64
|
+
}
|
65
|
+
|
66
|
+
letter.table [["Animal", "Programming Language", "coincidence"],
|
67
|
+
["Penguin", "C", "213" ],
|
68
|
+
["Platypus", "ObjC", "143" ],
|
69
|
+
["Cat", "Ruby", "47" ],
|
70
|
+
["Dog", "Python", "23" ],
|
71
|
+
["Olm", "PHP", "876" ]
|
72
|
+
]
|
73
|
+
|
74
|
+
letter.text %{
|
75
|
+
Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum.
|
76
|
+
|
77
|
+
Curabitur ullamcorper ultricies nisi. Nam eget dui.
|
78
|
+
|
79
|
+
Best Regards,
|
80
|
+
}
|
81
|
+
|
82
|
+
letter.image(File.join(File.dirname(__FILE__), "signature.png"), :fit => [3.cm, 3.cm])
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
Binary file
|
data/lib/dinbrief.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'prawn'
|
4
|
+
require 'prawn/measurement_extensions'
|
5
|
+
|
6
|
+
module Dinbrief
|
7
|
+
|
8
|
+
def self.letter(*args, &block)
|
9
|
+
Letter.letter(*args, &block)
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'dinbrief/version'
|
15
|
+
require 'dinbrief/letter'
|
16
|
+
require 'dinbrief/letter_builder'
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Dinbrief
|
4
|
+
|
5
|
+
class Letter < Prawn::Document
|
6
|
+
|
7
|
+
def self.letter(filename,options={},&block)
|
8
|
+
self.generate(filename, DocumentDefaults.merge(options)) do |letter|
|
9
|
+
yield(letter.letter_builder)
|
10
|
+
letter.meta_header()
|
11
|
+
letter.meta_footer()
|
12
|
+
letter.methods.map(&:to_s).select{|m|m.start_with?("typeset_")}.each do |m|
|
13
|
+
next if m=='typeset_body'
|
14
|
+
letter.send(m)
|
15
|
+
end
|
16
|
+
letter.typeset_body
|
17
|
+
letter.add_page_numbers
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_page_numbers
|
22
|
+
if show_page_numbers?
|
23
|
+
number_pages page_numbering_string, {
|
24
|
+
:start_count_at => 1,
|
25
|
+
:page_filter => :all, #[2..9999],
|
26
|
+
:at => [page_numbering_x, page_numbering_y],
|
27
|
+
:align => page_numbering_align,
|
28
|
+
:size => page_numbering_fontsize,
|
29
|
+
:width => page_numbering_width
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def letter_builder()
|
35
|
+
@letter_builder ||= LetterBuilder.new(self)
|
36
|
+
end
|
37
|
+
|
38
|
+
def lb_get(nam)
|
39
|
+
@letter_builder.instance_variable_get("@#{nam}")
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
require 'dinbrief/letter/constants'
|
46
|
+
require 'dinbrief/letter/typeset_methods'
|
47
|
+
require 'dinbrief/letter/design_elements'
|
@@ -0,0 +1,135 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
|
3
|
+
class Dinbrief::Letter
|
4
|
+
|
5
|
+
DocumentDefaults = { # The following options are available (with the default values marked in [])
|
6
|
+
:page_size => 'A4', # One of the Document::PageGeometry sizes [LETTER]
|
7
|
+
:page_layout => :portrait, # Either :portrait or :landscape
|
8
|
+
:left_margin => 25.mm, # Sets the left margin in points [0.5 inch]
|
9
|
+
:right_margin => 20.mm, # Sets the right margin in points [0.5 inch]
|
10
|
+
:top_margin => 30.mm, # Sets the top margin in points [0.5 inch]
|
11
|
+
:bottom_margin => 3.cm, # Sets the bottom margin in points [0.5 inch]
|
12
|
+
:skip_page_creation => false, # Creates a document without starting the first page [false]
|
13
|
+
:compress => false, # Compresses content streams before rendering them [false]
|
14
|
+
:optimize_objects => false, # Reduce number of PDF objects in output, at expense of render time [false]
|
15
|
+
:background => nil, # An image path to be used as background on all pages [nil]
|
16
|
+
:info => nil, # Generic hash allowing for custom metadata properties [nil]
|
17
|
+
:template => nil # The path to an existing PDF file to use as a template [nil]
|
18
|
+
}
|
19
|
+
|
20
|
+
MeasurementDefaults = {
|
21
|
+
# Folding Marks
|
22
|
+
:fold_mark_1_y => 87.mm,
|
23
|
+
:fold_mark_2_y => -105.mm,
|
24
|
+
:fold_mark_x => 5.mm,
|
25
|
+
:fold_mark_width => 5.mm,
|
26
|
+
:punch_mark_y => 148.5.mm,
|
27
|
+
:punch_mark_x => 5.mm,
|
28
|
+
:punch_mark_width => 5.mm,
|
29
|
+
|
30
|
+
# Return Address Field
|
31
|
+
:return_address_x => 20.mm,
|
32
|
+
:return_address_y => -45.mm - 10.mm,
|
33
|
+
:return_address_rule_x => 20.mm,
|
34
|
+
:return_address_rule_y => -45.mm - 14.mm,
|
35
|
+
:return_address_rule_width => 85.mm,
|
36
|
+
:return_address_rule_linewidth => 0.5.pt,
|
37
|
+
:return_address_fontsize => 8.pt,
|
38
|
+
:return_address_align => :center,
|
39
|
+
:return_address_width => 85.mm,
|
40
|
+
|
41
|
+
# Address Field
|
42
|
+
:address_x => 25.mm,
|
43
|
+
:address_y => -45.mm - 17.mm,
|
44
|
+
:address_width => 80.mm,
|
45
|
+
:address_height => 28.mm,
|
46
|
+
:address_fontsize => 10.pt,
|
47
|
+
:address_valign => :center,
|
48
|
+
|
49
|
+
# Info Block
|
50
|
+
:info_block_x => 125.mm,
|
51
|
+
:info_block_y => -45.mm,
|
52
|
+
:info_block_width => 75.mm,
|
53
|
+
:info_block_fontsize => 9.pt,
|
54
|
+
|
55
|
+
# Date
|
56
|
+
:date_x => 125.mm,
|
57
|
+
:date_y => -87.mm,
|
58
|
+
:date_fontsize => 10.pt,
|
59
|
+
|
60
|
+
# Subject
|
61
|
+
:subject_x => 25.mm,
|
62
|
+
:subject_y => - 105.mm + 2.mm,
|
63
|
+
:subject_fontsize => 11.pt,
|
64
|
+
:subject_style => :bold,
|
65
|
+
|
66
|
+
# Body
|
67
|
+
:body_fontsize => 10.pt,
|
68
|
+
:body_style => nil,
|
69
|
+
:body_preskip => 105.mm - 30.mm + 6.mm,
|
70
|
+
|
71
|
+
# Header
|
72
|
+
:header_x => 20.mm,
|
73
|
+
:header_y => 297.mm,
|
74
|
+
:header_width => 210.mm-30.mm,
|
75
|
+
:header_height => 45.mm,
|
76
|
+
|
77
|
+
# Footer
|
78
|
+
:footer_x => 20.mm,
|
79
|
+
:footer_y => 22.mm,
|
80
|
+
:footer_width => 210.mm-30.mm,
|
81
|
+
:footer_height => 12.mm,
|
82
|
+
|
83
|
+
# Page Numbering
|
84
|
+
:page_numbering_string => "<page>/<total>",
|
85
|
+
:page_numbering_x => 180.mm,
|
86
|
+
:page_numbering_y => 26.mm,
|
87
|
+
:page_numbering_width => 10.mm,
|
88
|
+
:page_numbering_align => :right,
|
89
|
+
:page_numbering_fontsize => 10.pt
|
90
|
+
}
|
91
|
+
|
92
|
+
MeasurementDefaults.each do |n,v|
|
93
|
+
nn = n.to_s
|
94
|
+
define_method(nn) do
|
95
|
+
v = MeasurementDefaults[n]
|
96
|
+
if nn.end_with?('_x')
|
97
|
+
(v < 0 ? 210.mm : 0) + v - DocumentDefaults[:left_margin]
|
98
|
+
elsif nn.end_with?('_y')
|
99
|
+
(v < 0 ? 297.mm : 0) + v - DocumentDefaults[:bottom_margin]
|
100
|
+
else
|
101
|
+
v
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
LetterDefaults = {
|
107
|
+
:show_fold_tics => true,
|
108
|
+
:show_punch_tic => true,
|
109
|
+
:show_return_address_rule => true,
|
110
|
+
:show_page_numbers => true
|
111
|
+
}
|
112
|
+
|
113
|
+
LetterDefaults.each do |n,v|
|
114
|
+
nn = n.to_s
|
115
|
+
define_method(nn) do LetterDefaults[n] end
|
116
|
+
if nn.start_with?("show_")
|
117
|
+
define_method("#{nn}?") do LetterDefaults[n] end
|
118
|
+
define_method("#{nn}!") do LetterDefaults[n] = true end
|
119
|
+
define_method("hide_#{nn[5..-1]}!") do LetterDefaults[n] = false end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
InfoTranslations = {
|
124
|
+
:yoursign => 'Ihr Zeichen',
|
125
|
+
:yourmessage => 'Ihre Nachricht vom',
|
126
|
+
:oursign => 'Unser Zeichen',
|
127
|
+
:ourmessage => 'Unsere Nachricht vom',
|
128
|
+
:name => 'Name',
|
129
|
+
:phone => 'Telefon',
|
130
|
+
:fax => 'Telefax',
|
131
|
+
:email => 'E-Mail',
|
132
|
+
:date => 'Datum'
|
133
|
+
}
|
134
|
+
|
135
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
|
3
|
+
class Dinbrief::Letter
|
4
|
+
|
5
|
+
#
|
6
|
+
# creates a header bounding box on the top of the page and
|
7
|
+
# renders some dummy content. If a 'header' method is implemented,
|
8
|
+
# it's called, so you can easily define your own header.
|
9
|
+
#
|
10
|
+
def meta_header
|
11
|
+
bounding_box([header_x, header_y],
|
12
|
+
:width => header_width,
|
13
|
+
:height => header_height
|
14
|
+
) do |pdf|
|
15
|
+
if self.respond_to? :header
|
16
|
+
header()
|
17
|
+
else
|
18
|
+
line_width 0.1.pt
|
19
|
+
stroke_bounds
|
20
|
+
text_box("DIN Brief Letter\na Ruby GEM for Prawn",
|
21
|
+
:at => [0.mm, 35.mm],
|
22
|
+
:size => 16.pt
|
23
|
+
)
|
24
|
+
draw_text("© 2011–#{Time.now.year} Peter Horn, metaminded UG",
|
25
|
+
:at => [0.mm, 13.mm],
|
26
|
+
:size => 10.pt
|
27
|
+
)
|
28
|
+
text_box(%{To replace this default header by yours,
|
29
|
+
just implement a 'header' function in your Dinbrief::Letter
|
30
|
+
subclass and draw whatever you like.
|
31
|
+
There, you are inside this bordered box with [0,0] being
|
32
|
+
the lower left corner.},
|
33
|
+
:at => [85.mm, 35.mm],
|
34
|
+
:width => 90.mm,
|
35
|
+
:align => :left,
|
36
|
+
:size => 10.pt,
|
37
|
+
:font => "Times-Roman"
|
38
|
+
|
39
|
+
)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# creates a footer bounding box on the bottom of the page and
|
46
|
+
# renders some dummy content. If a 'footer' method is implemented,
|
47
|
+
# it's called, so you can easily define your own footer.
|
48
|
+
#
|
49
|
+
def meta_footer()
|
50
|
+
bounding_box([footer_x, footer_y],
|
51
|
+
:width => footer_width,
|
52
|
+
:height => footer_height
|
53
|
+
) do |pdf|
|
54
|
+
if self.respond_to? :footer
|
55
|
+
footer()
|
56
|
+
else
|
57
|
+
line_width 0.1.pt
|
58
|
+
stroke_bounds
|
59
|
+
text_box(%{To replace this default footer by yours, just implement a 'footer' function in your Dinbrief::Letter subclass and draw whatever you like. There, you are inside this bordered box with [0,0] being the lower left corner.
|
60
|
+
© 2011–#{Time.now.year} Peter Horn, metaminded UG},
|
61
|
+
:at => [20.mm, 12.mm],
|
62
|
+
:width => 140.mm,
|
63
|
+
:align => :center,
|
64
|
+
:size => 8.pt,
|
65
|
+
)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
|
3
|
+
class Dinbrief::Letter
|
4
|
+
#
|
5
|
+
# typeset info block (sign, name, phone...)
|
6
|
+
#
|
7
|
+
def typeset_info
|
8
|
+
info = [:yoursign, :yourmessage, :oursign, :ourmessage,
|
9
|
+
:name, :phone, :fax, :email].map do |nam|
|
10
|
+
iv = lb_get nam
|
11
|
+
iv ? "#{InfoTranslations[nam]}: #{iv}" : nil
|
12
|
+
end.compact.join("\n")
|
13
|
+
return unless info
|
14
|
+
text_box(info,
|
15
|
+
:at => [info_block_x, info_block_y],
|
16
|
+
:size => info_block_fontsize
|
17
|
+
)
|
18
|
+
date = lb_get(:date) || Time.now.strftime("%d.%m.%Y")
|
19
|
+
text_box("#{InfoTranslations[:date]}: #{date}",
|
20
|
+
:at => [date_x, date_y],
|
21
|
+
:size => date_fontsize
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# typeset rerturn address above address field
|
27
|
+
#
|
28
|
+
def typeset_return_address
|
29
|
+
return unless lb_get(:return_address)
|
30
|
+
bounding_box([return_address_x, return_address_y],
|
31
|
+
:width => return_address_width,
|
32
|
+
:height => 5.mm
|
33
|
+
) do
|
34
|
+
text(lb_get(:return_address),
|
35
|
+
:size => return_address_fontsize,
|
36
|
+
:align => return_address_align
|
37
|
+
)
|
38
|
+
end
|
39
|
+
return unless show_return_address_rule?
|
40
|
+
line_width return_address_rule_linewidth
|
41
|
+
line(
|
42
|
+
[return_address_rule_x, return_address_rule_y],
|
43
|
+
[return_address_rule_x + return_address_rule_width, return_address_rule_y]
|
44
|
+
)
|
45
|
+
stroke
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
# draw the fold- and punchmarks
|
50
|
+
#
|
51
|
+
def typeset_marks
|
52
|
+
line_width(0.2)
|
53
|
+
if show_fold_tics?
|
54
|
+
line([fold_mark_x, fold_mark_1_y], [fold_mark_x+fold_mark_width, fold_mark_1_y])
|
55
|
+
line([fold_mark_x, fold_mark_2_y], [fold_mark_x+fold_mark_width, fold_mark_2_y])
|
56
|
+
end
|
57
|
+
if show_punch_tic?
|
58
|
+
line([punch_mark_x, punch_mark_y], [punch_mark_x+punch_mark_width, punch_mark_y])
|
59
|
+
end
|
60
|
+
stroke
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
# typeset the recipients address
|
65
|
+
#
|
66
|
+
def typeset_address
|
67
|
+
raise "An address should be given." unless lb_get(:address)
|
68
|
+
bounding_box([address_x, address_y],
|
69
|
+
:width => address_width,
|
70
|
+
:height => address_height,
|
71
|
+
:valign => address_valign,
|
72
|
+
) do
|
73
|
+
text(lb_get(:address),
|
74
|
+
:size => address_fontsize
|
75
|
+
)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def typeset_subject
|
80
|
+
return unless lb_get(:subject)
|
81
|
+
text_box(lb_get(:subject),
|
82
|
+
:at => [subject_x, subject_y],
|
83
|
+
:size => subject_fontsize,
|
84
|
+
:style => subject_style
|
85
|
+
)
|
86
|
+
end
|
87
|
+
|
88
|
+
def typeset_body
|
89
|
+
gbody = lb_get(:body)
|
90
|
+
raise "A body should be given." unless gbody
|
91
|
+
move_cursor_to bounds.height
|
92
|
+
move_down body_preskip
|
93
|
+
if gbody.respond_to?(:call)
|
94
|
+
font_size(body_fontsize)
|
95
|
+
#font_style(body_style)
|
96
|
+
gbody.call(self)
|
97
|
+
else
|
98
|
+
text(gbody.strip,
|
99
|
+
:size => body_fontsize,
|
100
|
+
:style => body_style
|
101
|
+
)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
|
3
|
+
module Dinbrief
|
4
|
+
class LetterBuilder
|
5
|
+
|
6
|
+
def initialize(letter=nil)
|
7
|
+
@letter = letter
|
8
|
+
end
|
9
|
+
|
10
|
+
[
|
11
|
+
:subject, :header, :return_address, :address,
|
12
|
+
:yoursign, :yourmessage, :oursign, :ourmessage,
|
13
|
+
:name, :phone, :fax, :email,
|
14
|
+
:date
|
15
|
+
].each do |nam|
|
16
|
+
define_method nam do |s|
|
17
|
+
instance_variable_set("@#{nam}", s)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def body(b=nil, &block)
|
22
|
+
@body = block_given? ? block : b
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dinbrief
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Peter Horn
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-01-04 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: prawn
|
16
|
+
requirement: &70283461717780 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - =
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.0.0.rc1
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70283461717780
|
25
|
+
description: DIN Brief gem for Prawn. Creating letters that confirm to the DIN specifications.
|
26
|
+
For Ruby.
|
27
|
+
email:
|
28
|
+
- peter.horn@provideal.net
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- .gitignore
|
34
|
+
- Gemfile
|
35
|
+
- README.textile
|
36
|
+
- Rakefile
|
37
|
+
- dinbrief.gemspec
|
38
|
+
- example/example.png
|
39
|
+
- example/hello.rb
|
40
|
+
- example/metaminded.png
|
41
|
+
- example/more_serious.rb
|
42
|
+
- example/signature.png
|
43
|
+
- lib/dinbrief.rb
|
44
|
+
- lib/dinbrief/letter.rb
|
45
|
+
- lib/dinbrief/letter/constants.rb
|
46
|
+
- lib/dinbrief/letter/design_elements.rb
|
47
|
+
- lib/dinbrief/letter/typeset_methods.rb
|
48
|
+
- lib/dinbrief/letter_builder.rb
|
49
|
+
- lib/dinbrief/version.rb
|
50
|
+
homepage: ''
|
51
|
+
licenses: []
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options: []
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ! '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
requirements: []
|
69
|
+
rubyforge_project: dinbrief
|
70
|
+
rubygems_version: 1.8.10
|
71
|
+
signing_key:
|
72
|
+
specification_version: 3
|
73
|
+
summary: DIN Letter gem for Prawn
|
74
|
+
test_files: []
|