UNPKG

4.83 kBJavaScriptView Raw
1(function () {
2
3 if (typeof Prism === 'undefined') {
4 return;
5 }
6
7 var assign = Object.assign || function (obj1, obj2) {
8 for (var name in obj2) {
9 if (obj2.hasOwnProperty(name)) {
10 obj1[name] = obj2[name];
11 }
12 }
13 return obj1;
14 };
15
16 function NormalizeWhitespace(defaults) {
17 this.defaults = assign({}, defaults);
18 }
19
20 function toCamelCase(value) {
21 return value.replace(/-(\w)/g, function (match, firstChar) {
22 return firstChar.toUpperCase();
23 });
24 }
25
26 function tabLen(str) {
27 var res = 0;
28 for (var i = 0; i < str.length; ++i) {
29 if (str.charCodeAt(i) == '\t'.charCodeAt(0)) {
30 res += 3;
31 }
32 }
33 return str.length + res;
34 }
35
36 NormalizeWhitespace.prototype = {
37 setDefaults: function (defaults) {
38 this.defaults = assign(this.defaults, defaults);
39 },
40 normalize: function (input, settings) {
41 settings = assign(this.defaults, settings);
42
43 for (var name in settings) {
44 var methodName = toCamelCase(name);
45 if (name !== 'normalize' && methodName !== 'setDefaults' &&
46 settings[name] && this[methodName]) {
47 input = this[methodName].call(this, input, settings[name]);
48 }
49 }
50
51 return input;
52 },
53
54 /*
55 * Normalization methods
56 */
57 leftTrim: function (input) {
58 return input.replace(/^\s+/, '');
59 },
60 rightTrim: function (input) {
61 return input.replace(/\s+$/, '');
62 },
63 tabsToSpaces: function (input, spaces) {
64 spaces = spaces|0 || 4;
65 return input.replace(/\t/g, new Array(++spaces).join(' '));
66 },
67 spacesToTabs: function (input, spaces) {
68 spaces = spaces|0 || 4;
69 return input.replace(RegExp(' {' + spaces + '}', 'g'), '\t');
70 },
71 removeTrailing: function (input) {
72 return input.replace(/\s*?$/gm, '');
73 },
74 // Support for deprecated plugin remove-initial-line-feed
75 removeInitialLineFeed: function (input) {
76 return input.replace(/^(?:\r?\n|\r)/, '');
77 },
78 removeIndent: function (input) {
79 var indents = input.match(/^[^\S\n\r]*(?=\S)/gm);
80
81 if (!indents || !indents[0].length) {
82 return input;
83 }
84
85 indents.sort(function (a, b) { return a.length - b.length; });
86
87 if (!indents[0].length) {
88 return input;
89 }
90
91 return input.replace(RegExp('^' + indents[0], 'gm'), '');
92 },
93 indent: function (input, tabs) {
94 return input.replace(/^[^\S\n\r]*(?=\S)/gm, new Array(++tabs).join('\t') + '$&');
95 },
96 breakLines: function (input, characters) {
97 characters = (characters === true) ? 80 : characters|0 || 80;
98
99 var lines = input.split('\n');
100 for (var i = 0; i < lines.length; ++i) {
101 if (tabLen(lines[i]) <= characters) {
102 continue;
103 }
104
105 var line = lines[i].split(/(\s+)/g);
106 var len = 0;
107
108 for (var j = 0; j < line.length; ++j) {
109 var tl = tabLen(line[j]);
110 len += tl;
111 if (len > characters) {
112 line[j] = '\n' + line[j];
113 len = tl;
114 }
115 }
116 lines[i] = line.join('');
117 }
118 return lines.join('\n');
119 }
120 };
121
122 // Support node modules
123 if (typeof module !== 'undefined' && module.exports) {
124 module.exports = NormalizeWhitespace;
125 }
126
127 Prism.plugins.NormalizeWhitespace = new NormalizeWhitespace({
128 'remove-trailing': true,
129 'remove-indent': true,
130 'left-trim': true,
131 'right-trim': true,
132 /*'break-lines': 80,
133 'indent': 2,
134 'remove-initial-line-feed': false,
135 'tabs-to-spaces': 4,
136 'spaces-to-tabs': 4*/
137 });
138
139 Prism.hooks.add('before-sanity-check', function (env) {
140 var Normalizer = Prism.plugins.NormalizeWhitespace;
141
142 // Check settings
143 if (env.settings && env.settings['whitespace-normalization'] === false) {
144 return;
145 }
146
147 // Check classes
148 if (!Prism.util.isActive(env.element, 'whitespace-normalization', true)) {
149 return;
150 }
151
152 // Simple mode if there is no env.element
153 if ((!env.element || !env.element.parentNode) && env.code) {
154 env.code = Normalizer.normalize(env.code, env.settings);
155 return;
156 }
157
158 // Normal mode
159 var pre = env.element.parentNode;
160 if (!env.code || !pre || pre.nodeName.toLowerCase() !== 'pre') {
161 return;
162 }
163
164 var children = pre.childNodes;
165 var before = '';
166 var after = '';
167 var codeFound = false;
168
169 // Move surrounding whitespace from the <pre> tag into the <code> tag
170 for (var i = 0; i < children.length; ++i) {
171 var node = children[i];
172
173 if (node == env.element) {
174 codeFound = true;
175 } else if (node.nodeName === '#text') {
176 if (codeFound) {
177 after += node.nodeValue;
178 } else {
179 before += node.nodeValue;
180 }
181
182 pre.removeChild(node);
183 --i;
184 }
185 }
186
187 if (!env.element.children.length || !Prism.plugins.KeepMarkup) {
188 env.code = before + env.code + after;
189 env.code = Normalizer.normalize(env.code, env.settings);
190 } else {
191 // Preserve markup for keep-markup plugin
192 var html = before + env.element.innerHTML + after;
193 env.element.innerHTML = Normalizer.normalize(html, env.settings);
194 env.code = env.element.textContent;
195 }
196 });
197
198}());