Class: Webgen::Utils::TagParser
- Inherits:
-
Object
- Object
- Webgen::Utils::TagParser
- Defined in:
- lib/webgen/utils/tag_parser.rb
Overview
This class is used to parse a string for webgen tags and replace them with dynamically generated content. See #replace_tags for more information.
Defined Under Namespace
Classes: Error, ProcessingStruct
Constant Summary collapse
- BRACKETS_RE =
:nodoc:
/([{}])/
Instance Method Summary collapse
-
#initialize(prefix = nil) ⇒ TagParser
constructor
Create a new TagParser object, optionally providing a tag prefix.
-
#parse_params(param_string, tag) ⇒ Object
Parse the parameter string and return the result.
-
#replace_tags(content) ⇒ Object
Return the
content
with all webgen tags replaced.
Constructor Details
#initialize(prefix = nil) ⇒ TagParser
Create a new TagParser object, optionally providing a tag prefix.
24 25 26 27 |
# File 'lib/webgen/utils/tag_parser.rb', line 24 def initialize(prefix = nil) @start_re = /(\\*)\{#{prefix}(\w+)(::?)/ @end_re = /(\\*)\{#{prefix}(\w+)\}/ end |
Instance Method Details
#parse_params(param_string, tag) ⇒ Object
Parse the parameter string and return the result.
115 116 117 118 119 |
# File 'lib/webgen/utils/tag_parser.rb', line 115 def parse_params(param_string, tag) YAML::load("--- #{param_string}") rescue ArgumentError, SyntaxError, YAML::SyntaxError => e raise Error.new("Could not parse parameter string '#{param_string}' for tag '#{tag}': #{e.}") end |
#replace_tags(content) ⇒ Object
Return the content
with all webgen tags replaced.
When a webgen tag is encountered by the parser, the method yields all found information and substitutes the returned string for the tag.
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 |
# File 'lib/webgen/utils/tag_parser.rb', line 37 def (content) #:yields: tag_name, params, body scanner = StringScanner.new(content) data = ProcessingStruct.new(:before_tag) while true case data.state when :before_tag if scanner.skip_until(@start_re) data.state = :in_start_tag data.backslashes = scanner[1].length data.brackets = 1 data.tag = scanner[2] data.simple_tag = (scanner[3] == ':') data.params_start_pos = scanner.pos data.start_pos = scanner.pos - scanner.matched.length else data.state = :done end when :in_start_tag data.brackets += (scanner[1] == '{' ? 1 : -1) while data.brackets != 0 && scanner.skip_until(BRACKETS_RE) if data.brackets != 0 raise Error.new("Unbalanced curly brackets found for tag '#{data.tag}'") else data.params_end_pos = data.body_end_pos = data.end_pos = scanner.pos - 1 data.state = (data.simple_tag ? :process : :in_body) end when :process begin enc = scanner.string.encoding scanner.string.force_encoding('ASCII-8BIT') if data.backslashes % 2 == 0 params = parse_params(scanner.string[data.params_start_pos...data.params_end_pos].force_encoding(enc), data.tag) result = yield(data.tag, params, scanner.string[(data.params_end_pos+1)...data.body_end_pos].to_s.force_encoding(enc)) result = result.to_s.force_encoding('ASCII-8BIT') scanner.string[data.start_pos..data.end_pos] = "\\" * (data.backslashes / 2) + result scanner.pos = data.start_pos + result.length else scanner.string[data.start_pos, 1 + data.backslashes / 2] = '' scanner.pos -= 1 + data.backslashes / 2 end ensure scanner.string.force_encoding(enc) end data.state = :before_tag when :in_body while (result = scanner.skip_until(@end_re)) next unless scanner[2] == data.tag if scanner[1].length % 2 == 1 scanner.string[(scanner.pos - scanner.matched.length), 1 + scanner[1].length / 2] = '' scanner.pos -= 1 + scanner[1].length / 2 else break end end if result data.state = :process data.end_pos = scanner.pos - 1 data.body_end_pos = scanner.pos - scanner.matched.length + scanner[1].length / 2 else raise Error.new("Invalid body part - no end tag found for '#{data.tag}'") end when :done break end end scanner.string rescue Error => e e.line = scanner.string[0...data.start_pos].scan("\n").size + 1 e.column = data.start_pos - (scanner.string.rindex("\n", data.start_pos) || -1) raise end |