How it works
- <pre><code class="language-javascript">
CODE
</code></pre>
pick pick language – wrap code in it - add plug-in css – by adding tags to page
rainbow-braces
line-numbers
match-braces
no-brace-hover
var myObject = {
property1: "something",
property2: 5,
property3: true
};
{{{{{{{{}}}}}}}}
[[[[[[[[]]]]]]]]
((((((((((()))))))))))
<pre><code class="language-javascript">
var myObject = {
property1: "something",
property2: 5,
property3: true
};
</code></pre>
{{{{{{{{}}}}}}}}
[[[[[[[[]]]]]]]]
((((((((((()))))))))))
Use Categories to add the plugin calls – line-numbers / rainbow-brackets
then hide those from results – search / archive etc.
ENABLE PRISM IN – WordPress Classic Editor:
– it does nothing without the language selection::
That is correct. Prism.js requires that the code block specify a language. Otherwise there is nothing (no styles) to load. For plain blocks (with no language specified), it is up to your theme to provide styles, not Prismatic. You can learn more about Prism.js usage in the docs:
https://prismjs.com/#basic-usage
If you are still using the Classic WordPress editor, use this method for Prism JS in your blog posts.
While you are writing a blog post in the Classic editor using WordPress, simply use the “Text” tab. There are two tabs that you can choose from while writing a post – a “Visual” tab and a “Text” tab. The “Text” tab allows the writer to include their own HTML.
When you want to write a code block using the new Prism syntax highlighting that you just implemented, you will start your code block with the normal <pre><code> tags like you normally would. Except now, all you need to do is assign a class to your tag.
If the code block is going to be written in HTML, you would start it with <pre><code class="language-markup">. If it will be in JavaScript, it would be <pre><code class="language-javascript"> and so on.
Got it? Here’s an example. In order to get an example code block written in JavaScript to take on the syntax highlighting from Prism, this is the full code you would have to write in the text tab of your blog post.
var myObject = {
property1: "something",
property2: 5,
property3: true
};
That’s it! You now have the power of using Prism syntax highlighting on all of your code blocks written in either the WordPress Gutenberg editor or the Classic editor. This is perfect for developers or anyone who includes code snippets as a part of their posts.
then hide those from results – search / archive etc.
ENABLE PRISM IN – WordPress Classic Editor:
– it does nothing without the language selection::
That is correct. Prism.js requires that the code block specify a language. Otherwise there is nothing (no styles) to load. For plain blocks (with no language specified), it is up to your theme to provide styles, not Prismatic. You can learn more about Prism.js usage in the docs:
https://prismjs.com/#basic-usage
If you are still using the Classic WordPress editor, use this method for Prism JS in your blog posts.
While you are writing a blog post in the Classic editor using WordPress, simply use the “Text” tab. There are two tabs that you can choose from while writing a post – a “Visual” tab and a “Text” tab. The “Text” tab allows the writer to include their own HTML.
When you want to write a code block using the new Prism syntax highlighting that you just implemented, you will start your code block with the normal <pre><code> tags like you normally would. Except now, all you need to do is assign a class to your
tag.
If the code block is going to be written in HTML, you would start it with <pre><code class="language-markup">. If it will be in JavaScript, it would be <pre><code class="language-javascript"> and so on.
Got it? Here’s an example. In order to get an example code block written in JavaScript to take on the syntax highlighting from Prism, this is the full code you would have to write in the text tab of your blog post.
var myObject = {
property1: "something",
property2: 5,
property3: true
};
That’s it! You now have the power of using Prism syntax highlighting on all of your code blocks written in either the WordPress Gutenberg editor or the Classic editor. This is perfect for developers or anyone who includes code snippets as a part of their posts.
https://startblogging101.com/how-to-add-prism-js-syntax-highlighting-wordpress/
Are you wondering how to add syntax highlighting to your WordPress site and blog posts built with either the Gutenberg editor or the Classic editor?
Perhaps the regular code snippet styling in the Gutenberg or Classic editor is too boring and you want to share snippets that look like they came from an actual code editor (IDE)?
Well, you’re in luck, Prism.js syntax highlighting for WordPress has you covered.
Prism is a syntax highlighter that will prettify all of the code snippets you put on your WordPress blog posts or pages.
Not sure what I mean by a syntax highlighter or wondering what does a syntax highlighter do? Here’s an example.
Your code snippets will go from looking something like this:
const getURLParameters = url =>
(url.match(/([^?=&]+)(=([^&]*))/g) || []).reduce(
(a, v) => ((a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1)), a),
{}
);
// Examples
getURLParameters('http://url.com/page?n=Adam&s=Smith'); // {n: 'Adam', s: 'Smith'}
getURLParameters('google.com'); // {}
To this!
const getURLParameters = url =>
(url.match(/([^?=&]+)(=([^&]*))/g) || []).reduce(
(a, v) => ((a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1)), a),
{}
);
// Examples
getURLParameters('http://url.com/page?n=Adam&s=Smith'); // {n: 'Adam', s: 'Smith'}
getURLParameters('google.com'); // {}
Pretty neat, huh?
In this article, I will teach you how to implement Prism.js syntax highlighting into your WordPress site without a plugin.
You could install a plugin to give you syntax highlighting in your WordPress site, but I try to avoid adding plugins whenever possible so my site loads faster.
Best of all, Prism is very lightweight, so it won’t slow your site down. The core code is only 2KB in size when it is minified and gzipped which is tiny.
Prism is a lightweight, extensible syntax highlighter, built with modern web standards in mind.
Also, if you need anymore convincing that Prism is the best syntax highlighter for WordPress to use, I should note that many well-known sites use it including CSS Tricks, Stripe, Mozilla, and even React’s main site.
Follow the 5 steps below to learn how to add Prism.js syntax highlighting to your WordPress site:
TABLE OF CONTENTS
- 1. Choose Prism Options
- 2. Download Prism JS and CSS Files
- 3. Upload Prism Files to Child Theme
- 4. Add PHP Function to Load Prism
- 5. Use Prism in WordPress Gutenberg and Classic Editor
1. Choose Prism Options
First, go to the Prism download page. You’ll see a page like the one below:
Here, you will see a whole bunch of options that you can choose to customize how your code will look with Prism.
For the first section that says “Compression level”, choose “Minified version.” This will shorten the amount of text used in the background code, therefore allowing it to run quicker on your site.
Next, you will choose the Theme that you want to use. I chose the Okaidia theme, but feel free to choose whatever theme you think will look best with your site.
As you click on the various themes, you’ll notice that the code blocks above the “Download JS” and “Download CSS” buttons will change to give you an idea of how the code will look with your chosen theme.
Next, choose the languages that will be used within the code blocks on your site.
For me, I left the defaults checked which are Markup, CSS, C-like, and JavaScript. I also chose PHP because WordPress snippets of code are almost always written in PHP. That covers the vast majority of languages that I plan to show within my blog posts.
However, if you know for sure that you’ll be using Python, TypeScript, or SQL for example, just check any of those boxes. Keep in mind, though, that the more languages you have checked, the bigger your JavaScript and CSS files will be.
So, just make sure that you choose only the languages you need. You can always go back and add the background code for another language if you find out that you needed one that you didn’t get at first.
As far as plugins go, you can read about those yourself by checking out the “Plugins” section here.
The plugins give a little extra functionality if desired such as having line numbers show up in your code blocks or adding a “copy” button to the code so others can easily copy it. I personally chose the “Copy to Clipboard Button” plugin which you can see by hovering over any of the prettified code snippets on this page.
If you’re on desktop, check out the copy button when you hover over this code snippet:
let button = document.getElementById('clickMe');
button.addEventListener('click', function(e) {
e.preventDefault();
document.execCommand('copy', false, document.getElementById('select-this').select());
});
Now that you have all your Prism JS syntax highlighter options chosen, it’s time to move to Step 2!
2. Download Prism JS and CSS Files
For the second part, you will be downloading your Prism JS (JavaScript) and CSS (Cascading Style Sheets) files.
Once you have your compression level, languages, and plugins selected that you want, you are ready to download the files you’ll be putting on your site.
Click on the big “Download JS” and “Download CSS” buttons as shown at the end of Step 1 and save each of these files somewhere on your machine.
This will create a prism.js and prism.css file in your Downloads folder.
Now it’s time to take these synxtax highlighter JS and CSS files and upload them to your WordPress child theme which I will cover in Step 3.
3. Upload Prism Files to Child Theme
After your prism.js and prism.css files are downloaded, you are ready to upload these files to the back end of your site.
You will not be using WordPress for this part. You will be logging onto the back end of your hosting provider (whether that be SiteGround or whatever hosting company you use). For most hosting providers, you will be accessing cPanel.
If your hosting provider uses something other than cPanel, then simply go to the area where you can access your domain files.
After you are logged in to your hosting back end (in this case, cPanel), click on “File Manager”. SiteGround’s File Manager is shown here:
Once you click on “File Manager,” it may ask you which directory you want to go to. Choose “Document Root for {your website}” and click “Go”:
Now, path out to your theme’s folder. If you use a child theme (which you should be), path out to that theme’s directory. Or, if you’re just using a parent theme, go there.
You can find your theme’s folder by going to wp-content/themes/your-theme-name
.
For Start Blogging 101, I am using the Kadence theme along with a Kadence child theme. If you haven’t heard of the Kadence theme, you should read how the Kadence theme won my award for the best WordPress theme for 2020.
Since I am using the Kadence theme with a Kadence child theme, my child theme’s folder is located at wp-content/themes/kadence-child
.
Once you are in the appropriate theme folder (such as a child theme folder), you should see some files in there already such as style.css and a functions.php. This is the folder where you will be uploading the prism.css and prism.js files that you downloaded.
Now it’s time to upload your files.
Hit the “Upload” button as shown in the screenshot above. An upload page should open up. Browse out to the prism.css file that you have stored on your computer and choose that file.
If the upload page has a section for “Permissions,” just leave the default of 6-4-4 as seen below:
Now, do the exact same steps for your prism.js file.
Once that is complete, if you go back to where your directory was showing, you should see both the prism.css and prism.js files sitting in your child theme’s folder now as seen below:
Good job! Time to move on to Step 4.
4. Add PHP Function to Load Prism
Your Prism files are now uploaded to the back end of your site. Great! All we have left to do is to make sure they get loaded up in our site whenever a page of our site comes up in a browser. This will require some more work on the back end where we were just working.
Remember the folder we were just in? wp-content/themes/your-theme-name
? We will be working in that folder again. However, this is why it’s very important that YOU ARE USING A CHILD THEME because we will be working with the child theme’s functions.php file.
You should NEVER modify the parent theme’s functions.php file because it can mess up how your site works, and, after your theme updates, you will probably lose any work you did in your parent theme’s functions.php file.
Okay, now that I’ve made that clear, find the functions.php file in your child theme’s folder. In my case, it’s found in wp-content/themes/kadence-child
.
Right-click this file and choose “Edit”. After you do that, a box may appear saying that you should back up your file in case anything goes wrong. Feel free to back up the contents of the file somewhere if you feel like you’ll be messing things up.
However, chances are you haven’t even added anything to your child theme’s functions.php file yet which means there would be nothing to back up. Anyway, click “Edit” on that popup box.
A rather ugly text editor page should show up in your browser. If you have been in this file already, there may be text you’ve already written (or maybe the theme’s creator added some comments in there). Otherwise, it will be blank.
If the file is blank, it will look something like this:
<?php
/**
* Add custom functions here
*/
Here, you will be writing the code to have your Prism files load up whenever someone opens a page on your site.
I won’t get into huge detail here, but the proper way to include custom scripts and styles on your site (if you’re using WordPress) is to first register the file, and then enqueue it. You can read some great documentation on including CSS and JavaScript into your WordPress site here.
**Note: I am going to be showing you two different ways that you can include your Prism files on your site. The first way, it will load your Prism JS and CSS files on every single page on your website. This shouldn’t really slow anything down because the files are very small. However, the second way shows you how to conditionally load your Prism JS and CSS files so that they only load on certain pages and will be more performant.
In order to do this, we will write a simple PHP function right in our functions.php file. The first option loads your Prism files on every page of your website. The second option conditionally loads your Prism files only on certain pages so that they aren’t running when they don’t need to. I’ll explain both options below.
Option 1: Load Prism files on every page of your website
<?php
// Function to add prism.css and prism.js to the site
function add_prism() {
// Register prism.css file
wp_register_style(
'prismCSS', // handle name for the style
get_stylesheet_directory_uri() . '/prism.css' // location of the prism.css file
);
// Register prism.js file
wp_register_script(
'prismJS', // handle name for the script
get_stylesheet_directory_uri() . '/prism.js' // location of the prism.js file
);
// Enqueue the registered style and script files
wp_enqueue_style('prismCSS');
wp_enqueue_script('prismJS');
}
add_action('wp_enqueue_scripts', 'add_prism');
Option 2: Conditionally load Prism files only on blog posts that have a tag of “code”
<?php
/**
* Add custom functions here
*/
// Function to add prism.css and prism.js to the site
function add_prism() {
if ( is_single() && has_tag( 'code' ) ) {
// Register prism.css file
wp_register_style(
'prismCSS', // handle name for the style
get_stylesheet_directory_uri() . '/prism.css' // location of the prism.css file
);
// Register prism.js file
wp_register_script(
'prismJS', // handle name for the script
get_stylesheet_directory_uri() . '/prism.js' // location of the prism.js file
);
// Enqueue the registered style and script files
wp_enqueue_style('prismCSS');
wp_enqueue_script('prismJS');
}
}
add_action('wp_enqueue_scripts', 'add_prism');
**Note: If you know some PHP code, you do NOT need to include the closing ?>
PHP tag as this may cause errors on your page, so copy the files above exactly as you see them.
For Start Blogging 101, I personally used Option 2. The reason I used option 2 is because I only want to load my Prism files when absolutely necessary. It’s not necessarily a bad thing to have them load on every page since they are so small, but why load them on every page if you don’t have to?
In Option 2, notice the extra line that is added from Option 1. The added line is shown below:
if ( is_single() && has_tag( 'code' ) ) {
// function here
}
Using is_single()
means that I want the Prism files to load only on blog posts, so that means that my Home page and regular pages such as About and Contact don’t load the files – nice!
The second part && has_tag( 'code' )
means that I only want the files to load if it’s a blog post and there is a tag of “code” on my blog post. That way, I can very easily specifically target blog posts that have code snippets in them. It also means that the Prism files don’t load on blog posts that don’t need them such as ones with no code snippets.
If I write a blog post and want Prism to make my code snippets look pretty, now all I have to do is add a tag of “code” and follow the instructions in Step 5, and voila! The Prism files load only on that page, my code snippets are prettified, and everything looks beautiful.
5. Use Prism in WordPress Gutenberg and Classic Editor
After you save your changes on your functions.php file, you should be ready to rock n’ roll! The last part is actually using the syntax highlighter within one of your WordPress blog posts. I’ll show you how to use Prism JS in the WordPress Gutenberg editor and also the Classic editor if you’re still using that.
WordPress Gutenberg Editor:
If you are using the new WordPress Gutenberg editor, then follow the method below. Speaking of which, you should be using the new WordPress Gutenberg editor because the Classic editor will only be supported until the end of the year 2021.
In order to have your code snippets prettified by Prism JS using Gutenberg, simply add a code block by clicking on the + button and adding a code block otherwise you can type /code in your editor and a code block will show up.
Choose the code block and then type or paste the code that you want to show. It will initially look something like this:
<a href="https://startblogging101.com" target="_blank">Start Blogging 101</a>
Once you have your code written in your block, all you have to do now is give the code block the appropriate CSS class to get the Prism syntax highlighting to kick in.
With the code block in focus, go to your Settings button in the upper-right and find the Advanced tab at the very bottom of the right panel.
Expand the Advanced tab and you’ll see a text area for Addtional CSS Class(es). In here, type language- followed by whatever language your code is in.
For example, if it’s HTML code, you would type language-markup, if it’s JavaScript, you would type language-javascript, if it’s PHP, you would type language-php, and so on.
If you are unsure what you should put after the language- piece, check out the supported languages section on the PrismJS site.
After you give your code block the appropriate CSS class, you’re good to go!
Keep in mind, the code block will still look like the same boring code styling in your Gutenberg editor, but as soon as you Preview your blog post, you will see the code block transformed into Prism goodness! Your code block will now look like this:
<a href="https://startblogging101.com" target="_blank">Start Blogging 101</a>
Also, if you happen to use the inline code
option within your Gutenberg paragraphs, all you have to do is add the appropriate CSS class to your paragraph block.
Make sure the paragraph block is in focus, go to Settings, expand the Advanced section and add the appropriate language- CSS class to your paragraph and it will <strong>look like this</strong>
for all your inline code.
That’s all there is to it! You have now successfully implemented Prism JS syntax highlighting into your WordPress blog posts using the Gutenberg editor.
WordPress Classic Editor:
If you are still using the Classic WordPress editor, use this method for Prism JS in your blog posts.
While you are writing a blog post in the Classic editor using WordPress, simply use the “Text” tab. There are two tabs that you can choose from while writing a post – a “Visual” tab and a “Text” tab. The “Text” tab allows the writer to include their own HTML.
When you want to write a code block using the new Prism syntax highlighting that you just implemented, you will start your code block with the normal <pre><code>
tags like you normally would. Except now, all you need to do is assign a class to your <code>
tag.
If the code block is going to be written in HTML, you would start it with <pre><code class="language-markup">
. If it will be in JavaScript, it would be <pre><code class="language-javascript">
and so on.
Got it? Here’s an example. In order to get an example code block written in JavaScript to take on the syntax highlighting from Prism, this is the full code you would have to write in the text tab of your blog post.
<pre><code class="language-javascript">
var myObject = {
property1: "something",
property2: 5,
property3: true
};
</code></pre>
RAINBOW BRACES - body.rainbow-braces
style="white-space:pre-wrap;"
soft wrap code - css
line numbers::
Add the line-numbers
class to your desired <pre>
or any of its ancestors, and the Line Numbers plugin will take care of the rest. To give all code blocks line numbers, add the line-numbers
class to the <body>
of the page. This is part of a general activation mechanism where adding the line-numbers
(or no-line-numbers
) class to any element will enable (or disable) the Line Numbers plugin for all code blocks in that element.
Rainbow braces 🌈
To enable rainbow braces, simply add the rainbow-braces
class to a code block. This class can also get inherited.
https://prismjs.com/plugins/match-braces/#how-to-use
To enable this plugin add the match-braces
class to a code block:
<pre><code class="language-xxxx match-braces">...</pre></code>
Just like language-xxxx
, the match-braces
class is inherited, so you can add the class to the <body>
to enable the plugin for the whole page.
The plugin will highlight brace pairs when the cursor hovers over one of the braces. The highlighting effect will disappear as soon as the cursor leaves the brace pair.
The hover effect can be disabled by adding the no-brace-hover
to the code block. This class can also be inherited.
You can also click on a brace to select the brace pair. To deselect the pair, click anywhere within the code block or select another pair.
The selection effect can be disabled by adding the no-brace-select
to the code block. This class can also be inherited.
Rainbow braces 🌈
To enable rainbow braces, simply add the rainbow-braces
class to a code block. This class can also get inherited.
SETUP - copy to clipboard button:
https://prismjs.com/plugins/copy-to-clipboard/#how-to-use
The plugin depends on the Prism Toolbar plugin. In addition to including the plugin file with your PrismJS build, ensure it is loaded before the plugin.
Settings
By default, the plugin shows messages in English and sets a 5-second timeout after a click. You can use the following HTML5 data attributes to override the default settings:
data-prismjs-copy
— default message displayed by Copy to Clipboard;data-prismjs-copy-error
— a message displayed after failing copying, prompting the user to pressCtrl+C
;data-prismjs-copy-success
— a message displayed after a successful copying;data-prismjs-copy-timeout
— a timeout (in milliseconds) after copying. Once the timeout passed, the success or error message will revert back to the default message. The value should be a non-negative integer.
The plugin traverses up the DOM tree to find each of these attributes. The search starts at every pre code
element and stops at the closest ancestor element that has a desired attribute or at the worst case, at the html
element.
Warning! Although possible, you definitely shouldn't add these attributes to the html
element, because a human-readable text should be placed after the character encoding declaration (<meta charset="...">
), and the latter must be serialized completely within the first 512 (in older browsers) or 1024 bytes of the document. Consider using the body
element or one of its descendants.
Styling
This plugin supports customizing the style of the copy button. To understand how this is done, let's look at the HTML structure of the copy button:
<button class="copy-to-clipboard-button" type="button" data-copy-state="copy">
<span>Copy</span>
</button>
The copy-to-clipboard-button
class can be used to select the button. The data-copy-state
attribute indicates the current state of the plugin with the 3 possible states being:
data-copy-state="copy"
— default state;data-copy-state="copy-error"
— the state after failing copying;data-copy-state="copy-success"
— the state after successful copying;
These 3 states should be conveyed to the user either by different styling or displaying the button text.
Examples
Sharing
The following code blocks show modified messages and both use a half-second timeout. The other settings are set to default.
Source code:
<body data-prismjs-copy-timeout="500">
<pre><code class="language-js" data-prismjs-copy="Copy the JavaScript snippet!">console.log('Hello, world!');</code></pre>
<pre><code class="language-c" data-prismjs-copy="Copy the C snippet!">int main() {
return 0;
}</code></pre>
</body>
Output:
console.log('Hello, world!');
Copy the JavaScript snippet!
int main() {
return 0;
}
Copy the C snippet!
Inheritance
The plugin always use the closest ancestor element that has a desired attribute, so it's possible to override any setting on any descendant. In the following example, the baz
message is used. The other settings are set to default.
Source code:
<body data-prismjs-copy="foo">
<main data-prismjs-copy="bar">
<pre><code class="language-c" data-prismjs-copy="baz">int main() {
return 0;
}</code></pre>
</main>
</body>
Output:
int main() {
return 0;
}
baz
i18n
You can use the data attributes for internationalization.
The following code blocks use shared messages in Russian and the default 5-second timeout.
Source code:
<!DOCTYPE html>
<html lang="ru">
<!-- The head is omitted. -->
<body
data-prismjs-copy="Скопировать"
data-prismjs-copy-error="Нажмите Ctrl+C, чтобы скопировать"
data-prismjs-copy-success="Скопировано!"
>
<pre><code class="language-c">int main() {
return 0;
}</code></pre>
<pre><code class="language-js">console.log('Hello, world!');</code></pre>
</body>
</html>
Output:
int main() {
return 0;
}
Скопировать
console.log('Hello, world!');
Скопировать
The next HTML document is in English, but some code blocks show messages in Russian and simplified Mainland Chinese. The other settings are set to default.
Source code:
<!DOCTYPE html>
<html lang="en"><!-- The head is omitted. -->
<body>
<pre><code class="language-js">console.log('Hello, world!');</code></pre>
<pre
lang="ru"
data-prismjs-copy="Скопировать"
data-prismjs-copy-error="Нажмите Ctrl+C, чтобы скопировать"
data-prismjs-copy-success="Скопировано!"
><code class="language-js">console.log('Привет, мир!');</code></pre>
<pre
lang="zh-Hans-CN"
data-prismjs-copy="复制文本"
data-prismjs-copy-error="按Ctrl+C复制"
data-prismjs-copy-success="文本已复制!"
><code class="language-js">console.log('你好,世界!');</code></pre>
</body>
</html>
Output:
console.log('Hello, world!');
console.log('Привет, мир!');
Скопировать
console.log('你好,世界!');
How to use
Obviously, this is supposed to work only for code blocks (<pre><code>
) and not for inline code.
Add the line-numbers
class to your desired <pre>
or any of its ancestors, and the Line Numbers plugin will take care of the rest. To give all code blocks line numbers, add the line-numbers
class to the <body>
of the page. This is part of a general activation mechanism where adding the line-numbers
(or no-line-numbers
) class to any element will enable (or disable) the Line Numbers plugin for all code blocks in that element.
Example:
<body class="line-numbers"> <!-- enabled for the whole page -->
<!-- with line numbers -->
<pre><code>...</code></pre>
<!-- disabled for a specific element - without line numbers -->
<pre class="no-line-numbers"><code>...</code></pre>
<div class="no-line-numbers"> <!-- disabled for this subtree -->
<!-- without line numbers -->
<pre><code>...</code></pre>
<!-- enabled for a specific element - with line numbers -->
<pre class="line-numbers"><code>...</code></pre>
</div>
</body>
Optional: You can specify the data-start
(Number) attribute on the <pre>
element. It will shift the line counter.
Optional: To support multiline line numbers using soft wrap, apply the CSS white-space: pre-line;
or white-space: pre-wrap;
to your desired <pre>
.
Examples
JavaScript
(function () {
if (typeof Prism === 'undefined' || typeof document === 'undefined') {
return;
}
/**
* Plugin name which is used as a class name for <pre> which is activating the plugin
*
* @type {string}
*/
var PLUGIN_NAME = 'line-numbers';
/**
* Regular expression used for determining line breaks
*
* @type {RegExp}
*/
var NEW_LINE_EXP = /\n(?!$)/g;
/**
* Global exports
*/
var config = Prism.plugins.lineNumbers = {
/**
* Get node for provided line number
*
* @param {Element} element pre element
* @param {number} number line number
* @returns {Element|undefined}
*/
getLine: function (element, number) {
if (element.tagName !== 'PRE' || !element.classList.contains(PLUGIN_NAME)) {
return;
}
var lineNumberRows = element.querySelector('.line-numbers-rows');
if (!lineNumberRows) {
return;
}
var lineNumberStart = parseInt(element.getAttribute('data-start'), 10) || 1;
var lineNumberEnd = lineNumberStart + (lineNumberRows.children.length - 1);
if (number < lineNumberStart) {
number = lineNumberStart;
}
if (number > lineNumberEnd) {
number = lineNumberEnd;
}
var lineIndex = number - lineNumberStart;
return lineNumberRows.children[lineIndex];
},
/**
* Resizes the line numbers of the given element.
*
* This function will not add line numbers. It will only resize existing ones.
*
* @param {HTMLElement} element A `<pre>` element with line numbers.
* @returns {void}
*/
resize: function (element) {
resizeElements([element]);
},
/**
* Whether the plugin can assume that the units font sizes and margins are not depended on the size of
* the current viewport.
*
* Setting this to `true` will allow the plugin to do certain optimizations for better performance.
*
* Set this to `false` if you use any of the following CSS units: `vh`, `vw`, `vmin`, `vmax`.
*
* @type {boolean}
*/
assumeViewportIndependence: true
};
/**
* Resizes the given elements.
*
* @param {HTMLElement[]} elements
*/
function resizeElements(elements) {
elements = elements.filter(function (e) {
var codeStyles = getStyles(e);
var whiteSpace = codeStyles['white-space'];
return whiteSpace === 'pre-wrap' || whiteSpace === 'pre-line';
});
if (elements.length == 0) {
return;
}
var infos = elements.map(function (element) {
var codeElement = element.querySelector('code');
var lineNumbersWrapper = element.querySelector('.line-numbers-rows');
if (!codeElement || !lineNumbersWrapper) {
return undefined;
}
/** @type {HTMLElement} */
var lineNumberSizer = element.querySelector('.line-numbers-sizer');
var codeLines = codeElement.textContent.split(NEW_LINE_EXP);
if (!lineNumberSizer) {
lineNumberSizer = document.createElement('span');
lineNumberSizer.className = 'line-numbers-sizer';
codeElement.appendChild(lineNumberSizer);
}
lineNumberSizer.innerHTML = '0';
lineNumberSizer.style.display = 'block';
var oneLinerHeight = lineNumberSizer.getBoundingClientRect().height;
lineNumberSizer.innerHTML = '';
return {
element: element,
lines: codeLines,
lineHeights: [],
oneLinerHeight: oneLinerHeight,
sizer: lineNumberSizer,
};
}).filter(Boolean);
infos.forEach(function (info) {
var lineNumberSizer = info.sizer;
var lines = info.lines;
var lineHeights = info.lineHeights;
var oneLinerHeight = info.oneLinerHeight;
lineHeights[lines.length - 1] = undefined;
lines.forEach(function (line, index) {
if (line && line.length > 1) {
var e = lineNumberSizer.appendChild(document.createElement('span'));
e.style.display = 'block';
e.textContent = line;
} else {
lineHeights[index] = oneLinerHeight;
}
});
});
infos.forEach(function (info) {
var lineNumberSizer = info.sizer;
var lineHeights = info.lineHeights;
var childIndex = 0;
for (var i = 0; i < lineHeights.length; i++) {
if (lineHeights[i] === undefined) {
lineHeights[i] = lineNumberSizer.children[childIndex++].getBoundingClientRect().height;
}
}
});
infos.forEach(function (info) {
var lineNumberSizer = info.sizer;
var wrapper = info.element.querySelector('.line-numbers-rows');
lineNumberSizer.style.display = 'none';
lineNumberSizer.innerHTML = '';
info.lineHeights.forEach(function (height, lineNumber) {
wrapper.children[lineNumber].style.height = height + 'px';
});
});
}
/**
* Returns style declarations for the element
*
* @param {Element} element
*/
function getStyles(element) {
if (!element) {
return null;
}
return window.getComputedStyle ? getComputedStyle(element) : (element.currentStyle || null);
}
var lastWidth = undefined;
window.addEventListener('resize', function () {
if (config.assumeViewportIndependence && lastWidth === window.innerWidth) {
return;
}
lastWidth = window.innerWidth;
resizeElements(Array.prototype.slice.call(document.querySelectorAll('pre.' + PLUGIN_NAME)));
});
Prism.hooks.add('complete', function (env) {
if (!env.code) {
return;
}
var code = /** @type {Element} */ (env.element);
var pre = /** @type {HTMLElement} */ (code.parentNode);
// works only for <code> wrapped inside <pre> (not inline)
if (!pre || !/pre/i.test(pre.nodeName)) {
return;
}
// Abort if line numbers already exists
if (code.querySelector('.line-numbers-rows')) {
return;
}
// only add line numbers if <code> or one of its ancestors has the `line-numbers` class
if (!Prism.util.isActive(code, PLUGIN_NAME)) {
return;
}
// Remove the class 'line-numbers' from the <code>
code.classList.remove(PLUGIN_NAME);
// Add the class 'line-numbers' to the <pre>
pre.classList.add(PLUGIN_NAME);
var match = env.code.match(NEW_LINE_EXP);
var linesNum = match ? match.length + 1 : 1;
var lineNumbersWrapper;
var lines = new Array(linesNum + 1).join('<span></span>');
lineNumbersWrapper = document.createElement('span');
lineNumbersWrapper.setAttribute('aria-hidden', 'true');
lineNumbersWrapper.className = 'line-numbers-rows';
lineNumbersWrapper.innerHTML = lines;
if (pre.hasAttribute('data-start')) {
pre.style.counterReset = 'linenumber ' + (parseInt(pre.getAttribute('data-start'), 10) - 1);
}
env.element.appendChild(lineNumbersWrapper);
resizeElements([pre]);
Prism.hooks.run('line-numbers', env);
});
Prism.hooks.add('line-numbers', function (env) {
env.plugins = env.plugins || {};
env.plugins.lineNumbers = true;
});
}());
CSS
Please note that this <pre>
does not have the line-numbers
class but its parent does.
pre[class*="language-"].line-numbers {
position: relative;
padding-left: 3.8em;
counter-reset: linenumber;
}
pre[class*="language-"].line-numbers > code {
position: relative;
white-space: inherit;
}
.line-numbers .line-numbers-rows {
position: absolute;
pointer-events: none;
top: 0;
font-size: 100%;
left: -3.8em;
width: 3em; /* works for line-numbers below 1000 lines */
letter-spacing: -1px;
border-right: 1px solid #999;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.line-numbers-rows > span {
display: block;
counter-increment: linenumber;
}
.line-numbers-rows > span:before {
content: counter(linenumber);
color: #999;
display: block;
padding-right: 0.8em;
text-align: right;
}
HTML
Please note the data-start="-5"
in the code below.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="assets/favicon.png" />
<title>Line Numbers ▲ Prism plugins</title>
<base href="../.." />
<link rel="stylesheet" href="assets/style.css" />
<link rel="stylesheet" href="themes/prism.css" data-noprefix />
<link rel="stylesheet" href="plugins/line-numbers/prism-line-numbers.css" data-noprefix />
<script src="assets/vendor/prefixfree.min.js"></script>
<script>var _gaq = [['_setAccount', 'UA-33746269-1'], ['_trackPageview']];</script>
<script src="https://www.google-analytics.com/ga.js" async></script>
</head>
<body class="language-none">
<header data-plugin-header="line-numbers"></header>
<section class="language-markup">
<h1>How to use</h1>
<p>Obviously, this is supposed to work only for code blocks (<code><pre><code></code>) and not for inline code.</p>
<p>Add the <code>line-numbers</code> class to your desired <code><pre></code> or any of its ancestors, and the Line Numbers plugin will take care of the rest. To give all code blocks line numbers, add the <code>line-numbers</code> class to the <code><body></code> of the page. This is part of a general activation mechanism where adding the <code>line-numbers</code> (or <code>no-line-numbers</code>) class to any element will enable (or disable) the Line Numbers plugin for all code blocks in that element. <br> Example:</p>
<pre><code><body class="line-numbers"> <!-- enabled for the whole page -->
<!-- with line numbers -->
<pre><code>...</code></pre>
<!-- disabled for a specific element - without line numbers -->
<pre class="no-line-numbers"><code>...</code></pre>
<div class="no-line-numbers"> <!-- disabled for this subtree -->
<!-- without line numbers -->
<pre><code>...</code></pre>
<!-- enabled for a specific element - with line numbers -->
<pre class="line-numbers"><code>...</code></pre>
</div>
</body></code></pre>
<p>Optional: You can specify the <code>data-start</code> (Number) attribute on the <code><pre></code> element. It will shift the line counter.</p>
<p>Optional: To support multiline line numbers using soft wrap, apply the CSS <code>white-space: pre-line;</code> or <code>white-space: pre-wrap;</code> to your desired <code><pre></code>.</p>
</section>
<section class="line-numbers">
<h1>Examples</h1>
<h5>JavaScript</h5>
<pre class="line-numbers" data-src="plugins/line-numbers/prism-line-numbers.js"></pre>
<h5>CSS</h5>
<p>Please note that this <code class="language-markup"><pre></code> does not have the <code>line-numbers</code> class but its parent does.</p>
<pre data-src="plugins/line-numbers/prism-line-numbers.css"></pre>
<h5>HTML</h5>
<p>Please note the <code>data-start="-5"</code> in the code below.</p>
<pre class="line-numbers" data-src="plugins/line-numbers/index.html" data-start="-5"></pre>
<h5>Unknown languages</h5>
<pre class="language-none line-numbers"><code>This raw text
is not highlighted
but it still has
line numbers</code></pre>
<h5>Soft wrap support</h5>
<p>Please note the <code>style="white-space:pre-wrap;"</code> in the code below.</p>
<pre class="line-numbers" data-src="plugins/line-numbers/index.html" data-start="-5" style="white-space:pre-wrap;"></pre>
</section>
<footer data-src="assets/templates/footer.html" data-type="text/html"></footer>
<script src="prism.js"></script>
<script src="plugins/line-numbers/prism-line-numbers.js"></script>
<script src="assets/vendor/utopia.js"></script>
<script src="components.js"></script>
<script src="assets/code.js"></script>
</body>
</html>
Unknown languages
This raw text
is not highlighted
but it still has
line numbers
Soft wrap support
Please note the style="white-space:pre-wrap;"
in the code below.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="assets/favicon.png" />
<title>Line Numbers ▲ Prism plugins</title>
<base href="../.." />
<link rel="stylesheet" href="assets/style.css" />
<link rel="stylesheet" href="themes/prism.css" data-noprefix />
<link rel="stylesheet" href="plugins/line-numbers/prism-line-numbers.css" data-noprefix />
<script src="assets/vendor/prefixfree.min.js"></script>
<script>var _gaq = [['_setAccount', 'UA-33746269-1'], ['_trackPageview']];</script>
<script src="https://www.google-analytics.com/ga.js" async></script>
</head>
<body class="language-none">
<header data-plugin-header="line-numbers"></header>
<section class="language-markup">
<h1>How to use</h1>
<p>Obviously, this is supposed to work only for code blocks (<code><pre><code></code>) and not for inline code.</p>
<p>Add the <code>line-numbers</code> class to your desired <code><pre></code> or any of its ancestors, and the Line Numbers plugin will take care of the rest. To give all code blocks line numbers, add the <code>line-numbers</code> class to the <code><body></code> of the page. This is part of a general activation mechanism where adding the <code>line-numbers</code> (or <code>no-line-numbers</code>) class to any element will enable (or disable) the Line Numbers plugin for all code blocks in that element. <br> Example:</p>
<pre><code><body class="line-numbers"> <!-- enabled for the whole page -->
<!-- with line numbers -->
<pre><code>...</code></pre>
<!-- disabled for a specific element - without line numbers -->
<pre class="no-line-numbers"><code>...</code></pre>
<div class="no-line-numbers"> <!-- disabled for this subtree -->
<!-- without line numbers -->
<pre><code>...</code></pre>
<!-- enabled for a specific element - with line numbers -->
<pre class="line-numbers"><code>...</code></pre>
</div>
</body></code></pre>
<p>Optional: You can specify the <code>data-start</code> (Number) attribute on the <code><pre></code> element. It will shift the line counter.</p>
<p>Optional: To support multiline line numbers using soft wrap, apply the CSS <code>white-space: pre-line;</code> or <code>white-space: pre-wrap;</code> to your desired <code><pre></code>.</p>
</section>
<section class="line-numbers">
<h1>Examples</h1>
<h5>JavaScript</h5>
<pre class="line-numbers" data-src="plugins/line-numbers/prism-line-numbers.js"></pre>
<h5>CSS</h5>
<p>Please note that this <code class="language-markup"><pre></code> does not have the <code>line-numbers</code> class but its parent does.</p>
<pre data-src="plugins/line-numbers/prism-line-numbers.css"></pre>
<h5>HTML</h5>
<p>Please note the <code>data-start="-5"</code> in the code below.</p>
<pre class="line-numbers" data-src="plugins/line-numbers/index.html" data-start="-5"></pre>
<h5>Unknown languages</h5>
<pre class="language-none line-numbers"><code>This raw text
is not highlighted
but it still has
line numbers</code></pre>
<h5>Soft wrap support</h5>
<p>Please note the <code>style="white-space:pre-wrap;"</code> in the code below.</p>
<pre class="line-numbers" data-src="plugins/line-numbers/index.html" data-start="-5" style="white-space:pre-wrap;"></pre>
</section>
<footer data-src="assets/templates/footer.html" data-type="text/html"></footer>
<script src="prism.js"></script>
<script src="plugins/line-numbers/prism-line-numbers.js"></script>
<script src="assets/vendor/utopia.js"></script>
<script src="components.js"></script>
<script src="assets/code.js"></script>
</body>
</html>
https://prismjs.com/plugins/keep-markup/#how-to-use
You have nothing to do. The plugin is active by default. With this plugin loaded, all markup inside code will be kept.
However, you can deactivate the plugin for certain code element by adding the no-keep-markup
class to it. You can also deactivate the plugin for the whole page by adding the no-keep-markup
class to the body of the page and then selectively activate it again by adding the keep-markup
class to code elements.
Examples
The following source code
<pre><code class="language-css">
@media <mark>screen</mark> {
div {
<mark>text</mark>-decoration: <mark><mark>under</mark>line</mark>;
back<mark>ground: url</mark>('foo.png');
}
}</code></pre>
would render like this:
@media screen {
div {
text-decoration: underline;
background: url('foo.png');
}
}
It also works for inline code: var bar = function () { /* foo */ };
Examples
JavaScript
(function () {
if (typeof Prism === 'undefined' || typeof document === 'undefined') {
return;
}
if (!Prism.plugins.toolbar) {
console.warn('Show Languages plugin loaded before Toolbar plugin.');
return;
}
/* eslint-disable */
// The languages map is built automatically with gulp
var Languages = /*languages_placeholder[*/{
"none": "Plain text",
"plain": "Plain text",
"plaintext": "Plain text",
"text": "Plain text",
"txt": "Plain text",
"html": "HTML",
"xml": "XML",
"svg": "SVG",
"mathml": "MathML",
"ssml": "SSML",
"rss": "RSS",
"css": "CSS",
"clike": "C-like",
"js": "JavaScript",
"abap": "ABAP",
"abnf": "ABNF",
"al": "AL",
"antlr4": "ANTLR4",
"g4": "ANTLR4",
"apacheconf": "Apache Configuration",
"apl": "APL",
"aql": "AQL",
"arff": "ARFF",
"asciidoc": "AsciiDoc",
"adoc": "AsciiDoc",
"aspnet": "ASP.NET (C#)",
"asm6502": "6502 Assembly",
"autohotkey": "AutoHotkey",
"autoit": "AutoIt",
"avro-idl": "Avro IDL",
"avdl": "Avro IDL",
"basic": "BASIC",
"bbcode": "BBcode",
"bnf": "BNF",
"rbnf": "RBNF",
"bsl": "BSL (1C:Enterprise)",
"oscript": "OneScript",
"csharp": "C#",
"cs": "C#",
"dotnet": "C#",
"cpp": "C++",
"cfscript": "CFScript",
"cfc": "CFScript",
"cil": "CIL",
"cmake": "CMake",
"cobol": "COBOL",
"coffee": "CoffeeScript",
"conc": "Concurnas",
"csp": "Content-Security-Policy",
"css-extras": "CSS Extras",
"csv": "CSV",
"dataweave": "DataWeave",
"dax": "DAX",
"django": "Django/Jinja2",
"jinja2": "Django/Jinja2",
"dns-zone-file": "DNS zone file",
"dns-zone": "DNS zone file",
"dockerfile": "Docker",
"dot": "DOT (Graphviz)",
"gv": "DOT (Graphviz)",
"ebnf": "EBNF",
"editorconfig": "EditorConfig",
"ejs": "EJS",
"etlua": "Embedded Lua templating",
"erb": "ERB",
"excel-formula": "Excel Formula",
"xlsx": "Excel Formula",
"xls": "Excel Formula",
"fsharp": "F#",
"firestore-security-rules": "Firestore security rules",
"ftl": "FreeMarker Template Language",
"gml": "GameMaker Language",
"gamemakerlanguage": "GameMaker Language",
"gcode": "G-code",
"gdscript": "GDScript",
"gedcom": "GEDCOM",
"glsl": "GLSL",
"gn": "GN",
"gni": "GN",
"graphql": "GraphQL",
"hbs": "Handlebars",
"hs": "Haskell",
"hcl": "HCL",
"hlsl": "HLSL",
"http": "HTTP",
"hpkp": "HTTP Public-Key-Pins",
"hsts": "HTTP Strict-Transport-Security",
"ichigojam": "IchigoJam",
"icu-message-format": "ICU Message Format",
"idr": "Idris",
"ignore": ".ignore",
"gitignore": ".gitignore",
"hgignore": ".hgignore",
"npmignore": ".npmignore",
"inform7": "Inform 7",
"javadoc": "JavaDoc",
"javadoclike": "JavaDoc-like",
"javastacktrace": "Java stack trace",
"jq": "JQ",
"jsdoc": "JSDoc",
"js-extras": "JS Extras",
"json": "JSON",
"webmanifest": "Web App Manifest",
"json5": "JSON5",
"jsonp": "JSONP",
"jsstacktrace": "JS stack trace",
"js-templates": "JS Templates",
"kts": "Kotlin Script",
"kt": "Kotlin",
"kumir": "KuMir (КуМир)",
"kum": "KuMir (КуМир)",
"latex": "LaTeX",
"tex": "TeX",
"context": "ConTeXt",
"lilypond": "LilyPond",
"ly": "LilyPond",
"emacs": "Lisp",
"elisp": "Lisp",
"emacs-lisp": "Lisp",
"llvm": "LLVM IR",
"log": "Log file",
"lolcode": "LOLCODE",
"md": "Markdown",
"markup-templating": "Markup templating",
"matlab": "MATLAB",
"mel": "MEL",
"mongodb": "MongoDB",
"moon": "MoonScript",
"n1ql": "N1QL",
"n4js": "N4JS",
"n4jsd": "N4JS",
"nand2tetris-hdl": "Nand To Tetris HDL",
"naniscript": "Naninovel Script",
"nani": "Naninovel Script",
"nasm": "NASM",
"neon": "NEON",
"nginx": "nginx",
"nsis": "NSIS",
"objectivec": "Objective-C",
"objc": "Objective-C",
"ocaml": "OCaml",
"opencl": "OpenCL",
"openqasm": "OpenQasm",
"qasm": "OpenQasm",
"parigp": "PARI/GP",
"objectpascal": "Object Pascal",
"psl": "PATROL Scripting Language",
"pcaxis": "PC-Axis",
"px": "PC-Axis",
"peoplecode": "PeopleCode",
"pcode": "PeopleCode",
"php": "PHP",
"phpdoc": "PHPDoc",
"php-extras": "PHP Extras",
"plsql": "PL/SQL",
"powerquery": "PowerQuery",
"pq": "PowerQuery",
"mscript": "PowerQuery",
"powershell": "PowerShell",
"promql": "PromQL",
"properties": ".properties",
"protobuf": "Protocol Buffers",
"purebasic": "PureBasic",
"pbfasm": "PureBasic",
"purs": "PureScript",
"py": "Python",
"qsharp": "Q#",
"qs": "Q#",
"q": "Q (kdb+ database)",
"qml": "QML",
"rkt": "Racket",
"jsx": "React JSX",
"tsx": "React TSX",
"renpy": "Ren'py",
"rpy": "Ren'py",
"rest": "reST (reStructuredText)",
"robotframework": "Robot Framework",
"robot": "Robot Framework",
"rb": "Ruby",
"sas": "SAS",
"sass": "Sass (Sass)",
"scss": "Sass (Scss)",
"shell-session": "Shell session",
"sh-session": "Shell session",
"shellsession": "Shell session",
"sml": "SML",
"smlnj": "SML/NJ",
"solidity": "Solidity (Ethereum)",
"sol": "Solidity (Ethereum)",
"solution-file": "Solution file",
"sln": "Solution file",
"soy": "Soy (Closure Template)",
"sparql": "SPARQL",
"rq": "SPARQL",
"splunk-spl": "Splunk SPL",
"sqf": "SQF: Status Quo Function (Arma 3)",
"sql": "SQL",
"iecst": "Structured Text (IEC 61131-3)",
"systemd": "Systemd configuration file",
"t4-templating": "T4 templating",
"t4-cs": "T4 Text Templates (C#)",
"t4": "T4 Text Templates (C#)",
"t4-vb": "T4 Text Templates (VB)",
"tap": "TAP",
"tt2": "Template Toolkit 2",
"toml": "TOML",
"trig": "TriG",
"ts": "TypeScript",
"tsconfig": "TSConfig",
"uscript": "UnrealScript",
"uc": "UnrealScript",
"uri": "URI",
"url": "URL",
"vbnet": "VB.Net",
"vhdl": "VHDL",
"vim": "vim",
"visual-basic": "Visual Basic",
"vba": "VBA",
"vb": "Visual Basic",
"wasm": "WebAssembly",
"wiki": "Wiki markup",
"wolfram": "Wolfram language",
"nb": "Mathematica Notebook",
"wl": "Wolfram language",
"xeoracube": "XeoraCube",
"xml-doc": "XML doc (.net)",
"xojo": "Xojo (REALbasic)",
"xquery": "XQuery",
"yaml": "YAML",
"yml": "YAML",
"yang": "YANG"
}/*]*/;
/* eslint-enable */
Prism.plugins.toolbar.registerButton('show-language', function (env) {
var pre = env.element.parentNode;
if (!pre || !/pre/i.test(pre.nodeName)) {
return;
}
/**
* Tries to guess the name of a language given its id.
*
* @param {string} id The language id.
* @returns {string}
*/
function guessTitle(id) {
if (!id) {
return id;
}
return (id.substring(0, 1).toUpperCase() + id.substring(1)).replace(/s(?=cript)/, 'S');
}
var language = pre.getAttribute('data-language') || Languages[env.language] || guessTitle(env.language);
if (!language) {
return;
}
var element = document.createElement('span');
element.textContent = language;
return element;
});
}());
JavaScript
CSS
div.code-toolbar {
position: relative;
}
div.code-toolbar > .toolbar {
position: absolute;
top: .3em;
right: .2em;
transition: opacity 0.3s ease-in-out;
opacity: 0;
}
div.code-toolbar:hover > .toolbar {
opacity: 1;
}
/* Separate line b/c rules are thrown out if selector is invalid.
IE11 and old Edge versions don't support :focus-within. */
div.code-toolbar:focus-within > .toolbar {
opacity: 1;
}
div.code-toolbar > .toolbar > .toolbar-item {
display: inline-block;
}
div.code-toolbar > .toolbar > .toolbar-item > a {
cursor: pointer;
}
div.code-toolbar > .toolbar > .toolbar-item > button {
background: none;
border: 0;
color: inherit;
font: inherit;
line-height: normal;
overflow: visible;
padding: 0;
-webkit-user-select: none; /* for button */
-moz-user-select: none;
-ms-user-select: none;
}
div.code-toolbar > .toolbar > .toolbar-item > a,
div.code-toolbar > .toolbar > .toolbar-item > button,
div.code-toolbar > .toolbar > .toolbar-item > span {
color: #bbb;
font-size: .8em;
padding: 0 .5em;
background: #f5f2f0;
background: rgba(224, 224, 224, 0.2);
box-shadow: 0 2px 0 0 rgba(0,0,0,0.2);
border-radius: .5em;
}
div.code-toolbar > .toolbar > .toolbar-item > a:hover,
div.code-toolbar > .toolbar > .toolbar-item > a:focus,
div.code-toolbar > .toolbar > .toolbar-item > button:hover,
div.code-toolbar > .toolbar > .toolbar-item > button:focus,
div.code-toolbar > .toolbar > .toolbar-item > span:hover,
div.code-toolbar > .toolbar > .toolbar-item > span:focus {
color: inherit;
text-decoration: none;
}
CSS
HTML (Markup)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="assets/favicon.png" />
<title>Show Language ▲ Prism plugins</title>
<base href="../.." />
<link rel="stylesheet" href="assets/style.css" />
<link rel="stylesheet" href="themes/prism.css" data-noprefix />
<link rel="stylesheet" href="plugins/toolbar/prism-toolbar.css" data-noprefix />
<script src="assets/vendor/prefixfree.min.js"></script>
<script>var _gaq = [['_setAccount', 'UA-33746269-1'], ['_trackPageview']];</script>
<script src="https://www.google-analytics.com/ga.js" async></script>
</head>
<body>
<header data-plugin-header="show-language"></header>
<section>
<h1>Examples</h1>
<h5>JavaScript</h5>
<pre data-src="plugins/show-language/prism-show-language.js"></pre>
<h5>CSS</h5>
<pre data-src="plugins/toolbar/prism-toolbar.css"></pre>
<h5>HTML (Markup)</h5>
<pre data-src="plugins/show-language/index.html"></pre>
<h5>SVG</h5>
<p>The <code class="language-markup">data-language</code> attribute can be used to display a specific label whether it has been defined as a language or not.</p>
<pre data-language="SVG v1.1" data-src="assets/logo.svg"></pre>
<h5>Plain text</h5>
<pre class="language-none"><code>Just some text (aka. not code).</code></pre>
</section>
<footer data-src="assets/templates/footer.html" data-type="text/html"></footer>
<script src="prism.js"></script>
<script src="plugins/toolbar/prism-toolbar.js"></script>
<script src="plugins/show-language/prism-show-language.js"></script>
<script src="assets/vendor/utopia.js"></script>
<script src="components.js"></script>
<script src="assets/code.js"></script>
</body>
</html>
HTML
SVG
The data-language
attribute can be used to display a specific label whether it has been defined as a language or not.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 170">
<path fill="#fff" d="M55.37 131.5H48.4v9.13h6.97c1.67 0 2.92-.4 3.78-1.22.85
-.8 1.28-1.92 1.28-3.33s-.43-2.54-1.28-3.35c-.86-.8-2.12-1.2-3.78-1.2m29.52
6.4c.3-.53.47-1.2.47-2.04 0-1.35-.45-2.4-1.37-3.2-.92-.76-2.14-1.15-3.65
-1.15H72.9v8.52h7.32c2.26 0 3.82-.7 4.67-2.1M100 0L0 170h500L100 0M60.86
141.03c-1.3 1.22-3.1 1.84-5.33 1.84H48.4v7.55H46v-21.2h9.53c2.24 0 4.02.63
5.34 1.87 1.3 1.23 1.96 2.88 1.96 4.95 0 2.1-.66 3.75-1.97 4.98m24.5 9.4l
-5.1-8.14h-7.37v8.12h-2.4v-21.2h10.14c2.15 0 3.88.6 5.18 1.8 1.3 1.18 1.95
2.8 1.95 4.84 0 2.64-1.1 4.44-3.3 5.4-.6.28-1.22.5-1.82.6l5.57 8.56h-2.85m
13.43 0h-2.4v-21.2h5.4v21.2m23.56-1.32c-1.48 1.05-3.53 1.57-6.16 1.57-2.96 0
-5.23-.6-6.78-1.85-1.4-1.1-2.18-2.7-2.37-4.74h5.5c.08 1.45.78 2.56 2.1 3.33
1.16.67 2.68 1 4.58 1 3.97 0 5.95-1.25 5.95-3.74 0-.86-.35-1.53-1.07-2.02-.7
-.5-1.6-.9-2.68-1.2-1.07-.33-2.24-.63-3.48-.9s-2.4-.65-3.5-1.08-1.97-1.02
-2.68-1.73c-.7-.72-1.07-1.68-1.07-2.9 0-1.73.65-3.13 1.97-4.22 1.32-1.08
3.32-1.62 6-1.62 2.67 0 4.75.6 6.23 1.85 1.34 1.1 2.05 2.5 2.14 4.2h-2.46c
-.22-1.76-1.35-2.92-3.4-3.5-.72-.2-1.62-.3-2.7-.3s-1.98.1-2.72.35c-.74.25
-1.3.55-1.7.9-.42.35-.7.74-.83 1.17s-.2.88-.2 1.36c0 .5.2.93.62 1.33s.96.75
1.65 1.03c.68.28 1.46.52 2.33.73.88.2 1.77.43 2.67.65.9.22 1.8.48 2.68.77.87
.3 1.65.65 2.33 1.1 1.53.96 2.28 2.27 2.28 3.94 0 2-.74 3.5-2.22 4.55m28.84
1.32v-17.54l-7.84 10.08-7.97-10.08v17.54H133v-21.2h5.78l7.58 10.06 7.45
-10.05h5.8v21.2h-2.4"/>
</svg>
SVG v1.1
Plain text
Just some text (aka. not code).
Plain text
download
&nsbp;
There are many WordPress plugins for highlighting programming code. Until now, I have used Crayon Syntax Highlighter on this blog and was satisfied with it, but at the time of the writing, the plugin was last updated more than 2 years ago, so I started looking for the non-plugin alternative. In the end, I chose to use Google code-prettify library. This article will show you how to implement this library into the WordPress and how to make it more versatile by using few CSS tricks.
At the moment, the WordPress plugin page for Crayon Syntax Highlighter is showing the following message:
This plugin hasn’t been tested with the latest 3 major releases of WordPress. It may no longer be maintained or supported and may have compatibility issues when used with more recent versions of WordPress.
It's never a good idea to have plugins that are no longer supported and the code-prettify library from Google is a good alternative. The library will do pretty good job on C based languages, JavaScript, HTML, while for other special case languages like F#, Scala, they are supported using extensions. Check the Prettify GitHub page for more information.
First, let's compare it with Crayon Syntax Highlighter, so you could have a better idea if the Prettify is a way to go.
Pro's
- More lightweight.
- Overall page size will be reduced.
- Simpler to use as all you need is to insert a class name into a
<pre>
tag. - It is a project from GitHub, so it should be always up-to-date as oppose as the WordPress plugins, where often they rely on a single developer to maintain it.
- The library is used by very popular websites like StackOverflow.
Con's
- Less accurate Syntax detection.
- As it is not a plugin, you need to do HTML encoding yourself.
- No native line highlighting support.
First, we will configure the WordPress to support the library. Next, we will need to encode our syntax code to be HTML friendly and finally, we will enable it to highlight the code.
Note: All the work regarding the embedding code snippets that we want to show in our posts will be done in "Text editor" of WordPress and not on "Visual editor" when editing the post.
Table of Contents
Step 1 - Setting code-prettify for WordPressStep 2 - HTML Encode the syntax code you want to show in your postStep 3 - Enabling the Google Prettify on the syntax codeChanging the default theme / skinTurning on line numbersColoring of the linesHighlighting the specific linesUsing inline codeOther issues and workarounds
Step 1 - Setting code-prettify for WordPress
The library itself can be found on GitHub, but to set up the code-prettify to work with WordPress, we just need to add following line into header.php
template file inside the <head>
tag before <?php wp_head(); ?>
.
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>
Note: The more correct way would be to add the script using the WordPress Enqueue functionality. For more information on how to accomplish that check this article.
Step 2 - HTML Encode the syntax code you want to show in your post
Next, we need to HTML encode our syntax code inside the post, as certain characters have special meaning in HTML and the browser will interpret them as a part of the HTML. The easiest way to achieve this is to find some online HTML encoder, like this one (shown below):
Click image to enlarge
Simply copy your syntax code inside the windows and click the 'Encode' button. You can leave the checkbox about converting all non-alphanumeric characters unchecked. Copy the encoded version from "Encode Result" window and paste it into the post editor in the WordPress.
Step 3 - Enabling the Google Prettify on the syntax code
After we copied the encoded syntax code, we need to do two things:
- Wrap it with
<pre>
tag. - To make the highlighter work on the
<pre>
tag, we need to add aclass="prettyprint"
to it.
For example, if we want to show the following snippet of code:
function MyFunction( $result, $url )
{
...
}
Then in our post editor, the code would look like this:
<pre class="prettyprint">
function MyFunction( $result, $url )
{
...
}
</pre>
And this is it. For each new syntax code you want to add, simply repeat the steps 2 and 3.
In all the remaining sections of this article, we will focus on different ways to customize the prettify functionality.
Changing the default theme / skin
Google Prettify has four themes to choose from. You can check them out here.
To load a theme, we need to append a query string ?skin=SKINNAME to the run_prettify.js
file we added in step 1. For example, to use "Desert" theme, we would put desert (all lower case) as a value like this:
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?skin=desert"></script>
Using 3rd party themes
There are also 3rd party themes available like this Color themes for Google Code Prettify project. The steps to use a theme from this project are:
- In the Color themes for Google Code Prettify, scroll down to "Preview", and choose the theme you like to have.
- Click on the minimized version of the CSS file (.min.css). The file should open in the new browser tab.
- Save that file into your computer
- Copy that .min.css file from your computer into your WordPress theme folder.
- All that is left is to reference that file in your theme. It should be added in the
header.php
file, but make sure it is added after therun_prettify.js
line of code that we already added in Step 1.
So, for example, if we copied github-v2.min.css
inside our theme folder, we would add this in the header.php
file:
<link rel="stylesheet" href="<?php echo get_stylesheet_directory_uri() . "/github-v2.min.css" ?>" type="text/css" />
To make any further CSS changes to it, we can simply override them in our WordPress Theme stylesheet file. In the following example, we set the comments to be a green color:
pre.prettyprint .com {
color: #080;
}
Note: Again, the correct way for adding styles is to use WordPress Enqueue functionality, but we can always fix that later.
Turning on line numbers
When we have a large block of syntax code with lots of lines, we can make it more readable by turning on line numbering. With Google Prettify, this is simply done by adding a linenums class to the <pre>
tag, like so:
<pre class="prettyprint linenums">
This will only show line number for every 5th line, so we need to add the following CSS rule in styles.css
to show the line numbers for every line:
li.L0, li.L1, li.L2, li.L3, li.L4, li.L5, li.L6, li.L7, li.L8, li.L9 {
list-style-type: decimal;
}
To change the background of the left side bar, where the line numbers reside, we add this:
pre.prettyprint.linenums {
background: #dfefff;
}
This will also change most of the background where syntax code is shown. We will fix this in the next section.
And to change the color of numbers itself, we add:
ol.linenums {
color: #5499de;
}
If not all digits are shown for the line numbers, we can fix that with padding:
pre.prettyprint.linenums ol {
padding-left: 10px;
}
Coloring of the lines
To set the background where the syntax code is displayed, we use this:
li.L0, li.L1, li.L2, li.L3, li.L4, li.L5, li.L6, li.L7, li.L8, li.L9 {
background: #f7f7f7;
}
And to set the alternative rows to different colors, we do:
li.L1, li.L3, li.L5, li.L7, li.L9 {
background: #eee;
}
Note: The coloring of alternative rows only works if the <pre>
is using line numbering.
Highlighting the specific lines
One cool feature of the Syntax Highlighter plugin is the ability to highlight the individual lines to a highlighting color. As the prettify doesn't seem to have that feature, we need to make use of<span>
elements and CSS to achieve the same effect.
Step 1 - Adding CSS rule
pre.prettyprint span.highlight { background: #fffee2; border-width: 1px; border-color: #e9e579;}
We need to add one more CSS rule. To highlight the whole line, we need to make it display:block;
, so we add this:
pre.prettyprint.linenums span.highlight { display:block;}
Step 2 - Specify which lines to highlight
Now that we added CSS, we just need to wrap the code we want to highlight with <span>
tag that will have .highlight class as shown below:
<span class="highlight">some code</span>
Note: We can highlight multiple lines with the single <span class="highlight">
tag, we just need to move the ending </span>
where we want the highlighting to end.
How the highlighted line on syntax code with line numbering works is shown below:
some codesome codesome codesome code
When not using line numbering, only the syntax code will get highlighted and not the whole line:
some code
some code
some code
some code
Using inline code
Sometimes, we want to have syntax code to be inline. We can easily achieve this by using <code>
tag instead of <pre>
, like so:
<code class="prettyprint">...</code>
And to style it, we use this:
code.prettyprint {
...
}
Other issues and workarounds
When using the customization tricks, we will sometimes notice that things don't always work as we intended.
Problem with background colors when coloring lines
One issue I have noticed is in cases where the long syntax code creates a horizontal scrollbar. In those cases, only the original unscrolled section will have background colors as intended. My fix was to prevent scrolling all together by using white-space property for the <pre>
tag:
pre.prettyprint {
white-space: pre-wrap;
}
This will prevent scrolling and will instead wrap the long lines and it will work for both coloring every second row and for highlighted lines.
Forcing a comment color on whole syntax code
One drawback of Prettify compared to Crayon Syntax Highlighter is that you cannot specify which language you are using, so sometimes it misses the coloring of the syntax. A good example of this is when you want to show a commented code in php.ini
, like this:
;always_populate_raw_post_data = –1
The above code will not be recognized as a comment, so to fix it, we can create a class that will force all the syntax to be in specific color:
pre.prettyprint.allcomment span {
color:#080;
}
Then, we just add allcomment class inside <pre>
tag like so:
<pre class="prettyprint allcomment">
Now, all the lines will be colored as a comment:
;always_populate_raw_post_data = –1
Conclusion
If we need to highlight the syntax code in our posts, there are many options to choose from. When using WordPress, the Crayon Syntax Highlighter plugin was and still is a very popular for this task. But it has been 2 years since the last update, so if you are looking for an alternative syntax code highlighter, the Google prettify library might be a good choice. In this article, we first examined how to set up the library for the WordPress, then we demonstrated how to use it and finally, we showed a few ways to customize it using CSS styles.