Class: Labrat::Label

Inherits:
Object
  • Object
show all
Defined in:
lib/labrat/label.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(texts, ops) ⇒ Label

Returns a new instance of Label.



8
9
10
11
12
13
14
15
16
17
18
# File 'lib/labrat/label.rb', line 8

def initialize(texts, ops)
  @ops = ops
  unless @ops.nl_sep.nil? || @ops.nl_sep == ''
    @texts = texts.map { |t| t.gsub(ops.nl_sep, "\n") }
  end
  if @ops.copies > 1
    duped_texts = []
    @texts.each { |t| @ops.copies.times { duped_texts << t } }
    @texts = duped_texts
  end
end

Instance Attribute Details

#opsObject (readonly)

Returns the value of attribute ops.



5
6
7
# File 'lib/labrat/label.rb', line 5

def ops
  @ops
end

#textsObject

Returns the value of attribute texts.



6
7
8
# File 'lib/labrat/label.rb', line 6

def texts
  @texts
end

Instance Method Details

#generateObject



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/labrat/label.rb', line 20

def generate
  # The default margin is 0.5in on all sides, way too big for labels, so
  # it is important to set these here.  The margins' designation as "top,"
  # "left," "bottom," and "right" take into account the page layout.  That
  # is, the left margin is on the left in both portrait and landscape
  # orientations.  But I want the user to be able to set the margins
  # according to the label type, independent of the orientation.  I adopt
  # the convention that the margins are named assuming a portrait
  # orientation and swap them here so that when Prawn swaps them again,
  # they come out correct.
  layout = ops.landscape ? :landscape : :portrait
  if layout == :portrait
    tpm = ops.top_page_margin
    bpm = ops.bottom_page_margin
    lpm = ops.left_page_margin
    rpm = ops.right_page_margin
  else
    lpm = ops.top_page_margin
    rpm = ops.bottom_page_margin
    tpm = ops.left_page_margin
    bpm = ops.right_page_margin
  end
  out_file = File.expand_path(ops.out_file)
  Prawn::Document.generate(
    out_file,
    page_size: [ops.page_width, ops.page_height],
                                   left_margin: lpm,
    right_margin: rpm,
                                   top_margin: tpm,
    bottom_margin: bpm,
                                   page_layout: layout,
  ) do |pdf|
    # Define a grid with each grid box to be used for a single label.
    pdf.define_grid(
      rows: ops.rows,
      columns: ops.columns,
      row_gutter: ops.row_gap,
      column_gutter: ops.column_gap,
    )
    if ops.verbose
      warn "Page dimensions:"
      warn "  [pg_wd, pg_ht] = [#{ops.page_width.round(2)}pt,#{ops.page_height.round(2)}pt]"
      warn "  orientation: #{layout}"
      warn "  [rows, columns] = [#{ops.rows},#{ops.columns}]"
      warn "  [lpm, rpm] = [#{lpm.round(2)}pt,#{rpm.round(2)}pt]"
      warn "  [tpm, bpm] = [#{tpm.round(2)}pt,#{bpm.round(2)}pt]"
      warn ""
    end
    if ops.template
      # Replace any texts with the numbers, the name of the label (and alias) and show the grid.
      lab_text = ops.raw_label || ops.label
      if ops.label != ops.raw_label
        lab_text += "\n(#{ops.label})"
      end
      self.texts = (1..(ops.rows * ops.columns)).map { |n| "#{n}\n#{lab_text}" }
      ops.font_name = 'Helvetica'
      ops.font_style = 'bold'
      ops.font_size = 11
      pdf.grid.show_all
    end
    raise EmptyLabelError, "Empty label" if waste_of_labels?

    last_k = texts.size - 1
    lab_dims_reported = false
    texts.each_with_index do |text, k|
      row, col = row_col(k + 1)
      pdf.grid(row, col).bounding_box do
        bounds = pdf.bounds
        pdf.stroke_bounds if ops.grid
        box_wd = (bounds.right - bounds.left) - ops.left_pad - ops.right_pad
        box_ht = (bounds.top - bounds.bottom) - ops.top_pad - ops.bottom_pad
        box_x = ops.left_pad + ops.delta_x
        box_y = ops.bottom_pad + box_ht + ops.delta_y
        pdf.font ops.font_name, style: ops.font_style, size: ops.font_size.to_f
        pdf.text_box(
          text,
          width: box_wd,
          height: box_ht,
                                   align: ops.h_align,
          valign: ops.v_align,
                                   overflow: :truncate,
          at: [box_x, box_y],
        )
        if ops.verbose && !lab_dims_reported
          warn "Label text box dimensions:"
          warn "  [box_wd, box_ht] = [#{box_wd.round(2)}pt,#{box_ht.round(2)}pt]"
          warn "  [box_x, box_y] = [#{box_x.round(2)}pt,#{box_y.round(2)}pt]"
          warn "  [delta_x, delta_y] = [#{ops.delta_x.round(2)}pt,#{ops.delta_y.round(2)}pt]"
          warn ''
          lab_dims_reported = true
        end
        if ops.verbose
          warn "Label ##{(k % lpp) + 1} on page #{page_num(k)} at row #{row + 1}, column #{col + 1}:"
          warn '-------------------'
          warn text
          warn '-------------------'
          warn ''
        end
        pdf.start_new_page if needs_new_page?(k, last_k)
      end
    end
  end
  puts ops.out_file
  self
end

#lppObject

Labels per page



149
150
151
# File 'lib/labrat/label.rb', line 149

def lpp
  ops.rows * ops.columns
end

#needs_new_page?(k, last_k) ⇒ Boolean

Should we emit a new page at this point?

Returns:

  • (Boolean)


166
167
168
169
170
171
# File 'lib/labrat/label.rb', line 166

def needs_new_page?(k, last_k)
  return false if k == last_k

  r, c = row_col(k + 1)
  r + 1 == ops.rows && c + 1 == ops.columns
end

#page_num(k) ⇒ Object

Page number of the kth label



154
155
156
# File 'lib/labrat/label.rb', line 154

def page_num(k)
  k.divmod(lpp)[0] + 1
end


126
127
128
129
130
131
132
133
# File 'lib/labrat/label.rb', line 126

def print
  cmd = ops.print_command.gsub('%p', ops.printer).gsub('%o', ops.out_file)
  if ops.verbose
    warn "Printing with:"
    warn "  #{cmd} &"
  end
  system("#{cmd} &")
end

#removeObject



144
145
146
# File 'lib/labrat/label.rb', line 144

def remove
  FileUtils.rm(ops.out_file)
end

#row_col(k) ⇒ Object

Return the 0-based row and column within a page on which the k-th (1-based) label should be printed.



160
161
162
163
# File 'lib/labrat/label.rb', line 160

def row_col(k)
  k_on_page = (k + ops.start_label - 2) % lpp
  k_on_page.divmod(ops.columns)
end

#viewObject



135
136
137
138
139
140
141
142
# File 'lib/labrat/label.rb', line 135

def view
  cmd = ops.view_command.gsub('%o', ops.out_file)
  if ops.verbose
    warn "Viewing with:"
    warn "  #{cmd} &"
  end
  system("#{cmd} &")
end

#waste_of_labels?Boolean

Would we just be printing blank labels?

Returns:

  • (Boolean)


174
175
176
177
# File 'lib/labrat/label.rb', line 174

def waste_of_labels?
  (texts.nil? || texts.empty? || texts.all?(&:blank?)) &&
    !ops.view
end