How to use Markdown in WordPress and preserve spaces in code blocks

It’s easy to add Markdown support to WordPress. However, it does have a nefarious quirk. In fact, even if you can input Markdown text from the Text panel, and it gets rendered just fine in the blog, the harsh truth is that, as soon as you inadvertently switch to the Visual panel, all the white space in your code blocks gets wiped out, losing all the indentation you had put in.

This looks like a typical reason for writing a plugin to fix that.

Use a shell plugin

Given that I often need small WordPress adjustments like this one, in the past I developed one ring to rule them all: Custom Stuff.

<?php
/*
Plugin Name: Custom Stuff
Plugin URI: http://andowebsit.es/
Description: Custom stuff for my blog.
Author: Andrea Ercolino
Author URI: http://andowebsit.es/about
Version: 1.0
*/

function custom_stuff_header() {
    require 'header.php';
}
add_action( 'wp_head',  'custom_stuff_header', 10, 0 );


function custom_stuff_footer() {
    require 'footer.php';
}
add_action( 'wp_footer',  'custom_stuff_footer', 10, 0 );

 (file wordpress/wp-content/plugins/custom-stuff/custom-stuff.php)

which is just a simple PHP script that basically declares itself as a WordPress plugin and all it does is to require other PHP scripts where the real action takes place.

Design a usable solution

What we need is a way to make WordPress aware that a post is written in Markdown thus no Visual editor will ever be allowed for it.

My solution is based on the user_can_richedit hook and the Shortcode API. It works like this:

  1. At the start of a Markdown text, you add the shortcode.
  2. In editing mode, the hook handler determines whether or not a post begins with that shortcode. If it does, a false is returned, thus effectively forbidding the Vsual editor.
  3. In reading mode, that shortcode is just replaced by an empty string.

Code

<?php

function custom_stuff_no_richedit_if_content_asks( $default ) {
    global $post;
    $content = $post ? $post->post_content : '';
    $start = '';
    if ( substr($content, 0, strlen($start)) === $start ) {
        return false;
    }
    return $default;
}
add_filter( 'user_can_richedit', 'custom_stuff_no_richedit_if_content_asks', 10, 1 );

function custom_stuff_nothing() {
    return '';
}
add_shortcode( 'no_richedit', 'custom_stuff_nothing', 10, 0 );

 (file wordpress/wp-content/plugins/custom-stuff/no-richedit.php)

<?php
/*
Plugin Name: Custom Stuff
Plugin URI: http://andowebsit.es/
Description: Custom stuff for my blog.
Author: Andrea Ercolino
Author URI: http://andowebsit.es/about
Version: 1.1
*/

function custom_stuff_header() {
    require 'header.php';
}
add_action( 'wp_head',  'custom_stuff_header', 10, 0 );


function custom_stuff_footer() {
    require 'footer.php';
}
add_action( 'wp_footer',  'custom_stuff_footer', 10, 0 );

require 'no-richedit.php';

 (file wordpress/wp-content/plugins/custom-stuff/custom-stuff.php)

Example

This is how WordPress looks like when the shortcode is used. Notice that there is no Visual editor panel

This is how WordPress looks like when the shortcode is not used.

Only one thing to remember

There is only one thing to remember then. When adding a post, before introducing any relevant Markdown, switch to the Text panel, add the [no-richedit] shortcode and save a draft. Then the Visual editor won’t appear anymore for that post. (until you remove the shortcode and save again)

One Reply to “How to use Markdown in WordPress and preserve spaces in code blocks”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.