Class: ZplRender::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/zpl_render/parser.rb

Overview

Tokenizes a ZPL II stream into [command, params] pairs.

Commands are introduced by the format prefix (^, changeable via ^CC/~CC) or the control prefix (~, changeable via ^CT/~CT). The command code is two characters, except ^A where the second character is the font designator (^A@ remains its own command). Parameters run until the next prefix character.

Defined Under Namespace

Classes: Command

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(zpl) ⇒ Parser

Returns a new instance of Parser.



23
24
25
# File 'lib/zpl_render/parser.rb', line 23

def initialize(zpl)
  @zpl = zpl.to_s
end

Class Method Details

.parse(zpl) ⇒ Object



19
20
21
# File 'lib/zpl_render/parser.rb', line 19

def self.parse(zpl)
  new(zpl).parse
end

Instance Method Details

#parseObject



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
# File 'lib/zpl_render/parser.rb', line 27

def parse
  commands = []
  caret = "^"
  tilde = "~"
  i = 0
  len = @zpl.length

  while i < len
    ch = @zpl[i]
    unless ch == caret || ch == tilde
      i += 1
      next
    end

    prefix = ch == caret ? :caret : :tilde
    code = @zpl[i + 1, 2].to_s
    if code.empty?
      i += 1
      next
    end

    name = nil
    font = nil
    if code[0]&.upcase == "A" && code != "A@" && prefix == :caret
      name = "A"
      font = code[1]
    else
      name = code.upcase
    end
    i += 3 # prefix + two command characters (^A consumes its font char)

    # ^CC/~CC and ^CT/~CT take effect immediately: their parameter is a
    # single character that becomes the new prefix.
    if name == "CC" || name == "CT"
      new_prefix = @zpl[i]
      if new_prefix
        caret = new_prefix if name == "CC"
        tilde = new_prefix if name == "CT"
        i += 1
      end
      next
    end

    # parameters: everything until the next prefix character
    j = i
    j += 1 while j < len && @zpl[j] != caret && @zpl[j] != tilde
    params = @zpl[i...j].to_s

    if name == "A"
      params = "#{font}#{params}"
    end

    # CR/LF are ignorable in ZPL streams
    params = params.delete("\r\n") unless %w[GF DG DB].include?(name)
    params = params.strip if %w[GF DG DB].include?(name)

    commands << Command.new(name: name, params: params, prefix: prefix)
    i = j
  end

  commands
end