Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Allow multiple instances of Shortcode with independent configurations * specs work with multiple instances version now, still need to write more tests * added spec for multiple shortcode instances * made the include helpers backwards compatible * get the haml template rendering spec to pass * Updated readme and changelog * Update README.md
- Loading branch information
1 parent
12c7aed
commit 93c6a4e
Showing
19 changed files
with
319 additions
and
170 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,43 +1,73 @@ | ||
class Shortcode::Parser < Parslet::Parser | ||
class Shortcode::Parser | ||
def initialize(configuration) | ||
@configuration = configuration | ||
setup_rules | ||
end | ||
|
||
rule(:block_tag) { match_any_of Shortcode.configuration.block_tags } | ||
rule(:self_closing_tag) { match_any_of Shortcode.configuration.self_closing_tags } | ||
def parse(string) | ||
klass_instance.parse(string) | ||
end | ||
|
||
rule(:quotes) { str(Shortcode.configuration.attribute_quote_type) } | ||
def open(*args) | ||
klass_instance.open(*args) | ||
end | ||
|
||
rule(:space) { str(' ').repeat(1) } | ||
rule(:space?) { space.maybe } | ||
rule(:newline) { (str("\r\n") | str("\n")) >> space? } | ||
rule(:newline?) { newline.maybe } | ||
rule(:whitespace) { (space | newline).repeat(1) } | ||
private | ||
|
||
rule(:key) { match('[a-zA-Z0-9\-_]').repeat(1) } | ||
# This allows us to create a new class with the rules for the specific configuration | ||
def klass | ||
@klass ||= Class.new(Parslet::Parser) | ||
end | ||
|
||
rule(:value_with_quotes) { quotes >> (quotes.absent? >> any).repeat.as(:value) >> quotes } | ||
rule(:value_without_quotes) { quotes.absent? >> ( (str(']') | whitespace).absent? >> any ).repeat.as(:value) } | ||
rule(:value) { Shortcode.configuration.use_attribute_quotes ? value_with_quotes : (value_without_quotes | value_with_quotes) } | ||
def klass_instance | ||
@klass_instance ||= klass.new | ||
end | ||
|
||
rule(:option) { key.as(:key) >> str('=') >> value } | ||
rule(:options) { (str(' ') >> option).repeat(1) } | ||
rule(:options?) { options.repeat(0, 1) } | ||
def setup_rules | ||
define_match_any_of | ||
|
||
rule(:open) { str('[') >> block_tag.as(:open) >> options?.as(:options) >> str(']') >> newline? } | ||
rule(:close) { str('[/') >> block_tag.as(:close) >> str(']') >> newline? } | ||
rule(:open_close) { str('[') >> self_closing_tag.as(:open_close) >> options?.as(:options) >> str(']') >> newline? } | ||
shortcode_configuration = @configuration | ||
klass.rule(:block_tag) { match_any_of shortcode_configuration.block_tags } | ||
klass.rule(:self_closing_tag) { match_any_of shortcode_configuration.self_closing_tags } | ||
|
||
rule(:text) { ((close | block | open_close).absent? >> any).repeat(1).as(:text) } | ||
rule(:block) { (open >> (block | text | open_close).repeat.as(:inner) >> close) } | ||
klass.rule(:quotes) { str(shortcode_configuration.attribute_quote_type) } | ||
|
||
rule(:body) { (block | text | open_close).repeat.as(:body) } | ||
root(:body) | ||
klass.rule(:space) { str(' ').repeat(1) } | ||
klass.rule(:space?) { space.maybe } | ||
klass.rule(:newline) { (str("\r\n") | str("\n")) >> space? } | ||
klass.rule(:newline?) { newline.maybe } | ||
klass.rule(:whitespace) { (space | newline).repeat(1) } | ||
|
||
private | ||
klass.rule(:key) { match('[a-zA-Z0-9\-_]').repeat(1) } | ||
|
||
klass.rule(:value_with_quotes) { quotes >> (quotes.absent? >> any).repeat.as(:value) >> quotes } | ||
klass.rule(:value_without_quotes) { quotes.absent? >> ( (str(']') | whitespace).absent? >> any ).repeat.as(:value) } | ||
klass.rule(:value) { shortcode_configuration.use_attribute_quotes ? value_with_quotes : (value_without_quotes | value_with_quotes) } | ||
|
||
klass.rule(:option) { key.as(:key) >> str('=') >> value } | ||
klass.rule(:options) { (str(' ') >> option).repeat(1) } | ||
klass.rule(:options?) { options.repeat(0, 1) } | ||
|
||
def match_any_of(tags) | ||
return str('') if tags.length < 1 | ||
tags.map{ |tag| str(tag) }.inject do |tag_chain, tag| | ||
tag_chain.send :|, tag | ||
klass.rule(:open) { str('[') >> block_tag.as(:open) >> options?.as(:options) >> str(']') >> newline? } | ||
klass.rule(:close) { str('[/') >> block_tag.as(:close) >> str(']') >> newline? } | ||
klass.rule(:open_close) { str('[') >> self_closing_tag.as(:open_close) >> options?.as(:options) >> str(']') >> newline? } | ||
|
||
klass.rule(:text) { ((close | block | open_close).absent? >> any).repeat(1).as(:text) } | ||
klass.rule(:block) { (open >> (block | text | open_close).repeat.as(:inner) >> close) } | ||
|
||
klass.rule(:body) { (block | text | open_close).repeat.as(:body) } | ||
klass.root(:body) | ||
end | ||
|
||
def define_match_any_of | ||
klass.send(:define_method, :match_any_of) do |tags| | ||
if tags.length < 1 | ||
return str('') | ||
else | ||
tags.map{ |tag| str(tag) }.inject do |tag_chain, tag| | ||
tag_chain.send :|, tag | ||
end | ||
end | ||
end | ||
|
||
end | ||
end |
Oops, something went wrong.