# @Opulent module Opulent # Opulent KEYWORDS KEYWORDS = [ :def, :yield, :include, :if, :else, :elsif, :unless, :case, :when, :each, :while, :until, :doctype ].freeze # @Tokens class Tokens # All tokens available within Opulent # @tokens = { # Indentation indent: /\A\s*/, # Node node: /\A\w+(\-\w+)*/, node_lookahead: /\A(\w+(\-\w+)*)/, # Shorthand attributes shorthand: /\A[\.\#\&]/, shorthand_node: /\A\-?\w+(\-\w+)*/, shorthand_lookahead: /\A[\.\#\&][a-zA-Z\-\_\(\"]/, # Leading and trailing whitespace leading_whitespace: /\A(\')/, trailing_whitespace: /\A(\")/, # Self enclosing node self_enclosing: %r{\A\/(.*)}, # Definition def: /\Adef +/, # Definition doctype: /\Adoctype */, # Include file include: /\Ainclude +/, # Node Attributes attributes_bracket: /\A\(\[\{/, extend_attributes: /\A(\+)/, # Attribute assignments assignment: /\A *(\:|\=)/, assignment_unescaped: /\A\~/, assignment_terminator: /\A(\,|\;)\s*/, assignment_lookahead: /\A *([a-zA-Z]([\-\_]?[a-zA-Z0-9]+)* *[\:\=] *)/, # Node inline child inline_child: /\A *\> */, # Comments comment: /\A\//, # Intepreted filters filter: /\A\:[a-zA-Z]([\-\_]?[a-zA-Z0-9]+)*/, # Print nodes print: /\A\=/, print_lookahead: /\A *=/, # Unescaped value unescaped_value: /\A\~/, # Multiline Text multiline: /\A(\|)/, # HTML Text html_text: /\A\<.+\>.*/, # Yield yield: /\A(yield)/, # Conditional Structures control: /\A(if|elsif|else|unless|case|when|each|while|until)/, each_pattern: /\A(.+) +do *\|(.+)\|/, # Text text: /\A\|/, # Brackets round_bracket: /\A(\()/, square_bracket: /\A(\[)/, curly_bracket: /\A(\{)/, angular_bracket: /\A(\<)/, # Receive matching brackets for allowing multiple bracket types for # element attributes brackets: /\A([\(\[\{])/, :'(' => /\A(\))/, :'[' => /\A(\])/, :'{' => /\A(\})/, :'<' => /\A(\>)/, # Terminators comma: /\A(\s*\,\s*)/, colon: /\A(\s*\:\s*)/, semicolon: /\A(\s*\;\s*)/, # Expression exp_context: /\A(\$(.|\-.)?|\@|\@\@)/, exp_method_call: /\A(\.[a-zA-Z\_][a-zA-Z0-9\_]*[\!\?]?)/, exp_module: /\A(\:\:)/, exp_identifier: /\A([a-zA-Z\_][a-zA-Z0-9\_]*[\!\?]?)/, exp_assignment: /\A(\=)/, exp_operation: /\A( *(\+|\-|\*\*|\*|\/|\<\<|\>\>|\.\.|\%|\<\=\>|\<\=|\^|\<|\>\=|\>|\=\~|\!\~|\=\=\=|\=\=|\!|not|\&\&|\&|and|\|\||\||or) *)/, exp_regex: /\A(\/((?:[^\/\\]|\\.)*?)\/)/, exp_string: /\A(("((?:[^"\\]|\\.)*?)")|('(?:[^'\\]|\\.)*?'))/, exp_string_match: /\A(("((?:[^"\\]|\\.)*?)")|('(?:[^'\\]|\\.)*?'))\Z/, exp_percent: /\A(\%[wWqQrxsiI]?.)/, exp_double: /\A([0-9]+\.[0-9]+([eE][-+]?[0-9]+)?)/, exp_fixnum: /\A([0-9]+)/, exp_nil: /\A(nil)/, exp_boolean: /\A(true|false)/, exp_ternary: /\A( *\? *)/, exp_ternary_else: /\A( *\: *)/, exp_identifier_lookahead: /\A[a-zA-Z\_][a-zA-Z0-9\_]*[\!\?]?/, exp_identifier_stripped_lookahead: /\A *[a-zA-Z\_][a-zA-Z0-9\_]*[\!\?]?/, # Hash hash_terminator: /\A(\s*(\,)\s*)/, hash_assignment: /\A(\s*(\=\>)\s*)/, hash_symbol: /\A([a-zA-Z\_][a-zA-Z0-9\_]*\:(?!\:))/, # Whitespace whitespace: /\A\s+/, # Recursive Node Definitions recursive: /\A\*/, # Evaluation eval: /\A\-/, # Whitespace newline: /\A(\n+)/, # Feed line_feed: /\A(.*)/, line_whitespace: /\A\s*\Z/ } # Return the matching closing bracket # # @param bracket [String] Opening bracket for the capture group # def self.bracket(bracket) case bracket when '(' then return ')' when '[' then return ']' when '{' then return '}' when '<' then return '>' end end # Return the requested token to the parser # # @param name [Symbol] Token requested by the parser accept method # def self.[](name) @tokens[name] end # Set a new token at runtime # # @param name [Symboidentifierl] Identifier for the token # @param token [Token] Token data to be set # def self.[]=(name, token) @tokens[name] = token end end end