# -*- coding: utf-8 -*- # # frozen_string_literal: true module Rouge module Lexers class Liquid < RegexLexer title "Liquid" desc 'Liquid is a templating engine for Ruby (liquidmarkup.org)' tag 'liquid' filenames '*.liquid' state :root do rule %r/[^\{]+/, Text rule %r/(\{%-?)(\s*)/ do groups Punctuation, Text::Whitespace push :tag_or_block end rule %r/(\{\{-?)(\s*)/ do groups Punctuation, Text::Whitespace push :output end rule %r/\{/, Text end state :tag_or_block do # builtin logic blocks rule %r/(if|elsif|unless|case)\b/, Keyword::Reserved, :condition rule %r/(when)\b/, Keyword::Reserved, :when rule %r/(else)(\s*)(-?%\})/ do groups Keyword::Reserved, Text::Whitespace, Punctuation pop! end # other builtin blocks rule %r/(capture|(?:in|de)crement)(\s+)([^\s%]+)(\s*)(-?%\})/ do groups Name::Tag, Text::Whitespace, Name::Variable, Text::Whitespace, Punctuation pop! end rule %r/(comment)(\s*)(-?%\})/ do groups Name::Tag, Text::Whitespace, Punctuation push :comment end rule %r/(raw)(\s*)(-?%\})/ do groups Name::Tag, Text::Whitespace, Punctuation push :raw end # end of block rule %r/(end(?:if|unless|case))(\s*)(-?%\})/ do groups Keyword::Reserved, Text::Whitespace, Punctuation pop! end rule %r/(end(?:[^\s%]+))(\s*)(-?%\})/ do groups Name::Tag, Text::Whitespace, Punctuation pop! end # builtin tags rule %r/(assign|echo)\b/, Name::Tag, :assign rule %r/(include|render)\b/, Name::Tag, :include rule %r/(cycle)(\s+)(?:([^\s:]*)(\s*)(:))?(\s*)/ do |m| token_class = case m[3] when %r/'[^']*'/ then Str::Single when %r/"[^"]*"/ then Str::Double else Name::Attribute end groups Name::Tag, Text::Whitespace, token_class, Text::Whitespace, Punctuation, Text::Whitespace push :variable_tag_markup end # iteration rule %r/ (for|tablerow)(\s+) ([\w-]+)(\s+) (in)(\s+) ( (?: [^\s%,\|'"] | (?:"[^"]*"|'[^']*') )+ )(\s*) /x do |m| groups Name::Tag, Text::Whitespace, Name::Variable, Text::Whitespace, Name::Tag, Text::Whitespace token_class = case m[7] when %r/'[^']*'/ then Str::Single when %r/"[^"]*"/ then Str::Double else Name::Variable end token token_class, m[7] token Text::Whitespace, m[8] push :tag_markup end # other tags or blocks rule %r/([^\s%]+)(\s*)/ do groups Name::Tag, Text::Whitespace push :tag_markup end end state :output do rule %r/(\|)(\s*)([a-zA-Z_][^\s}\|:]*)/ do groups Punctuation, Text::Whitespace, Name::Function push :filters end mixin :end_of_tag mixin :generic end state :filters do rule %r/(\|)(\s*)([a-zA-Z_][^\s%}\|:]*)/ do groups Punctuation, Text::Whitespace, Name::Function end mixin :end_of_tag mixin :end_of_block mixin :variable_param_markup end state :condition do rule %r/([=!]=|[<>]=?)/, Operator rule %r/(and|or|contains)\b/, Operator::Word mixin :end_of_block mixin :generic end state :when do mixin :end_of_block mixin :generic end state :end_of_tag do rule(/-?\}\}/) { token Punctuation; reset_stack } end state :end_of_block do rule(/-?%\}/) { token Punctuation; reset_stack } end # states for unknown markup state :param_markup do mixin :whitespace mixin :keyword mixin :string mixin :number rule %r/([^\s=:]+)(\s*)(=|:)/ do groups Name::Attribute, Text::Whitespace, Operator end rule %r/[,:]/, Punctuation end state :default_param_markup do mixin :param_markup rule %r/\S+/, Text end state :variable_param_markup do mixin :param_markup mixin :variable rule %r/\S+/, Text end state :tag_markup do rule %r/(reversed)\b/, Name::Attribute mixin :end_of_block mixin :default_param_markup end state :variable_tag_markup do mixin :end_of_block mixin :variable_param_markup end # states for different values types state :keyword do rule %r/(false|true|nil)\b/, Keyword::Constant end state :variable do rule %r/(empty|blank|forloop\.[^\s%}\|:]+)\b/, Name::Builtin rule %r/\.(?=\w)|\[|\]/, Punctuation rule %r/(first|last|size)\b/, Name::Function rule %r/[a-zA-Z_][\w-]*\??/, Name::Variable end state :string do rule %r/'[^']*'/, Str::Single rule %r/"[^"]*"/, Str::Double end state :number do rule %r/-/, Operator rule %r/\d+\.\d+/, Num::Float rule %r/\d+/, Num::Integer end state :generic do mixin :whitespace mixin :keyword mixin :string mixin :number mixin :variable end state :whitespace do rule %r/[ \t]+/, Text::Whitespace end state :comment do rule %r/[^\{]+/, Comment rule %r/(\{%-?)(\s*)(endcomment)(\s*)(-?%\})/ do groups Punctuation, Text::Whitespace, Name::Tag, Text::Whitespace, Punctuation reset_stack end rule %r/\{/, Comment end state :raw do rule %r/[^\{]+/, Text rule %r/(\{%-?)(\s*)(endraw)(\s*)(-?%\})/ do groups Punctuation, Text::Whitespace, Name::Tag, Text::Whitespace, Punctuation reset_stack end rule %r/\{/, Text end state :assign do rule %r/=/, Operator rule %r/(\|)(\s*)([a-zA-Z_][^\s%\|:]*)/ do groups Punctuation, Text::Whitespace, Name::Function push :filters end mixin :end_of_block mixin :generic end state :include do rule %r/(\{\{-?)(\s*)/ do groups Punctuation, Text::Whitespace push :output_embed end rule %r/(with|for)\b/, Name::Tag rule %r/[^\s\.]+(\.[^\s\.]+)+\b/, Name::Other mixin :variable_tag_markup end state :output_embed do rule %r/(\|)(\s*)([a-zA-Z_][^\s}\|:]*)/ do groups Punctuation, Text::Whitespace, Name::Function end rule %r/-?\}\}/, Punctuation, :pop! mixin :variable_param_markup end end end end