UNPKG

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