Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crayon Compatibility Mode #136

Closed
AndiDittrich opened this issue Dec 24, 2018 · 38 comments
Closed

Crayon Compatibility Mode #136

AndiDittrich opened this issue Dec 24, 2018 · 38 comments

Comments

@AndiDittrich
Copy link
Member

AndiDittrich commented Dec 24, 2018

Add an additional filter to convert crayon code into Enlighter codeblock

see https://wordpress.org/support/topic/enlighter-not-picking-pre-tags-in-compatibility/

Structure

<pre class="lang:xhtml decode:true ">
....
</pre>

Todo

Add a parser which recognizes lang:XXX within the class attribute

@AndiDittrich
Copy link
Member Author

AndiDittrich commented Dec 24, 2018

Simple regex code to be added to the themes functions.php file or a custom plugin

add_filter('the_content', function($content){
	// crayon filter regex
	$regex = 
		// opening tag, language identifier (optional)
		'/<pre\s+class="lang:([a-z]+?)([^"]*)"\s*>' .
	
		// case insensitive, multiline
		'/im';
	
	// apply filter regex
	return preg_replace_callback($regex, function($match){
		return '<pre class="EnlighterJSRAW" data-enlighter-language="' . esc_attr($match[1]) . '">';
	}, $content);
}, 1);

@willstocks
Copy link

@AndiDittrich - this might be a REALLY janky solution to this (however, I have a strong feeling that over the next few months, you're going to get an in-flux of ex-crayon users, due to no Gutenberg compatibility, no PHP7.3 compatibility, no updates, no support etc.) - what about a "search and replace" style add-on for Enlighter that "once and for all" converts all Crayon blocks to Enlighter blocks? This would also have a benefit of you not then having to "support" Crayon blocks in compatibility mode - instead someone could install the add-on, convert their blocks in bulk (I've seen bloggers with 100's (maybe even 1000's) of Crayon posts - doing it manually would be impossible) and then they can remove the add-on and use Enlighter "natively"?

@AndiDittrich
Copy link
Member Author

the solution is very clean and reliable...

i will avoid to do any kind of persistent changes...in case there are some weird environments such regex filters may destroy users content or break it.

especially for beginners or intermediate users without valid backups this can be a major issue.

such decisions (in context of WordPress) are more about possible issues .... not about technological aspects...

@willstocks
Copy link

willstocks commented Feb 26, 2019 via email

@AndiDittrich
Copy link
Member Author

by using a caching plugin there will be absolutely no impact...otherwise it will take some more cpu time on the server...but compared to the WordPress Core itself it's meaningless

@willstocks
Copy link

willstocks commented Feb 26, 2019 via email

@AndiDittrich
Copy link
Member Author

opcode caching does not take action in this case because the content is loaded from the database

@willstocks
Copy link

willstocks commented Feb 26, 2019 via email

@Mte90
Copy link

Mte90 commented Mar 8, 2019

The snippet works but I think that a converter of the old tag can be useful also because the original plugin is abandoned so why keep this old content in the database forever?

@AndiDittrich
Copy link
Member Author

see my comment above...

altering the database can cause a persistent damage on users content in case of weird/broken hosting environments (there are a lot of them in the WordPress world..) - and the most users didn't have a recent/working backup...

the best way is to do it offline or via an external script. i can create a cli tool or an additional WordPress plugin.

@Mte90
Copy link

Mte90 commented Mar 8, 2019

a cli tool is good, for me is important that there is a way to change the content in the website so in that way I am sure that there are no traces of plugins that are not used anymore.

@AndiDittrich
Copy link
Member Author

WP-CLI ?

@Mte90
Copy link

Mte90 commented Mar 8, 2019

yes maybe a command for that to do that magic :-D

@willstocks
Copy link

willstocks commented Mar 8, 2019 via email

@Suplanus
Copy link

I would love to see this earlier.

Here is a fix for crayon with line numbers:

// Crayon fix with line numbers
add_filter('the_content', function($content){
	// crayon filter regex
	$regex = 
		// opening tag, language identifier (optional)
		'/<pre\s+class="nums:false lang:([a-z]+?)([^"]*)"\s*>' .
	
		// case insensitive, multiline
		'/im';
	
	// apply filter regex
	return preg_replace_callback($regex, function($match){
		return '<pre class="EnlighterJSRAW" data-enlighter-linenumbers="false" data-enlighter-language="' . esc_attr($match[1]) . '">';
	}, $content);
}, 1);

@AndiDittrich
Copy link
Member Author

@willstocks-tech @Mte90

there are 2 possibilities how the content is altered in the database

  1. run a low-level regex on the wp_posts.post_content - this would affect all post types and revisions - there is no way back
  2. use the WordPress API functions to get a post, run the regex and save the post - this will create a new revision for each altered post/page in the database. custom post types are not supported by default.

i would prefer the second option - what do you think ?

@Mte90
Copy link

Mte90 commented Mar 17, 2019

the second will be a bulk operation?

@AndiDittrich
Copy link
Member Author

both of them will be bulk operations

@Mte90
Copy link

Mte90 commented Mar 17, 2019

well if the second is bulk it's fine.
I can do a backup of the db anyway so I don't care right now :-)

@willstocks
Copy link

I second @Mte90's notion - if both are bulk, the second option sounds less risky - ultimately it would also allow a user to rollback an individual post revision (it makes sense not to make changes to revisions as well?)...
Might be worth sticking a notice next to the option to make sure people take a backup of their DB prior to using the function tho'!

@izderadicka
Copy link

Used proposed code for simple plugin (have to modify regex and map some language names as they differ) and it serves as temporary solution for my old posts with crayon (BTW there is also updated for of crayon):

<?php


/*
Plugin Name: Crayon to Enlighter
Plugin URI:  http://zderadicka.eu
Description: Filters old crayon blocks to be compatible with Enlighter
Version:     0.1
Author:      Ivan
Author URI:  http://zderadicka.eu
License:     MIT
License URI: https://opensource.org/licenses/MIT
*/

add_filter('the_content', function($content){
	// crayon filter regex
	$regex = 
		// opening tag, language identifier (optional)
		'/<pre\s+class="([^"]*)lang:([a-z]+)([^"]*)"\s*>' .
		// case insensitive, multiline
        '/im';
        
    $aliases = array("sh"=>"shell", "xhtml"=>"html");
	
    // apply filter regex
	return preg_replace_callback($regex, function($match) use ($aliases){
        $m = $match[2];
        $lang = isset($aliases[$m])?$aliases[$m]:$m;
	return '<pre class="EnlighterJSRAW" data-enlighter-language="' . esc_attr($lang) . '">';
	}, $content);
}, 1);

?>

@AndiDittrich
Copy link
Member Author

i've just added a compatibility mode to Enlighter v4 - the following crayon attributes are supported:

  • lang
  • nums
  • mark
  • title
  • start-line

the filtering is done via the ContentProcessor which also protects the code form wp-auto-p filtering


image

@RehanSaeed
Copy link

@AndiDittrich Thanks for the excellent update. Any limitations we should be aware of? Since this is a compatibility mode, I'm guessing it doesn't convert tags to the enlighter syntax.

@AndiDittrich
Copy link
Member Author

it converts the tags on-the-fly via a filter applied to the_content (also excerpt, widget, comment, commentexcerpt)

Crayon has a lot more options available for each code-tag which are technically not supported by EnlighterJS (most of the options have a global scope or provided via css=

example:

<pre class="lang:js nums:false    theme:twilight mark:1,2-4" title="something">

becomes

<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-highlight="1,2-4" data-enlighter-linenumbers="false" data-enlighter-title="something">

later on i'll add a wp-cli command to make these changes persistent (apply the filter directly on the database)

@AndiDittrich
Copy link
Member Author

i've just release the first beta version of Enlighter v4 including the compat mode

https://github.com/EnlighterJS/Plugin.WordPress/releases/tag/v4.0.0-BETA1


i appreciate your feedback

@florianwalther-private
Copy link

Thanks for the great work.
Do I understand it correctly, that the compatibility mode does NOT make any persistent changes to my content? If I deactivate it, everything will back to normal?
So could I use this feature while I am manually transferring all my old Crayon snippets to Enlighter ones?

@AndiDittrich
Copy link
Member Author

@florianwalther

of course, the changes are just made on-the-fly

@florianwalther-private
Copy link

Does it make sense to wait for 4.0 before switching to Enlighter? Considering that it's not backwards compatible? I have like 1000 code snippets to convert.

@AndiDittrich
Copy link
Member Author

normally you didn't have to touch old posts/snippets - the "compatibility mode" takes care of it
just create new post with the Enlighter Gutenberg block

@florianwalther-private
Copy link

Thank you. So this compatibility mode works flawlessly? Or is it still better to convert my snippets by hand? The code snippets are the heart of my website (they're not in posts but on ordered pages)

@AndiDittrich
Copy link
Member Author

just try it please. in case you didn't edit old post it doesn't matter

@florianwalther-private
Copy link

Does that mean you are not sure? I'd rather not experiment with that on an active site

@AndiDittrich
Copy link
Member Author

you should test it on your testing site ;)
and again: the content is not changed by the compat mode within the database...only the output got modified on-the-fly

@florianwalther-private
Copy link

This compatibility mode is only available in v4? When will the stable update come out?

@AndiDittrich
Copy link
Member Author

there is no fixed roadmap...currently i didn't have any time to re-implement the theme customizer.
the "v4-beta1" includes all features of the stable version without the customizer.

you can also use code snippets above for v3

@r-martins
Copy link

Can I reopen this issue?
I just tested Crayon compatibility with Wordpress 5.5.1 and Enlighter 4.3.1.
It's not working with a code similar to the one mentioned in the first comment of this page.

<pre class="lang:php decode:true" title="app/code/Magenteiro/Observer/Observer/CustomerRegister.php">

@AndiDittrich
Copy link
Member Author

@r-martins

please open a new issue. the compat mode doesn't require any custom php code, it has been added the the stable version

@r-martins
Copy link

Thanks for the prompt response @AndiDittrich .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants