rdpl 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm ree@rdpl
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Cássio Marques
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,17 @@
1
+ = rdpl
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 Cássio Marques. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,45 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "rdpl"
8
+ gem.summary = %Q{Create Datamax™ labels using Ruby! }
9
+ gem.description = %Q{RDPL provides a way to create labels for the Datamax™ printers using plain Ruby, through an abstraction of the DPL (Datamax Programming Language)}
10
+ gem.email = "cassiommc@gmail.com"
11
+ gem.homepage = "http://github.com/cassiomarques/rdpl"
12
+ gem.authors = ["Cássio Marques"]
13
+ gem.add_development_dependency "rspec", ">= 1.3.0"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
+ end
20
+
21
+ require 'spec/rake/spectask'
22
+ Spec::Rake::SpecTask.new(:spec) do |spec|
23
+ spec.libs << 'lib' << 'spec'
24
+ spec.spec_files = FileList['spec/**/*_spec.rb']
25
+ end
26
+
27
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
28
+ spec.libs << 'lib' << 'spec'
29
+ spec.pattern = 'spec/**/*_spec.rb'
30
+ spec.rcov = true
31
+ end
32
+
33
+ task :spec => :check_dependencies
34
+
35
+ task :default => :spec
36
+
37
+ require 'rake/rdoctask'
38
+ Rake::RDocTask.new do |rdoc|
39
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
40
+
41
+ rdoc.rdoc_dir = 'rdoc'
42
+ rdoc.title = "rdpl #{version}"
43
+ rdoc.rdoc_files.include('README*')
44
+ rdoc.rdoc_files.include('lib/**/*.rb')
45
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,37 @@
1
+ module Rdpl
2
+ class Barcode
3
+ include Element
4
+
5
+ CODE_128 = 'e'
6
+ CODE_128_HUMAN = "E"
7
+
8
+ alias :wide_bar_multiplier :width_multiplier
9
+ alias :wide_bar_multiplier= :width_multiplier=
10
+ alias :narrow_bar_multiplier :height_multiplier
11
+ alias :narrow_bar_multiplier= :height_multiplier=
12
+
13
+ DEFAULT_HEIGHT = 25
14
+
15
+ def height=(height)
16
+ raise InvalidBarcodeHeightError unless valid_height_range.include?(height)
17
+ @height = height
18
+ end
19
+
20
+ def height
21
+ @height || DEFAULT_HEIGHT
22
+ end
23
+
24
+ private
25
+ def valid_height_range
26
+ 0..999
27
+ end
28
+
29
+ def formatted_height
30
+ '%03d' % height
31
+ end
32
+
33
+ def valid_font_id_ranges
34
+ [('a'.. 'z'), ('A'..'Z')]
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,10 @@
1
+ module Rdpl
2
+ class BitmappedText
3
+ include Element
4
+
5
+ private
6
+ def valid_font_id_ranges
7
+ [(0..9)]
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,34 @@
1
+ module Rdpl
2
+ class Box
3
+ attr_writer :bottom_and_top_thickness, :sides_thickness
4
+
5
+ DEFAULT_CHARACTER = 'b'
6
+
7
+ include LinesAndBoxes
8
+
9
+ def bottom_and_top_thickness
10
+ @bottom_and_top_thickness || 0
11
+ end
12
+
13
+ def sides_thickness
14
+ @sides_thickness || 0
15
+ end
16
+
17
+ def data
18
+ DEFAULT_CHARACTER +
19
+ formatted_horizontal_width +
20
+ formatted_vertical_width +
21
+ formatted_bottom_and_top_thickness +
22
+ formatted_sides_thickness
23
+ end
24
+
25
+ private
26
+ def formatted_bottom_and_top_thickness
27
+ '%04d' % normalize_number(bottom_and_top_thickness)
28
+ end
29
+
30
+ def formatted_sides_thickness
31
+ '%04d' % normalize_number(sides_thickness)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,134 @@
1
+ module Rdpl
2
+ module Element
3
+ ROTATION_0_DEGREES = 1
4
+ ROTATION_90_DEGREES = 2
5
+ ROTATION_180_DEGREES = 3
6
+ ROTATION_270_DEGREES = 4
7
+
8
+ class InvalidRotationError < StandardError; end
9
+ class InvalidFontIdError < StandardError; end
10
+ class InvalidWidthMultiplierError < StandardError; end
11
+ class InvalidHeightMultiplierError < StandardError; end
12
+ class InvalidBarcodeHeightError < StandardError; end
13
+ class FixedValueError < StandardError; end
14
+ class InvalidAssigmentError < StandardError; end
15
+
16
+ def initialize(options = {})
17
+ options.each_pair { |option, value| self.send "#{option}=", value }
18
+ end
19
+
20
+ def rotation=(rotation)
21
+ raise InvalidRotationError, rotation unless valid_rotation_range.include?(rotation)
22
+ @rotation = rotation
23
+ end
24
+
25
+ def rotation
26
+ @rotation || ROTATION_0_DEGREES
27
+ end
28
+
29
+ # Sets the element font type. Available types are:
30
+ #
31
+ # Type Interpretation
32
+ # 0-9 Font
33
+ # A-T Barcode with human readable text
34
+ # a-z Barcode without human readable text
35
+ # X Line, box, polygon, circle
36
+ # Y Image
37
+ def font_id=(font_id)
38
+ raise InvalidFontIdError unless valid_font_id_ranges.any? { |range| range.include? font_id }
39
+ @font_id = font_id
40
+ end
41
+
42
+ def font_id
43
+ @font_id
44
+ end
45
+
46
+ # Valid values goes from 1 to 9 and A to O (base 25)
47
+ def width_multiplier=(multiplier)
48
+ raise InvalidWidthMultiplierError, multiplier unless valid_width_or_height_multiplier?(multiplier)
49
+ @width_multiplier = multiplier
50
+ end
51
+
52
+ def width_multiplier
53
+ @width_multiplier || 1
54
+ end
55
+
56
+ def height_multiplier=(multiplier)
57
+ raise InvalidHeightMultiplierError, multiplier unless valid_width_or_height_multiplier?(multiplier)
58
+ @height_multiplier = multiplier
59
+ end
60
+
61
+ # Valid values goes from 1 to 9 and A to O (base 25)
62
+ def height_multiplier
63
+ @height_multiplier || 1
64
+ end
65
+
66
+ # Used only by barcode and smooth/scaleble fonts, but has to be present as 000
67
+ # in other elements.
68
+ def formatted_height
69
+ '000'
70
+ end
71
+
72
+ # Interpreted in hundredths of an inch or tenths of millimeters, depending on
73
+ # the measurement used in the printing job.
74
+ def row_position=(position)
75
+ @row_position = position
76
+ end
77
+
78
+ def row_position
79
+ @row_position || 0
80
+ end
81
+
82
+ # Interpreted in hundredths of an inch or tenths of millimeters, depending on
83
+ # the measurement used in the printing job.
84
+ #
85
+ # Notice that the limits for this value depend on the printer model.
86
+ def column_position=(position)
87
+ @column_position = position
88
+ end
89
+
90
+ def column_position
91
+ @column_position || 0
92
+ end
93
+
94
+ def data=(data)
95
+ @data = data
96
+ end
97
+
98
+ def data
99
+ @data || ''
100
+ end
101
+
102
+ def to_s
103
+ [rotation, font_id, width_multiplier, height_multiplier, formatted_height,
104
+ formatted_row_position, formatted_column_position, data].join
105
+ end
106
+
107
+ private
108
+ def valid_rotation_range
109
+ ROTATION_0_DEGREES..ROTATION_270_DEGREES
110
+ end
111
+
112
+ def valid_width_or_height_multiplier_ranges
113
+ [(1..9), ('A'..'O')]
114
+ end
115
+
116
+ def valid_width_or_height_multiplier?(multiplier)
117
+ valid_width_or_height_multiplier_ranges.any? { |range| range.include? multiplier }
118
+ end
119
+
120
+ def default_rotation; 1; end
121
+
122
+ def formatted_row_position
123
+ '%04d' % normalize_number(row_position)
124
+ end
125
+
126
+ def formatted_column_position
127
+ '%04d' % normalize_number(column_position)
128
+ end
129
+
130
+ def normalize_number(number)
131
+ number.to_s.gsub(/\./, '')
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,11 @@
1
+ module Rdpl
2
+ module Graphic
3
+ def font_id
4
+ 'X'
5
+ end
6
+
7
+ def data=(data)
8
+ raise Element::InvalidAssigmentError, 'You cannot assign data to graphic elements'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Rdpl
2
+ class Line
3
+ DEFAULT_CHARACTER = 'l'
4
+
5
+ include LinesAndBoxes
6
+
7
+ def data
8
+ DEFAULT_CHARACTER + formatted_horizontal_width + formatted_vertical_width
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,37 @@
1
+ module Rdpl
2
+ module LinesAndBoxes
3
+ attr_writer :vertical_width, :horizontal_width
4
+
5
+ include Element
6
+ include Graphic
7
+
8
+ def vertical_width
9
+ @vertical_width || 0
10
+ end
11
+
12
+ def horizontal_width
13
+ @horizontal_width || 0
14
+ end
15
+
16
+ def width_multiplier=(multiplier)
17
+ raise FixedValueError, 'for lines width multiplier is fixed to 1'
18
+ end
19
+
20
+ def height_multiplier=(multiplier)
21
+ raise FixedValueError, 'for lines height multiplier is fixed to 1'
22
+ end
23
+
24
+ def font_id
25
+ 'X'
26
+ end
27
+
28
+ private
29
+ def formatted_horizontal_width
30
+ '%04d' % normalize_number(horizontal_width)
31
+ end
32
+
33
+ def formatted_vertical_width
34
+ '%04d' % normalize_number(vertical_width)
35
+ end
36
+ end
37
+ end
data/lib/job.rb ADDED
@@ -0,0 +1,66 @@
1
+ require 'tempfile'
2
+
3
+ module Rdpl
4
+ class Job
5
+ attr_reader :labels, :printer, :state
6
+ attr_writer :sensor
7
+
8
+ include Commandable
9
+ include Enumerable
10
+
11
+ def initialize(options = {})
12
+ initialize_options options
13
+ @contents = ''
14
+ start
15
+ @labels = []
16
+ end
17
+
18
+ def each
19
+ @labels.each { |label| yield label }
20
+ end
21
+
22
+ def sensor; @sensor ||= Sensor::EDGE; end
23
+
24
+ def measurement; @measurement ||= :inches; end
25
+
26
+ def in?; measurement == :inches; end
27
+
28
+ def mm?; measurement == :metric; end
29
+
30
+ def <<(label)
31
+ @labels << label
32
+ label.job = self
33
+ @contents << label.dump
34
+ feed
35
+ end
36
+ alias :add_label :<<
37
+
38
+ def dump; @contents.dup; end
39
+
40
+ def feed; command FEED; end
41
+
42
+ def print
43
+ tempfile = Tempfile.new 'datamax_label'
44
+ tempfile << dump
45
+ tempfile.close
46
+ Kernel.system "lpr -P #{printer} #{tempfile.path}"
47
+ end
48
+
49
+ private
50
+ def printer=(printer); @printer = printer; end
51
+ def measurement=(measurement); @measurement = measurement; end
52
+
53
+ def initialize_options(options)
54
+ validate_measurement_option options[:measurement]
55
+ options.each_pair { |option, value| self.send("#{option}=", value) }
56
+ raise MissingPrinterNameError if printer.nil?
57
+ @state = :open
58
+ end
59
+
60
+ def start; command sensor; end
61
+
62
+ def validate_measurement_option(option)
63
+ raise ArgumentError, 'should be :metric or :inches' unless [nil, :metric, :inches].include?(option)
64
+ end
65
+ end
66
+ end