# -*- coding: utf-8 -*- # # frozen_string_literal: true module Rouge module Lexers class Jinja < TemplateLexer title "Jinja" desc "Django/Jinja template engine (jinja.pocoo.org)" tag 'jinja' aliases 'django' mimetypes 'application/x-django-templating', 'application/x-jinja', 'text/html+django', 'text/html+jinja' def self.keywords @@keywords ||= %w(as context do else extends from ignore missing import include reversed recursive scoped autoescape endautoescape block endblock call endcall filter endfilter for endfor if endif macro endmacro set endset trans endtrans with endwith without) end def self.tests @@tests ||= %w(callable defined divisibleby equalto escaped even iterable lower mapping none number odd sameas sequence string undefined upper) end def self.pseudo_keywords @@pseudo_keywords ||= %w(true false none True False None) end def self.word_operators @@word_operators ||= %w(is in and or not) end state :root do # Comments rule %r/{#/, Comment, :comment # Statements rule %r/\{\%/ do token Comment::Preproc push :statement end # Expressions rule %r/\{\{/ do token Comment::Preproc push :expression end rule(/(.+?)(?=\\|{{|{%|{#)/m) { delegate parent } rule(/.+/m) { delegate parent } end state :filter do # Filters are called like variable|foo(arg1, ...) rule %r/(\|)(\w+)/ do groups Operator, Name::Function end end state :function do rule %r/(\w+)(\()/ do groups Name::Function, Punctuation end end state :text do rule %r/\s+/m, Text end state :literal do # Strings rule %r/"(\\.|.)*?"/, Str::Double rule %r/'(\\.|.)*?'/, Str::Single # Numbers rule %r/\d+(?=}\s)/, Num # Arithmetic operators (+, -, *, **, //, /) # TODO : implement modulo (%) rule %r/(\+|\-|\*|\/\/?|\*\*?|=)/, Operator # Comparisons operators (<=, <, >=, >, ==, ===, !=) rule %r/(<=?|>=?|===?|!=)/, Operator # Punctuation (the comma, [], ()) rule %r/,/, Punctuation rule %r/\[/, Punctuation rule %r/\]/, Punctuation rule %r/\(/, Punctuation rule %r/\)/, Punctuation end state :comment do rule(/[^{#]+/m) { token Comment } rule(/#}/) { token Comment; pop! } end state :expression do rule %r/\w+\.?/m, Name::Variable mixin :filter mixin :function mixin :literal mixin :text rule %r/%}|}}/, Comment::Preproc, :pop! end state :statement do rule %r/(raw|verbatim)(\s+)(\%\})/ do groups Keyword, Text, Comment::Preproc goto :raw end rule %r/(\w+\.?)/ do |m| if self.class.keywords.include?(m[0]) groups Keyword elsif self.class.pseudo_keywords.include?(m[0]) groups Keyword::Pseudo elsif self.class.word_operators.include?(m[0]) groups Operator::Word elsif self.class.tests.include?(m[0]) groups Name::Builtin else groups Name::Variable end end mixin :filter mixin :function mixin :literal mixin :text rule %r/\%\}/, Comment::Preproc, :pop! end state :raw do rule %r{(\{\%)(\s+)(endverbatim|endraw)(\s+)(\%\})} do groups Comment::Preproc, Text, Keyword, Text, Comment::Preproc pop! end rule %r/(.+?)/m, Text end end end end