Textpattern CMS support forum

You are not logged in. Register | Login | Help

#11 2019-11-03 09:13:18

etc
Developer
Registered: 2010-11-11
Posts: 3,356
Website

Re: Code syntax highlighting of bc in txp:body with textile?

jakob wrote #319913:

(txp seems to interpret that as $thing as I discovered which was throwing off the preg_replace code).

Every tag is passed attributes as its first argument and $thing (even if named differently) as the second one. But I think your plugin should act on article save rather than as global attribute.

Offline

#12 2019-11-03 09:45:06

jakob
Admin
From: Germany
Registered: 2005-01-20
Posts: 3,553
Website

Re: Code syntax highlighting of bc in txp:body with textile?

etc wrote #319914:

Every tag is passed attributes as its first argument and $thing (even if named differently) as the second one.

As I gathered :-)

But I think your plugin should act on article save rather than as global attribute.

That’s a much better idea, I agree: process it only once instead of on every page render. I’ll have to investigate that but probably won’t get to that today.


TXP Builders – finely-crafted code, design and txp

Offline

#13 2019-11-03 22:16:06

etc
Developer
Registered: 2010-11-11
Posts: 3,356
Website

Re: Code syntax highlighting of bc in txp:body with textile?

jakob wrote #319915:

I agree: process it only once instead of on every page render.

This, plus removing the need to care about syntaxhint attribute.

Offline

#14 2019-11-04 21:42:31

jakob
Admin
From: Germany
Registered: 2005-01-20
Posts: 3,553
Website

Re: Code syntax highlighting of bc in txp:body with textile?

Thanks again for the pointers. After a little experimentation I think I have it working as a simple plugin that, as you suggested, simply works on installation and activation without any public-side tags. One only has to go over old articles, add the code identifier to the article body and resave.

It hooks into article_saved & article_posted as follows:

if (txpinterface === 'admin') {
    register_callback('jcr_syntaxhint', 'article_posted');
    register_callback('jcr_syntaxhint', 'article_saved');
}

function jcr_syntaxhint($event, $step, $rs)
{
     // if there's a value for current article ID, extract it into a variable, otherwise do nothing
     if (!($row = safe_row('Body_html', 'textpattern', 'ID='.$rs['ID']))) return;
     extract($row);

     // borrowed wholesale from @gocom's code for the textpattern forum
     // list of permitted code language identifiers (for prism)
     static $extra_code_language_identifiers = array(
         'apacheconf',
         'clike',
         'coffeescript',
         'css',
         'git',
         'haml',
         'html',
         'javascript',
         'js',
         'json',
         'less',
         'markdown',
         'markup',
         'nginx',
         'perl',
         'php',
         'ruby',
         'sass',
         'scss',
         'sql',
         'stylus',
         'textile',
         'txp',
         'yaml',
     );

     $code_language_identifiers = implode('|', $extra_code_language_identifiers);

     // search and replace bc..{space}{newline}code identifier{newline} to prism classes
     $body_html_codehint = preg_replace(
         '@<pre><code>(?:\/\/|#|;)?(?:\s+)?('.$code_language_identifiers.')[\n\r]+@',
         '<pre class="prism language-$1" data-language="$1"><code>',
         $Body_html
     );
     $body_html_codehint = doSlash($body_html_codehint);

     // write back to the database
     safe_update('textpattern', "Body_html = '$body_html_codehint'", 'ID = '.$rs['ID']);
 }

Is this the right way of going about things? i.e. retrieve the field, manipulate it and write it back to the database, or can you hook into the data before it gets written to the database? I had no luck with $rs['Body_html'].

Also, I presume $rs['ID'] comes straight from the page and can’t be tampered with so doesn’t need assert_int() for safety.

Another question: how does article_posted and article_saved handle several functions? i.e. if I had other functions that also manipulated the content. Do they chain, or does the last/first plugin to fire displace the others? If they chain, how do I control the order?


TXP Builders – finely-crafted code, design and txp

Offline

#15 2019-11-04 22:25:42

etc
Developer
Registered: 2010-11-11
Posts: 3,356
Website

Re: Code syntax highlighting of bc in txp:body with textile?

jakob wrote #319924:

Is this the right way of going about things? i.e. retrieve the field, manipulate it and write it back to the database, or can you hook into the data before it gets written to the database? I had no luck with $rs['Body_html'].

Not necessarily a right one, but the only way atm, since $rs[Body_html] is not set. We should set it and also add a pre-save callback, imo.

Also, I presume $rs['ID'] comes straight from the page and can’t be tampered with so doesn’t need assert_int() for safety.

It’s ok for $rs['ID'], but you must escape $body_html_codehint before inserting it into db:

$body_html_codehint = doSlash($body_html_codehint);

Another question: how does article_posted and article_saved handle several functions? i.e. if I had other functions that also manipulated the content. Do they chain, or does the last/first plugin to fire displace the others? If they chain, how do I control the order?

They chain and are ordered by plugins load order (which you don’t really control because it can be altered by users).

Offline

#16 2019-11-04 22:55:17

jakob
Admin
From: Germany
Registered: 2005-01-20
Posts: 3,553
Website

Re: Code syntax highlighting of bc in txp:body with textile?

Brilliant. Thank you! That’s very informative.

etc wrote #319925:

It’s ok for $rs['ID'], but you must escape $body_html_codehint before inserting it into db:

$body_html_codehint = doSlash($body_html_codehint);...

Makes sense. Duly done. I’ve added it to my own code and the code above.


TXP Builders – finely-crafted code, design and txp

Offline

#17 2019-11-05 15:48:35

philwareham
Core designer
From: Farnham, Surrey, UK
Registered: 2009-06-11
Posts: 3,199
Website

Re: Code syntax highlighting of bc in txp:body with textile?

You can of course use JavaScript for this task, for example:

var code = document.querySelectorAll('pre code');

if (code.length) {
    var elems = document.querySelectorAll('.language-txp');

    [].forEach.call(elems, function(el) {
        el.classList.add('language-html');
        el.classList.remove('language-txp');
    });

    Prism.highlightAll();
}

Offline

#18 2019-11-05 18:37:24

etc
Developer
Registered: 2010-11-11
Posts: 3,356
Website

Re: Code syntax highlighting of bc in txp:body with textile?

philwareham wrote #319931:

You can of course use JavaScript for this task

That’s how I understood it, indeed. But actually it would be better to generate all markup server-side, avoiding downloading Prism.js (only css) and processing to clients.

Offline

#19 2019-11-05 21:56:13

jakob
Admin
From: Germany
Registered: 2005-01-20
Posts: 3,553
Website

Re: Code syntax highlighting of bc in txp:body with textile?

philwareham wrote #319931:

You can of course use JavaScript for this task, for example:

var code = document.querySelectorAll('pre code');...

Yes, exactly that is what I have. The plugin code above only makes it possible for you to add your code language using textile in the article body (like you can here in the forum). The js-switch from language-txp to language-html may not be necessary if some day we have a prism syntax file for txp itself :-)

etc wrote #319933:

That’s how I understood it, indeed. But actually it would be better to generate all markup server-side, avoiding downloading Prism.js (only css) and processing to clients.

What would you suggest for that, then? I know php has highlight_string but by all accounts that’s pretty basic and adds the css colors inline on its own (no extra css required).

I hadn’t seen a php-only implementation of prism. On the admin-side we currently also use the js file. Or do you mean preprocessing Body_html through prism.js on the admin-side when saving? I don’t have node.js on this server nor have I ever explored V8js.

Otherwise, there is a php port of highlight.js, though. There is also a css-only project called ft-syntax-highlight but the minified css for that comes in as heavier than the js+css of prism.js.


TXP Builders – finely-crafted code, design and txp

Offline

#20 2019-11-06 10:41:12

etc
Developer
Registered: 2010-11-11
Posts: 3,356
Website

Re: Code syntax highlighting of bc in txp:body with textile?

jakob wrote #319943:

What would you suggest for that, then? I know php has highlight_string but by all accounts that’s pretty basic and adds the css colors inline on its own (no extra css required).

I hadn’t seen a php-only implementation of prism. On the admin-side we currently also use the js file. Or do you mean preprocessing Body_html through prism.js on the admin-side when saving? I don’t have node.js on this server nor have I ever explored V8js.

Dunno, sorry, just thinking to myself that sending a js file to every visitor (even those who visit a page without any code to highlight) is not optimal. A Textile plugin would be great if you fancy exploring unbeaten roads ;-)

Otherwise, there is a php port of highlight.js, though. There is also a css-only project called ft-syntax-highlight but the minified css for that comes in as heavier than the js+css of prism.js.

This css thingy is amazing but seems to require a special markup to be fully-powered.

Offline

Board footer

Powered by FluxBB