Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Avatar for KuCalc : devops.
Download
50665 views
1
CodeMirror.defineMode("puppet", function () {
2
// Stores the words from the define method
3
var words = {};
4
// Taken, mostly, from the Puppet official variable standards regex
5
var variable_regex = /({)?([a-z][a-z0-9_]*)?((::[a-z][a-z0-9_]*)*::)?[a-zA-Z0-9_]+(})?/;
6
7
// Takes a string of words separated by spaces and adds them as
8
// keys with the value of the first argument 'style'
9
function define(style, string) {
10
var split = string.split(' ');
11
for (var i = 0; i < split.length; i++) {
12
words[split[i]] = style;
13
}
14
}
15
16
// Takes commonly known puppet types/words and classifies them to a style
17
define('keyword', 'class define site node include import inherits');
18
define('keyword', 'case if else in and elsif default or');
19
define('atom', 'false true running present absent file directory undef');
20
define('builtin', 'action augeas burst chain computer cron destination dport exec ' +
21
'file filebucket group host icmp iniface interface jump k5login limit log_level ' +
22
'log_prefix macauthorization mailalias maillist mcx mount nagios_command ' +
23
'nagios_contact nagios_contactgroup nagios_host nagios_hostdependency ' +
24
'nagios_hostescalation nagios_hostextinfo nagios_hostgroup nagios_service ' +
25
'nagios_servicedependency nagios_serviceescalation nagios_serviceextinfo ' +
26
'nagios_servicegroup nagios_timeperiod name notify outiface package proto reject ' +
27
'resources router schedule scheduled_task selboolean selmodule service source ' +
28
'sport ssh_authorized_key sshkey stage state table tidy todest toports tosource ' +
29
'user vlan yumrepo zfs zone zpool');
30
31
// After finding a start of a string ('|") this function attempts to find the end;
32
// If a variable is encountered along the way, we display it differently when it
33
// is encapsulated in a double-quoted string.
34
function tokenString(stream, state) {
35
var current, prev, found_var = false;
36
while (!stream.eol() && (current = stream.next()) != state.pending) {
37
if (current === '$' && prev != '\\' && state.pending == '"') {
38
found_var = true;
39
break;
40
}
41
prev = current;
42
}
43
if (found_var) {
44
stream.backUp(1);
45
}
46
if (current == state.pending) {
47
state.continueString = false;
48
} else {
49
state.continueString = true;
50
}
51
return "string";
52
}
53
54
// Main function
55
function tokenize(stream, state) {
56
// Matches one whole word
57
var word = stream.match(/[\w]+/, false);
58
// Matches attributes (i.e. ensure => present ; 'ensure' would be matched)
59
var attribute = stream.match(/(\s+)?\w+\s+=>.*/, false);
60
// Matches non-builtin resource declarations
61
// (i.e. "apache::vhost {" or "mycustomclasss {" would be matched)
62
var resource = stream.match(/(\s+)?[\w:_]+(\s+)?{/, false);
63
// Matches virtual and exported resources (i.e. @@user { ; and the like)
64
var special_resource = stream.match(/(\s+)?[@]{1,2}[\w:_]+(\s+)?{/, false);
65
66
// Finally advance the stream
67
var ch = stream.next();
68
69
// Have we found a variable?
70
if (ch === '$') {
71
if (stream.match(variable_regex)) {
72
// If so, and its in a string, assign it a different color
73
return state.continueString ? 'variable-2' : 'variable';
74
}
75
// Otherwise return an invalid variable
76
return "error";
77
}
78
// Should we still be looking for the end of a string?
79
if (state.continueString) {
80
// If so, go through the loop again
81
stream.backUp(1);
82
return tokenString(stream, state);
83
}
84
// Are we in a definition (class, node, define)?
85
if (state.inDefinition) {
86
// If so, return def (i.e. for 'class myclass {' ; 'myclass' would be matched)
87
if (stream.match(/(\s+)?[\w:_]+(\s+)?/)) {
88
return 'def';
89
}
90
// Match the rest it the next time around
91
stream.match(/\s+{/);
92
state.inDefinition = false;
93
}
94
// Are we in an 'include' statement?
95
if (state.inInclude) {
96
// Match and return the included class
97
stream.match(/(\s+)?\S+(\s+)?/);
98
state.inInclude = false;
99
return 'def';
100
}
101
// Do we just have a function on our hands?
102
// In 'ensure_resource("myclass")', 'ensure_resource' is matched
103
if (stream.match(/(\s+)?\w+\(/)) {
104
stream.backUp(1);
105
return 'def';
106
}
107
// Have we matched the prior attribute regex?
108
if (attribute) {
109
stream.match(/(\s+)?\w+/);
110
return 'tag';
111
}
112
// Do we have Puppet specific words?
113
if (word && words.hasOwnProperty(word)) {
114
// Negates the initial next()
115
stream.backUp(1);
116
// Acutally move the stream
117
stream.match(/[\w]+/);
118
// We want to process these words differently
119
// do to the importance they have in Puppet
120
if (stream.match(/\s+\S+\s+{/, false)) {
121
state.inDefinition = true;
122
}
123
if (word == 'include') {
124
state.inInclude = true;
125
}
126
// Returns their value as state in the prior define methods
127
return words[word];
128
}
129
// Is there a match on a reference?
130
if (/(\s+)?[A-Z]/.test(word)) {
131
// Negate the next()
132
stream.backUp(1);
133
// Match the full reference
134
stream.match(/(\s+)?[A-Z][\w:_]+/);
135
return 'def';
136
}
137
// Have we matched the prior resource regex?
138
if (resource) {
139
stream.match(/(\s+)?[\w:_]+/);
140
return 'def';
141
}
142
// Have we matched the prior special_resource regex?
143
if (special_resource) {
144
stream.match(/(\s+)?[@]{1,2}/);
145
return 'special';
146
}
147
// Match all the comments. All of them.
148
if (ch == "#") {
149
stream.skipToEnd();
150
return "comment";
151
}
152
// Have we found a string?
153
if (ch == "'" || ch == '"') {
154
// Store the type (single or double)
155
state.pending = ch;
156
// Perform the looping function to find the end
157
return tokenString(stream, state);
158
}
159
// Match all the brackets
160
if (ch == '{' || ch == '}') {
161
return 'bracket';
162
}
163
// Match characters that we are going to assume
164
// are trying to be regex
165
if (ch == '/') {
166
stream.match(/.*\//);
167
return 'variable-3';
168
}
169
// Match all the numbers
170
if (ch.match(/[0-9]/)) {
171
stream.eatWhile(/[0-9]+/);
172
return 'number';
173
}
174
// Match the '=' and '=>' operators
175
if (ch == '=') {
176
if (stream.peek() == '>') {
177
stream.next();
178
}
179
return "operator";
180
}
181
// Keep advancing through all the rest
182
stream.eatWhile(/[\w-]/);
183
// Return a blank line for everything else
184
return null;
185
}
186
// Start it all
187
return {
188
startState: function () {
189
var state = {};
190
state.inDefinition = false;
191
state.inInclude = false;
192
state.continueString = false;
193
state.pending = false;
194
return state;
195
},
196
token: function (stream, state) {
197
// Strip the spaces, but regex will account for them eitherway
198
if (stream.eatSpace()) return null;
199
// Go through the main process
200
return tokenize(stream, state);
201
}
202
};
203
});
204
CodeMirror.defineMIME("text/x-puppet", "puppet");
205
206