Class: Mustache::Parser
- Inherits:
-
Object
- Object
- Mustache::Parser
- Defined in:
- lib/mustache/parser.rb
Overview
The Parser is responsible for taking a string template and converting it into an array of tokens and, really, expressions. It raises SyntaxError if there is anything it doesn’t understand and knows which sigil corresponds to which tag type.
For example, given this template:
Hi {{thing}}!
Run through the Parser we’ll get these tokens:
[:multi,
[:static, "Hi "],
[:mustache, :etag, "thing"],
[:static, "!\n"]]
You can see the array of tokens for any template with the mustache(1) command line tool:
$ mustache --tokens test.mustache
[:multi, [:static, "Hi "], [:mustache, :etag, "thing"], [:static, "!\n"]]
Defined Under Namespace
Classes: SyntaxError
Constant Summary collapse
- VALID_TYPES =
The sigil types which are valid after an opening ‘{{`
[ '#', '^', '/', '=', '!', '<', '>', '&', '{' ].map(&:freeze)
- SKIP_WHITESPACE =
After these types of tags, all whitespace until the end of the line will be skipped if they are the first (and only) non-whitespace content on the line.
[ '#', '^', '/', '<', '>', '=', '!' ].map(&:freeze)
- ALLOWED_CONTENT =
The content allowed in a tag name.
/(\w|[?!\/.-])*/
- ANY_CONTENT =
These types of tags allow any content, the rest only allow ALLOWED_CONTENT.
[ '!', '=' ].map(&:freeze)
Instance Attribute Summary collapse
-
#ctag ⇒ Object
Returns the value of attribute ctag.
-
#otag ⇒ Object
Returns the value of attribute otag.
Class Method Summary collapse
-
.add_type(*types, &block) ⇒ Object
Add a supported sigil type (with optional aliases) to the Parser.
- .valid_types ⇒ Object
Instance Method Summary collapse
-
#compile(template) ⇒ Object
Given a string template, returns an array of tokens.
-
#initialize(options = {}) ⇒ Parser
constructor
Accepts an options hash which does nothing but may be used in the future.
Constructor Details
#initialize(options = {}) ⇒ Parser
Accepts an options hash which does nothing but may be used in the future.
91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/mustache/parser.rb', line 91 def initialize( = {}) @options = @option_inline_partials_at_compile_time = [:inline_partials_at_compile_time] if @option_inline_partials_at_compile_time @partial_resolver = [:partial_resolver] raise ArgumentError.new "Missing or invalid partial_resolver" unless @partial_resolver.respond_to? :call end # Initialize default tags self.otag ||= '{{' self.ctag ||= '}}' end |
Instance Attribute Details
#ctag ⇒ Object
Returns the value of attribute ctag.
87 88 89 |
# File 'lib/mustache/parser.rb', line 87 def ctag @ctag end |
#otag ⇒ Object
Returns the value of attribute otag.
87 88 89 |
# File 'lib/mustache/parser.rb', line 87 def otag @otag end |
Class Method Details
.add_type(*types, &block) ⇒ Object
Add a supported sigil type (with optional aliases) to the Parser.
Requires a block, which will be sent the following parameters:
-
content - The raw content of the tag
-
fetch- A mustache context fetch expression for the content
-
padding - Indentation whitespace from the currently-parsed line
-
pre_match_position - Location of the scanner before a match was made
The provided block will be evaluated against the current instance of Parser, and may append to the Parser’s @result as needed.
65 66 67 68 69 70 71 72 73 |
# File 'lib/mustache/parser.rb', line 65 def self.add_type(*types, &block) types = types.map(&:to_s) type, *aliases = types method_name = "scan_tag_#{type}".to_sym define_method(method_name, &block) aliases.each { |a| alias_method "scan_tag_#{a}", method_name } types.each { |t| VALID_TYPES << t unless VALID_TYPES.include?(t) } @valid_types = nil end |
.valid_types ⇒ Object
50 51 52 |
# File 'lib/mustache/parser.rb', line 50 def self.valid_types @valid_types ||= Regexp.new(VALID_TYPES.map { |t| Regexp.escape(t) }.join('|') ) end |
Instance Method Details
#compile(template) ⇒ Object
Given a string template, returns an array of tokens.
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/mustache/parser.rb', line 119 def compile(template) @encoding = nil if template.respond_to?(:encoding) @encoding = template.encoding template = template.dup.force_encoding("BINARY") end # Keeps information about opened sections. @sections = [] @result = [:multi] @scanner = StringScanner.new(template) # Scan until the end of the template. until @scanner.eos? || scan_text end unless @sections.empty? # We have parsed the whole file, but there's still opened sections. type, pos, _ = @sections.pop error "Unclosed section #{type.inspect}", pos end @result end |