Jump to content

Prism Syntax Highlighter


abdus
 Share

Recommended Posts

ProcessWire Prism JS Syntax Highlighter

A module to parse given HTML and syntax-highlight code elements using Prism JS

Features 

  • Support for 120 languages
  • Very lightweight, core weights 2KB minified gzipped. 
  • Customizable. Specify your own CSS, or use one of 8 default themes 
  • Hookable. Use hooks to specify your own custom CSS, and JS 
  • Plugin support. You can use all available plugins that come with Prism JS. 

Installation

  • Add module to /site/modules/ and then install.
    Or go to Modules > Install > Add New and use any of the options provided to to install.
  • Create a text/textarea field or use an existing one then pick Prism Code Highlighter from Details > Text Formatters
    Protip: This module parses HTML markup, so it should come after HTML parsers such as Markdown textformatters. 
  • Add code elements within the field content with language-xxxx classes.
    Or pick a default language from configuration page if you are unable to specify the classes. 
  • Go to configuration page and select any plugins you want. To use some plugins, extra classes are required. See plugin documentation
  • Install these recommended modules for the best experience: 
    Parsedown Extra module to render Markdown Extra into HTML. You can also set custom attributes for each element unlike vanilla Markdown. 

 Customization 

  • Go to module configuration to specify:  Auto inclusion of highlighters for parsed languages 
  • Default language for inline code elements or ones without language-xxxx classes. 
  • Ability to use minified/non-minified component and parser files 
  • Plugin options
  • Theme options
  • Custom JS and CSS for configuration / theming 
  • Ability to use hooks to specify custom CSS and JS 

Hooks

  • Hook into TextformatterPrism::getCustomCss and TextformatterPrism::getCustomJs in your ready.php file and return an (array of) URLs as follows: 
// specify custom CSS
wire()->addHookAfter('TextformatterPrism::getCustomCss', function (HookEvent $event) {
    $event->return = 'path/to/custom.css';
});
// Specify custom JS
wire()->addHookAfter('TextformatterPrism::getCustomJs', function (HookEvent $event) {
    $event->return = ['path/to/custom.js', 'another/custom.js'];
});

 

Screenshots

2017-01-12 19_53_15-Modules • ProcessWire • abdus.dev.png

2017-01-12 19_53_00-Practical Uses of Hooks in Processwire - abdus.png

 

Links

  • Like 17
Link to comment
Share on other sites

  • 4 weeks later...

Good Day,

I have installed this module to test out on a new site that I'm building.  It shows as Version 0.0.1

When I go to Upgrade it shows that there is a Version 1.0.0

prism-module1.png

prism-module2.png

Once You go to upgrade, it says that things were upgraded however it's still at Version 0.0.1

prism-module3.png

prism-module4.png

Any help that you can provide is greatly appreciated.

 

Link to comment
Share on other sites

3 minutes ago, abdus said:

module repository should update in a day I guess.

No need to wait for a day. Go to your module in the repo, click button to edit it and immediately save; (no need to edit anything actually). Voila, it is updated in the repo! :).

  • Like 2
Link to comment
Share on other sites

1 minute ago, kongondo said:

No need to wait for a day. Go to your module in the repo, click button to edit it and immediately save; (no need to edit anything actually). Voila, it is updated! :).

Done! Thanks.

  • Like 2
Link to comment
Share on other sites

  • 9 months later...

Somehow your module does not work correctly in my ProcessWire. I am using 3.0.71 right now.

I have this code in my body field and your textformatter applied to the body field:

<pre>
<code class="language-php">
echo "this is PHP";
</code>
</pre>

After outputting it on my site it shows up as:

           pre>
<code class=" language-php language-php">
<span class="token keyword">echo</span> <span class="token string">"this is PHP"</span><span class="token punctuation">;</span>
</code>
    <script src="/site/modules/TextformatterPrism/prism/prism.js"></script>
    <script src="/site/modules/TextformatterPrism/prism/components/prism-php.js"></script>                       
               

So as you can see, it the first pre tag is destroyed/converted and the closing pre tag is removed. 

 

Link to comment
Share on other sites

  • 1 year later...

Just in case someone else stumbles over this, you'll need to modify these lines at the end of method format() in TextformatterPrism.module:

        $markup = $dom->saveHTML($dom->getElementsByTagName('body')->item(0));
        $markup = ltrim(rtrim($markup, '</body>'), '<body>');

Into this:

        $markup = $dom->saveHTML($dom->getElementsByTagName('body')->item(0)->nodevalue);

Reason is, that ltrim/rtrim do not trim strings but character groups. So they do not stop after the <body> tag but continue to strip any following char if its one of "<>bdoy"...

Using nodevalue (or textcontent) from the body element eliminates the need for the trim.

  • Like 1
Link to comment
Share on other sites

Just realized that saveHTML automatically adds doctype and <html><body> frame around the content (from PHP 5.2.6).

Edit: For PHP >= 5.4.0 better change loading the HTML from

$dom->loadHTML(mb_convert_encoding($str, 'HTML-ENTITIES', 'UTF-8'));

to

$dom->loadHTML(mb_convert_encoding($str, 'HTML-ENTITIES', 'UTF-8'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

https://stackoverflow.com/questions/4879946/how-to-savehtml-of-domdocument-without-html-wrapper

http://php.net/manual/de/libxml.constants.php

 

 

so that should be removed using something like (5.2.6 <= PHP < 5.4.0) :

		// Remove added doctype/html/body added from saveHTML
		$markup = preg_replace('/^<!DOCTYPE.+?>/', '',
			str_replace( array('<html>', '</html>', '<body>', '</body>'),
						 array('', '', '', ''),
						 $markup));

http://php.net/manual/de/domdocument.savehtml.php#85165

Link to comment
Share on other sites

Ok, DOMDocument drives me crazy. It does not properly work without a surrounding container, so I've changed the loadHTML as follows:

$dom->loadHTML('<div>'.mb_convert_encoding($str, 'HTML-ENTITIES', 'UTF-8').'</div>', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

This, of course, needs to be cleaned up at the end, which I quick&dirty done like this:

						// strlen('<div>') = 5
$markup = substr(trim($dom->saveHTML($dom)), 5, -6);

The trim is required, since the return of saveHTML ends with a newline and I don't want to hard-encode this using -7 for the length parameter of substr, sigh.

Edit: changed <dummycontainer> to <div> to make loadHTML happy.

  • Thanks 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...