Class: FormatEngine::FormatSpec

Inherits:
Object
  • Object
show all
Defined in:
lib/format_engine/format_spec.rb

Overview

The format string parser.

Constant Summary collapse

REGEX =

The regex used to parse variable specifications.

%r{(?<flags> [~@#$^&*\=?_<>\\\/\.,\|!]*){0}
 (?<parms> [-+]?(\d+(\.\d+)?)?){0}
 (?<var> %\g<flags>\g<parms>[a-zA-Z]){0}
 (?<set> %\g<flags>\d*\[([^\]\\]|\\.)+\]){0}
 (?<per> %%){0}
 \g<var> | \g<set> | \g<per>
}x

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(fmt_string) ⇒ FormatSpec

Set up an instance of a format specification.
Note This is a private method (rdoc gets it wrong). To create new instances of FormatSpec do not use FormatSpec.new, but use FormatSpec.get_spec instead.



36
37
38
39
# File 'lib/format_engine/format_spec.rb', line 36

def initialize(fmt_string)
  @specs = []
  scan_spec(fmt_string)
end

Instance Attribute Details

#specsObject (readonly)

The array of specifications that were extracted.



30
31
32
# File 'lib/format_engine/format_spec.rb', line 30

def specs
  @specs
end

Class Method Details

.get_spec(fmt_string) ⇒ Object

Either get a format specification from the pool or create one.



24
25
26
27
# File 'lib/format_engine/format_spec.rb', line 24

def self.get_spec(fmt_string)
  @spec_pool ||= {}
  @spec_pool[fmt_string] ||= new(fmt_string)
end

Instance Method Details

#scan_spec(fmt_string) ⇒ Object

Scan the format string extracting literals and variables.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/format_engine/format_spec.rb', line 42

def scan_spec(fmt_string)
  until fmt_string.empty?
    if (match_data = REGEX.match(fmt_string))
      mid = match_data.to_s
      pre = match_data.pre_match

      @specs << FormatLiteral.new(pre) unless pre.empty?
      @specs << case
                when match_data[:var] then FormatVariable.new(mid)
                when match_data[:set] then FormatSet.new(mid)
                when match_data[:per] then FormatLiteral.new("\%")
                else fail "Impossible case in scan_spec."
                end
      fmt_string = match_data.post_match
    else
      @specs << FormatLiteral.new(fmt_string)
      fmt_string = ""
    end
  end
end

#validate(engine) ⇒ Object

Validate the specs of this format against the engine.



64
65
66
67
# File 'lib/format_engine/format_spec.rb', line 64

def validate(engine)
  specs.each {|item| item.validate(engine)}
  self
end