Skip to content

Commit

Permalink
Add whitespace-normalizer plugin
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
zeitgeist87 committed Jan 7, 2016
1 parent dfa5263 commit e86ec01
Show file tree
Hide file tree
Showing 6 changed files with 267 additions and 1 deletion.
5 changes: 5 additions & 0 deletions components.js
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,11 @@ var components = {
"command-line": {
"title": "Command Line",
"owner": "chriswells0"
},
"normalize-whitespace": {
"title": "Normalize Whitespace",
"owner": "zeitgeist87",
"noCSS": true
}
}
};
29 changes: 29 additions & 0 deletions plugins/normalize-whitespace/demo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<body data-prism data-remove-trailing="true">
<section id="main" class="language-javascript" data-right-trim="true">

<pre>

<code data-left-trim="true">


var example = {
foo: true,

bar: false
};


</code>

</pre>

</section>
<script src="plugins/normalize-whitespace/prism-normalize-whitespace.js"></script>
<script type="text/javascript">
Prism.plugins.NormalizeWhitespace.setDefaults({
'remove-trailing': false,
'left-trim': false,
'right-trim': false
});
</script>
</body>
101 changes: 101 additions & 0 deletions plugins/normalize-whitespace/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<!DOCTYPE html>
<html lang="en">
<head>

<meta charset="utf-8" />
<link rel="shortcut icon" href="favicon.png" />
<title>Normalize Whitespace ▲ Prism plugins</title>
<base href="../.." />
<link rel="stylesheet" href="style.css" />
<link rel="stylesheet" href="themes/prism.css" data-noprefix />
<script src="prefixfree.min.js"></script>

<script>var _gaq = [['_setAccount', 'UA-33746269-1'], ['_trackPageview']];</script>
<script src="http://www.google-analytics.com/ga.js" async></script>
</head>
<body>

<header>
<div class="intro" data-src="templates/header-plugins.html" data-type="text/html"></div>

<h2>Normalize Whitespace</h2>
<p>Supports multiple operations to normalize whitespace in code blocks.</p>
</header>

<section class="language-markup">
<h1>How to use</h1>

<p>Obviously, this is supposed to work only for code blocks (<code>&lt;pre>&lt;code></code>) and not for inline code.</p>
<p>By default the plugin trims all leading and trailing whitespace of every code block.
It also removes extra indents and trailing whitespace on every line.</p>

<p>The plugin uses the <a href="plugins/parse-settings/">Parse Settings</a> plugin to get its settings.
The default settings can be overridden with the <code class="language-javascript">setDefaults()</code> method
like so:</p>

<pre class="language-javascript"><code>
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*/
});
</code></pre>

<p>It is also possible to change the default settings with <code>data-*</code>-attributes.</p>

<pre><code>&lt;code data-left-trim="false">...&lt;/code></code></pre>

<p>The class <code>no-whitespace-normalization</code> or the corresponding
data-attribute can be used to disable the normalization for a particular
code block.</p>

<pre><code>&lt;code class="no-whitespace-normalization"
data-whitespace-normalization="false">
...
&lt;/code></code></pre>
</section>

<section class="language-markup">
<h1>Examples</h1>

<p>The following example shows some of the possible ways of configuring this plugin:</p>

<pre data-src="plugins/normalize-whitespace/demo.html"></pre>

<p>The result looks like this:</p>

<pre class="language-javascript">

<code>


var example = {
foo: true,

bar: false
};


</code>

</pre>

</section>

<footer data-src="templates/footer.html" data-type="text/html"></footer>

<script src="prism.js"></script>
<script src="plugins/parse-settings/prism-parse-settings.js"></script>
<script src="plugins/normalize-whitespace/prism-normalize-whitespace.js"></script>
<script src="utopia.js"></script>
<script src="components.js"></script>
<script src="code.js"></script>


</body>
</html>
129 changes: 129 additions & 0 deletions plugins/normalize-whitespace/prism-normalize-whitespace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
(function() {

if (typeof self === 'undefined' || !self.Prism || !self.document) {
return;
}

var assign = Object.assign || function (obj1, obj2) {
for (var name in obj2) {
if (obj2.hasOwnProperty(name))
obj1[name] = obj2[name];
}
return obj1;
}

function NormalizeWhitespace(defaults) {
this.defaults = assign({}, defaults);
}

function toCamelCase(value) {
return value.replace(/-(\w)/g, function(match, firstChar) {
return firstChar.toUpperCase();
});
}

NormalizeWhitespace.prototype = {
setDefaults: function (defaults) {
this.defaults = assign(this.defaults, defaults);
},
normalize: function (input, settings) {
settings = assign(this.defaults, settings);

for (var name in settings) {
var methodName = toCamelCase(name);
if (name !== "normalize" && methodName !== 'setDefaults' &&
settings[name] && this[methodName]) {
input = this[methodName].call(this, input, settings[name]);
}
}

return input;
},

/*
* Normalization methods
*/
leftTrim: function (input) {
return input.replace(/^\s+/, '');
},
rightTrim: function (input) {
return input.replace(/\s+$/, '');
},
tabsToSpaces: function (input, spaces) {
spaces = spaces|0 || 4;
return input.replace(/\t/g, new Array(++spaces).join(' '));
},
spacesToTabs: function (input, spaces) {
spaces = spaces|0 || 4;
return input.replace(new RegExp(' {' + spaces + '}', 'g'), '\t');
},
removeTrailing: function (input) {
return input.replace(/\s*?$/gm, '');
},
// Support for deprecated plugin remove-initial-line-feed
removeInitialLineFeed: function (input) {
return input.replace(/^(?:\r?\n|\r)/, '');
},
removeIndent: function (input) {
var indents = input.match(/^[^\S\n\r]*(?=\S)/gm);

if (!indents || !indents[0].length)
return input;

indents.sort(function(a, b){return a.length - b.length; });

if (!indents[0].length)
return input;

return input.replace(new RegExp('^' + indents[0], 'gm'), '');
},
indent: function (input, tabs) {
return input.replace(/^[^\S\n\r]*(?=\S)/gm, new Array(++tabs).join('\t') + '$&');
}
};

Prism.plugins.NormalizeWhitespace = new NormalizeWhitespace({
'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*/
});

Prism.hooks.add('before-highlight', function (env) {
var pre = env.element.parentNode;
if (!env.code || !pre || pre.nodeName.toLowerCase() !== 'pre' ||
(env.settings && env.settings['whitespace-normalization'] === false))
return;

var children = pre.childNodes,
before = '',
after = '',
codeFound = false;

// Move surrounding whitespace from the <pre> tag into the <code> tag
for (var i = 0; i < children.length; ++i) {
var node = children[i];

if (node == env.element) {
codeFound = true;
} else if (node.nodeName === "#text") {
if (codeFound) {
after += node.nodeValue;
} else {
before += node.nodeValue;
}

pre.removeChild(node);
--i;
}
}
env.code = before + env.code + after;

env.code = Prism.plugins.NormalizeWhitespace.normalize(env.code, env.settings);
});

}());

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion plugins/remove-initial-line-feed/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ <h2>Remove initial line feed</h2>
</header>

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

<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>
<p>Obviously, this is supposed to work only for code blocks (<code>&lt;pre>&lt;code></code>) and not for inline code.</p>
<p>With this plugin included, any initial line feed will be removed by default.</p>
<p>To bypass this behaviour, you may add the class <strong>keep-initial-line-feed</strong> to your desired <code>&lt;pre></code>.</p>
Expand Down

0 comments on commit e86ec01

Please sign in to comment.