Class: Qipowl::Bowlers::Bowler
- Includes:
- TypoLogging
- Defined in:
- lib/qipowl/core/bowler.rb
Overview
Base class for all the parsers.
Technically it may be instantiated, but that’s meaningless. Main operation method for it and all the descendants is #parse. It sequentially executes following private methods:
- #defreeze
- #roast
- #serveup
Normally the developer does not need to interfere the #roast method which proceeds the input string. To prepare the input for +evaluation+ one overwrites #defreeze, for some afterwork the #serveup method is here.
Descendants are supposed to overwrite #method_missing for some
custom processing and introduce DSL methods, which will be executed
by eval inside the #roast method.
Instance variables :in and :out are here to gain an access to
the last interpreted input string and the result of evaluation
respectively.
Constant Summary collapse
- SEPARATOR =
Internal constant for joining/splitting the strings during processing. Override on your own risk. I can′t imagine why you would need to do so.
$, || ' '
Instance Attribute Summary collapse
-
#in ⇒ Object
readonly
Returns the value of attribute in.
-
#out ⇒ Object
readonly
Returns the value of attribute out.
Class Method Summary collapse
-
.const_missing(name) ⇒ Object
Everything is a DSL, remember? Even constants.
Instance Method Summary collapse
-
#add_entity(section, key, value, enclosure_value = null) ⇒ Object
Adds new +entity+ in the section specified.
-
#block(str) ⇒ Object
private
Prepares blocks in the input for the execution.
-
#custom(str) ⇒ Object
private
Prepares customs in the input for the execution.
- #execute(str) ⇒ Object
-
#grip(str) ⇒ Object
private
Prepares grips in the input for the execution FIX<E There is a problem: we append a trailing space, need to remove it later!!.
-
#method_missing(method, *args, &block) ⇒ Object
If somebody needs to interfere the standard processing, she supposed to introduce
special_handlermethod. -
#remove_entity(key) ⇒ Object
Removes key from both Mapping.SPICES and Mapping.SALT.
-
#respond_to?(method) ⇒ Boolean
Everything is a DSL, remember?.
- #split(str) ⇒ Object private
Methods included from TypoLogging
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object
If somebody needs to interfere the standard processing,
she supposed to introduce special_handler method. The descendants
will be processed before standard operation (which in fact simply
collects words within an array one by one.)
66 67 68 69 70 |
# File 'lib/qipowl/core/bowler.rb', line 66 def method_missing method, *args, &block method, *args = special_handler(method, *args, &block) \ if self.private_methods.include?(:special_handler) [method, args].flatten end |
Instance Attribute Details
#in ⇒ Object (readonly)
Returns the value of attribute in.
36 37 38 |
# File 'lib/qipowl/core/bowler.rb', line 36 def in @in end |
#out ⇒ Object (readonly)
Returns the value of attribute out.
36 37 38 |
# File 'lib/qipowl/core/bowler.rb', line 36 def out @out end |
Class Method Details
.const_missing(name) ⇒ Object
This fails to do with DSLing words, beginning with capitals :-(
Everything is a DSL, remember? Even constants.
57 58 59 60 |
# File 'lib/qipowl/core/bowler.rb', line 57 def self.const_missing name raise "There was CONST [#{name}] met. Stupid programming error." name end |
Instance Method Details
#add_entity(section, key, value, enclosure_value = null) ⇒ Object
Adds new +entity+ in the section specified. E. g., call to
add_spice :linewide, :°, :deg, :degrees
in HTML implementation adds a support for specifying something like:
° 15
° 30
° 45
which is to be converted to the following:
<degrees>
<deg>15</deg>
<deg>30</deg>
<deg>45</deg>
</degrees>
95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/qipowl/core/bowler.rb', line 95 def add_entity section, key, value, enclosure_value = null if ( = self.class.const_get("#{section.upcase}_TAGS")) key = key.bowl.to_sym [key] = value.to_sym self.class.const_get("ENCLOSURES_TAGS")[key] = enclosure_value.to_sym if enclosure_value self.class.class_eval %Q{ alias_method :#{key}, :∀_#{section} } # unless self.class.instance_methods(true).include?(key.bowl) else logger.warn "Trying to add key “#{key}” in an invalid section “#{section}”. Ignoring…" end end |
#block(str) ⇒ Object (private)
Prepares blocks in the input for the execution
206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/qipowl/core/bowler.rb', line 206 def block str result = str.dup self.class::BLOCK_TAGS.each { |tag, value| result.gsub!(/(#{tag})\s*(\S*\s*|$)(.*?)(#{tag}|\Z)/m) { %Q{ #{$1}('#{$2.strip}', '#{$3.carriage}') } } } result end |
#custom(str) ⇒ Object (private)
Prepares customs in the input for the execution
221 222 223 224 225 226 227 |
# File 'lib/qipowl/core/bowler.rb', line 221 def custom str result = str.unbowl.dup self.class::CUSTOM_TAGS.each { |tag, value| result.gsub!(/#{tag}/, value) } result.bowl end |
#execute(str) ⇒ Object
42 43 44 |
# File 'lib/qipowl/core/bowler.rb', line 42 def execute str @out = (serveup roast defreeze @in = str) end |
#grip(str) ⇒ Object (private)
Prepares grips in the input for the execution FIX<E There is a problem: we append a trailing space, need to remove it later!!
231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/qipowl/core/bowler.rb', line 231 def grip str result = str.dup self.class::GRIP_TAGS.each { |tag, value| result.gsub!(/(?:#{tag})(.*?)(?:#{tag})/m) { next if (args = $1).vacant? tag = value[:marker] if Hash === value && value[:marker] "⌦ #{tag} #{args}#{tag}∎⌫" } } result end |
#remove_entity(key) ⇒ Object
Removes key from both Mapping.SPICES and Mapping.SALT. See #add_spice
111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/qipowl/core/bowler.rb', line 111 def remove_entity key %w(block alone magnet grip regular).each { |section| next unless send :"∃_#{section}_tag", key.to_sym self.class.const_get("#{section.upcase}_TAGS").delete key self.class.const_get("ENCLOSURES_TAGS").delete key self.class.class_eval %Q{ remove_method :#{key.bowl} } } end |
#respond_to?(method) ⇒ Boolean
Everything is a DSL, remember?
49 50 51 |
# File 'lib/qipowl/core/bowler.rb', line 49 def respond_to?(method) true end |
#split(str) ⇒ Object (private)
243 244 245 246 247 248 |
# File 'lib/qipowl/core/bowler.rb', line 243 def split str (block str.bowl).split(/\R{2,}/).map { |para| para =~ /\A(#{self.class::BLOCK_TAGS.keys.join('|')})\(/ ? para : (grip custom para) } end |