1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
# -*- coding: utf-8 -*- #
# frozen_string_literal: true
module Rouge
module Lexers
class Puppet < RegexLexer
title "Puppet"
desc 'The Puppet configuration management language (puppetlabs.org)'
tag 'puppet'
aliases 'pp'
filenames '*.pp'
def self.detect?(text)
return true if text.shebang? 'puppet-apply'
return true if text.shebang? 'puppet'
end
def self.keywords
@keywords ||= Set.new %w(
and case class default define else elsif if in import inherits
node unless
)
end
def self.constants
@constants ||= Set.new %w(
false true undef
)
end
def self.metaparameters
@metaparameters ||= Set.new %w(
before require notify subscribe
)
end
id = /[a-z]\w*/
cap_id = /[A-Z]\w*/
qualname = /(::)?(#{id}::)*\w+/
state :whitespace do
rule %r/\s+/m, Text
rule %r/#.*?\n/, Comment
end
state :root do
mixin :whitespace
rule %r/[$]#{qualname}/, Name::Variable
rule %r/(#{id})(?=\s*[=+]>)/m do |m|
if self.class.metaparameters.include? m[0]
token Keyword::Pseudo
else
token Name::Property
end
end
rule %r/(#{qualname})(?=\s*[(])/m, Name::Function
rule cap_id, Name::Class
rule %r/[+=|~-]>|<[|~-]/, Punctuation
rule %r/[|:}();\[\]]/, Punctuation
# HACK for case statements and selectors
rule %r/{/, Punctuation, :regex_allowed
rule %r/,/, Punctuation, :regex_allowed
rule %r/(in|and|or)\b/, Operator::Word
rule %r/[=!<>]=/, Operator
rule %r/[=!]~/, Operator, :regex_allowed
rule %r([.=<>!+*/-]), Operator
rule %r/(class|include)(\s*)(#{qualname})/ do
groups Keyword, Text, Name::Class
end
rule %r/node\b/, Keyword, :regex_allowed
rule %r/'(\\[\\']|[^'])*'/m, Str::Single
rule %r/"/, Str::Double, :dquotes
rule %r/\d+([.]\d+)?(e[+-]\d+)?/, Num
# a valid regex. TODO: regexes are only allowed
# in certain places in puppet.
rule qualname do |m|
if self.class.keywords.include? m[0]
token Keyword
elsif self.class.constants.include? m[0]
token Keyword::Constant
else
token Name
end
end
end
state :regex_allowed do
mixin :whitespace
rule %r(/), Str::Regex, :regex
rule(//) { pop! }
end
state :regex do
rule %r(/), Str::Regex, :pop!
rule %r/\\./, Str::Escape
rule %r/[(){}]/, Str::Interpol
rule %r/\[/, Str::Interpol, :regex_class
rule %r/./, Str::Regex
end
state :regex_class do
rule %r/\]/, Str::Interpol, :pop!
rule %r/(?<!\[)-(?=\])/, Str::Regex
rule %r/-/, Str::Interpol
rule %r/\\./, Str::Escape
rule %r/[^\\\]-]+/, Str::Regex
end
state :dquotes do
rule %r/"/, Str::Double, :pop!
rule %r/[^$\\"]+/m, Str::Double
rule %r/\\./m, Str::Escape
rule %r/[$]#{qualname}/, Name::Variable
rule %r/[$][{]#{qualname}[}]/, Name::Variable
end
end
end
end
|