Because I'm a grumpy old man, I don't use Gutenberg or Block themes on my WordPress. Instead, I write everything in Markdown.
When I write code snippets in Markdown, they look like this:
```php
$a = 1;
echo $a;
if ($a < 5) {
// Do Something
return thing( $a, true );
}
```
But I want to render that with code highlighting. I was using the Prismatic Plugin. It is excellent and very customisable. But it uses JavaScript to do the code highlighting. I want to respect my readers' time and battery life; so I'm trying to reduce my dependency on Client-Side rendering.
I've switched to a modified version of WP-GeSHi-Highlight. That turns the above Markdown into:
PHP
$a = 1; echo $a; if ($a < 5) { // Do Something return thing( $a, true ); }
Necessary Changes
When the JetPack Markdown pre-processor encounters a code block, it changes:
```php
into
<pre><code class="language-php">
This means the WP-GeSHi-Highlight detection needs to be changed.
Old version:
PHP
return preg_replace_callback( "/\s*<pre(?:lang=[\"']([\w-]+)[\"']|line=[\"'](\d*)[\"']" ."|escaped=[\"'](true|false)?[\"']|cssfile=[\"']([\S]+)[\"']|\s)+>". "(.*)<\/pre>\s*/siU", "wp_geshi_store_and_substitute", $s );
New version:
PHP
return preg_replace_callback( "/\s*<code(?:class=[\"']language\-([\w-]+)[\"']|line=[\"'](\d*)[\"']" ."|escaped=[\"'](true|false)?[\"']|cssfile=[\"']([\S]+)[\"']|\s)+>". "(.*)<\/code>\s*/siU", "wp_geshi_store_and_substitute", $s );
One of those matches looks for escaped= which can be true or false. I always want this to be true so, later in the code, I change a variable from:
PHP
$escaped = trim($match[3]);
To:
PHP
$escaped = true;
Style Changes
By default, everything looks pretty good - but there are a few changes I found necessary to make.
Firstly, there was something weird going on with the line-heights of my style, so I added this to my site's CSS:
CSS
/* GeSHI Highlighter Fixes */ pre:has(> .wp-geshi-highlight-wrap5) { line-height: 0; padding: 0; background: none; filter: invert(1); }
The invert gives it a dark mode.
Secondly, in order to make any changes to the default styles of the highlighter, you need to add the bundled wp-geshi-highlight.css file into your style directory. The plugin will use that if it exists - so you can change font size and padding to be the same as your main theme.
Limitations
There are a few limitations with this approach.
No line-numbers. The plugin looks for something like line="13", but there's no way to add that in Markdown.
GeSHi hasn't received style updates on some languages for quite some time. It hasn't received any significant update since 2019. Which means bugs and security issues are likely.
Language definitions are quite strict. You can use javascript but not json.
The plugin doesn't have any options - nor an easy way to override its settings. So I've monkeypatched everything above. If the plugin updates, I'll need to change my code.
Demos
A few demos - just so you can see what it looks like.
Python
Python 3
#!/usr/bin/env python from datetime import datetime, timedelta from mastodon import Mastodon from bs4 import BeautifulSoup import config # Set up access mastodon = Mastodon( api_base_url=config.instance, access_token=config.access_token ) # Get user's info me = mastodon.me() my_id = me["id"] year_joined = me["created_at"].year
Bash
Bash
if [ "$(basename $2)" = "Image.gz" ] || [ "$(basename $2)" = "vmlinuz.efi" ] then # Compressed install echo "Installing compressed kernel" base=vmlinuz else # Normal install echo "Installing normal kernel" base=vmlinux fi if [ -f $4/$base-$1 ]; then mv $4/$base-$1 $4/$base-$1.old fi
Rust
RUST// This is the main function.
fn main() {
// Print text to the console.
println!("Hello World!");
}
JavaScript
JAVASCRIPT
if (hour < 18) { greeting = "Good day"; alert( greeting ); }
3 thoughts on “Server-Side Rendering of Embedded Markdown Code Snippets in WordPress”
@blog For those who use blocks, the plugins with the name «Syntax-highlighting Code Block (with Server-side Rendering)» by a Weston Ruter https://wordpress.org/plugins/syntax-highlighting-code-block/ which uses https://github.com/scrivo/highlight.php (a hightligt.js port) might be an alternative @Edent
| Reply to original comment on mastodon.social
@Edent I do something similar with Craft. Everything in Markdown.
I need to have a code-snippet solution. I’ve only run into the issue once but it caused some headaches for me when trying to publish my email.
| Reply to original comment on writing.exchange
It seems to include an additional <pre>
<pre>element with a few lines of whitespace, when rendering it in the RSS feed.In fact, it puts the
divinside thepre, which is not allowed, and thus some user agents believe there is aprewith a few lines of whitespace, a forgotten close-pre tag, and then it starts thediv. In other words, it doesn't look "right" when viewing on some browsers or RSS readers. (In my case, Inoreader.)More comments on Mastodon.
What links here from around this blog?