Skip to content

Commit e86ec01

Browse files
committed
Add whitespace-normalizer plugin
This plugin normalizes whitespace in code blocks. It can perform various operations. The user can configure them through the plugin object located at Prism.plugins.NormalizeWhitespace. Prism.plugins.NormalizeWhitespace.setDefaults({ 'remove-trailing': true, 'remove-indent': true, 'left-trim': true, 'right-trim': true, /*'indent': 2, 'remove-initial-line-feed': false, 'tabs-to-spaces': 4, 'spaces-to-tabs': 4*/ }); The plugin can be disabled for certain code blocks, by adding the class "no-whitespace-normalization" to it. There is also a HTML-interface using the parse-settings plugin.
1 parent dfa5263 commit e86ec01

File tree

6 files changed

+267
-1
lines changed

6 files changed

+267
-1
lines changed

components.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,11 @@ var components = {
607607
"command-line": {
608608
"title": "Command Line",
609609
"owner": "chriswells0"
610+
},
611+
"normalize-whitespace": {
612+
"title": "Normalize Whitespace",
613+
"owner": "zeitgeist87",
614+
"noCSS": true
610615
}
611616
}
612617
};
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<body data-prism data-remove-trailing="true">
2+
<section id="main" class="language-javascript" data-right-trim="true">
3+
4+
<pre>
5+
6+
<code data-left-trim="true">
7+
8+
9+
var example = {
10+
foo: true,
11+
12+
bar: false
13+
};
14+
15+
16+
</code>
17+
18+
</pre>
19+
20+
</section>
21+
<script src="plugins/normalize-whitespace/prism-normalize-whitespace.js"></script>
22+
<script type="text/javascript">
23+
Prism.plugins.NormalizeWhitespace.setDefaults({
24+
'remove-trailing': false,
25+
'left-trim': false,
26+
'right-trim': false
27+
});
28+
</script>
29+
</body>
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
5+
<meta charset="utf-8" />
6+
<link rel="shortcut icon" href="favicon.png" />
7+
<title>Normalize Whitespace ▲ Prism plugins</title>
8+
<base href="../.." />
9+
<link rel="stylesheet" href="style.css" />
10+
<link rel="stylesheet" href="themes/prism.css" data-noprefix />
11+
<script src="prefixfree.min.js"></script>
12+
13+
<script>var _gaq = [['_setAccount', 'UA-33746269-1'], ['_trackPageview']];</script>
14+
<script src="http://www.google-analytics.com/ga.js" async></script>
15+
</head>
16+
<body>
17+
18+
<header>
19+
<div class="intro" data-src="templates/header-plugins.html" data-type="text/html"></div>
20+
21+
<h2>Normalize Whitespace</h2>
22+
<p>Supports multiple operations to normalize whitespace in code blocks.</p>
23+
</header>
24+
25+
<section class="language-markup">
26+
<h1>How to use</h1>
27+
28+
<p>Obviously, this is supposed to work only for code blocks (<code>&lt;pre>&lt;code></code>) and not for inline code.</p>
29+
<p>By default the plugin trims all leading and trailing whitespace of every code block.
30+
It also removes extra indents and trailing whitespace on every line.</p>
31+
32+
<p>The plugin uses the <a href="plugins/parse-settings/">Parse Settings</a> plugin to get its settings.
33+
The default settings can be overridden with the <code class="language-javascript">setDefaults()</code> method
34+
like so:</p>
35+
36+
<pre class="language-javascript"><code>
37+
Prism.plugins.NormalizeWhitespace.setDefaults({
38+
'remove-trailing': true,
39+
'remove-indent': true,
40+
'left-trim': true,
41+
'right-trim': true,
42+
/*'indent': 2,
43+
'remove-initial-line-feed': false,
44+
'tabs-to-spaces': 4,
45+
'spaces-to-tabs': 4*/
46+
});
47+
</code></pre>
48+
49+
<p>It is also possible to change the default settings with <code>data-*</code>-attributes.</p>
50+
51+
<pre><code>&lt;code data-left-trim="false">...&lt;/code></code></pre>
52+
53+
<p>The class <code>no-whitespace-normalization</code> or the corresponding
54+
data-attribute can be used to disable the normalization for a particular
55+
code block.</p>
56+
57+
<pre><code>&lt;code class="no-whitespace-normalization"
58+
data-whitespace-normalization="false">
59+
...
60+
&lt;/code></code></pre>
61+
</section>
62+
63+
<section class="language-markup">
64+
<h1>Examples</h1>
65+
66+
<p>The following example shows some of the possible ways of configuring this plugin:</p>
67+
68+
<pre data-src="plugins/normalize-whitespace/demo.html"></pre>
69+
70+
<p>The result looks like this:</p>
71+
72+
<pre class="language-javascript">
73+
74+
<code>
75+
76+
77+
var example = {
78+
foo: true,
79+
80+
bar: false
81+
};
82+
83+
84+
</code>
85+
86+
</pre>
87+
88+
</section>
89+
90+
<footer data-src="templates/footer.html" data-type="text/html"></footer>
91+
92+
<script src="prism.js"></script>
93+
<script src="plugins/parse-settings/prism-parse-settings.js"></script>
94+
<script src="plugins/normalize-whitespace/prism-normalize-whitespace.js"></script>
95+
<script src="utopia.js"></script>
96+
<script src="components.js"></script>
97+
<script src="code.js"></script>
98+
99+
100+
</body>
101+
</html>
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
(function() {
2+
3+
if (typeof self === 'undefined' || !self.Prism || !self.document) {
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+
return obj1;
13+
}
14+
15+
function NormalizeWhitespace(defaults) {
16+
this.defaults = assign({}, defaults);
17+
}
18+
19+
function toCamelCase(value) {
20+
return value.replace(/-(\w)/g, function(match, firstChar) {
21+
return firstChar.toUpperCase();
22+
});
23+
}
24+
25+
NormalizeWhitespace.prototype = {
26+
setDefaults: function (defaults) {
27+
this.defaults = assign(this.defaults, defaults);
28+
},
29+
normalize: function (input, settings) {
30+
settings = assign(this.defaults, settings);
31+
32+
for (var name in settings) {
33+
var methodName = toCamelCase(name);
34+
if (name !== "normalize" && methodName !== 'setDefaults' &&
35+
settings[name] && this[methodName]) {
36+
input = this[methodName].call(this, input, settings[name]);
37+
}
38+
}
39+
40+
return input;
41+
},
42+
43+
/*
44+
* Normalization methods
45+
*/
46+
leftTrim: function (input) {
47+
return input.replace(/^\s+/, '');
48+
},
49+
rightTrim: function (input) {
50+
return input.replace(/\s+$/, '');
51+
},
52+
tabsToSpaces: function (input, spaces) {
53+
spaces = spaces|0 || 4;
54+
return input.replace(/\t/g, new Array(++spaces).join(' '));
55+
},
56+
spacesToTabs: function (input, spaces) {
57+
spaces = spaces|0 || 4;
58+
return input.replace(new RegExp(' {' + spaces + '}', 'g'), '\t');
59+
},
60+
removeTrailing: function (input) {
61+
return input.replace(/\s*?$/gm, '');
62+
},
63+
// Support for deprecated plugin remove-initial-line-feed
64+
removeInitialLineFeed: function (input) {
65+
return input.replace(/^(?:\r?\n|\r)/, '');
66+
},
67+
removeIndent: function (input) {
68+
var indents = input.match(/^[^\S\n\r]*(?=\S)/gm);
69+
70+
if (!indents || !indents[0].length)
71+
return input;
72+
73+
indents.sort(function(a, b){return a.length - b.length; });
74+
75+
if (!indents[0].length)
76+
return input;
77+
78+
return input.replace(new RegExp('^' + indents[0], 'gm'), '');
79+
},
80+
indent: function (input, tabs) {
81+
return input.replace(/^[^\S\n\r]*(?=\S)/gm, new Array(++tabs).join('\t') + '$&');
82+
}
83+
};
84+
85+
Prism.plugins.NormalizeWhitespace = new NormalizeWhitespace({
86+
'remove-trailing': true,
87+
'remove-indent': true,
88+
'left-trim': true,
89+
'right-trim': true,
90+
/*'indent': 2,
91+
'remove-initial-line-feed': false,
92+
'tabs-to-spaces': 4,
93+
'spaces-to-tabs': 4*/
94+
});
95+
96+
Prism.hooks.add('before-highlight', function (env) {
97+
var pre = env.element.parentNode;
98+
if (!env.code || !pre || pre.nodeName.toLowerCase() !== 'pre' ||
99+
(env.settings && env.settings['whitespace-normalization'] === false))
100+
return;
101+
102+
var children = pre.childNodes,
103+
before = '',
104+
after = '',
105+
codeFound = false;
106+
107+
// Move surrounding whitespace from the <pre> tag into the <code> tag
108+
for (var i = 0; i < children.length; ++i) {
109+
var node = children[i];
110+
111+
if (node == env.element) {
112+
codeFound = true;
113+
} else if (node.nodeName === "#text") {
114+
if (codeFound) {
115+
after += node.nodeValue;
116+
} else {
117+
before += node.nodeValue;
118+
}
119+
120+
pre.removeChild(node);
121+
--i;
122+
}
123+
}
124+
env.code = before + env.code + after;
125+
126+
env.code = Prism.plugins.NormalizeWhitespace.normalize(env.code, env.settings);
127+
});
128+
129+
}());

plugins/normalize-whitespace/prism-normalize-whitespace.min.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugins/remove-initial-line-feed/index.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ <h2>Remove initial line feed</h2>
2323
</header>
2424

2525
<section class="language-markup">
26-
<h1>How to use</h1>
26+
<h1>How to use (DEPRECATED)</h1>
2727

28+
<p>This plugin will be removed in the future. Please use the general purpose <a href="plugins/normalize-whitespace/">Normalize Whitespace</a> plugin instead.</p>
2829
<p>Obviously, this is supposed to work only for code blocks (<code>&lt;pre>&lt;code></code>) and not for inline code.</p>
2930
<p>With this plugin included, any initial line feed will be removed by default.</p>
3031
<p>To bypass this behaviour, you may add the class <strong>keep-initial-line-feed</strong> to your desired <code>&lt;pre></code>.</p>

0 commit comments

Comments
 (0)