TOPIC: INCLUDE DIRECTIVE
Rendering Markdown in WordPress without plugins by using Parsedown
4th November 2025Much of what is generated using GenAI as articles is output as Markdown, meaning that you need to convert the content when using it in a WordPress website. Naturally, this kind of thing should be done with care to ensure that you are the creator and that it is not all the work of a machine; orchestration is fine, regurgitation does that add that much. Naturally, fact checking is another need as well.
Writing plain Markdown has secured its own following as well, with WordPress plugins switching over the editor to facilitate such a mode of editing. When I tried Markup Markdown, I found it restrictive when it came to working with images within the text, and it needed a workaround for getting links to open in new browser tabs as well. Thus, I got rid of it to realise that it had not converted any Markdown as I expected, only to provide rendering at post or page display time. Rather than attempting to update the affected text, I decided to see if another solution could be found.
This took me to Parsedown, which proved to be handy for accomplishing what I needed once I had everything set in place. First, that meant cloning its GitHub repo onto the web server. Next, I created a directory called includes under that of my theme. Into there, I copied Parsedown.php to that location. When all was done, I ensured that file and directory ownership were assigned to www-data to avoid execution issues.
Then, I could set to updating the functions.php file. The first line to get added there included the parser file:
require_once get_template_directory() . '/includes/Parsedown.php';
After that, I found that I needed to disable the WordPress rendering machinery because that got in the way of Markdown rendering:
remove_filter('the_content', 'wpautop');
remove_filter('the_content', 'wptexturize');
The last step was to add a filter that parsed the Markdown and passed its output to WordPress rendering to do the rest as usual. This was a simple affair until I needed to deal with code snippets in pre and code tags. Hopefully, the included comments tell you much of what is happening. A possible exception is $matches[0]which itself is an array of entire <pre>...</pre> blocks including the containing tags, with $i => $block doing a $key (not the same variable as in the code, by the way) => $value lookup of the values in the array nesting.
add_filter('the_content', function($content) {
// Prepare a store for placeholders
$placeholders = [];
// 1. Extract pre blocks (including nested code) and replace with safe placeholders
preg_match_all('//si', $content, $pre_matches);
foreach ($pre_matches[0] as $i => $block) {
$key = "§PREBLOCK{$i}§";
$placeholders[$key] = $block;
$content = str_replace($block, $key, $content);
}
// 2. Extract standalone code blocks (not inside pre)
preg_match_all('/).*?<\/code>/si', $content, $code_matches);
foreach ($code_matches[0] as $i => $block) {
$key = "§CODEBLOCK{$i}§";
$placeholders[$key] = $block;
$content = str_replace($block, $key, $content);
}
// 3. Run Parsedown on the remaining content
$Parsedown = new Parsedown();
$content = $Parsedown->text($content);
// 4. Restore both pre and code placeholders
foreach ($placeholders as $key => $block) {
$content = str_replace($key, $block, $content);
}
// 5. Apply paragraph formatting
return wpautop($content);
}, 12);
All of this avoided dealing with extra plugins to produce the required result. Handily, I still use the Classic Editor, which makes this work a lot more easily. There still is a Markdown import plugin that I am tempted to remove as well to streamline things. That can wait, though. It best not add any more of them any way, not least avoid clashes between them and what is now in the theme.
Taking control of Ruff checks on Python scripts
22nd October 2025Positron is becoming my tool of choice for developing Python code. Along from using a Python console like a REPL environment, it also includes Ruff for checking code compliance. One of its rules is that Python modules must be declared at the top. However, I want to use some code that checks for the present of any modules used in a script, installing those that are missing. This means that import statements appear later in a script that Ruff recommends, making me wish for a way to turn off that check since things run well anyway. The chosen solution is to create a file called pyproject.toml in the directory where my scripts are store and add the following lines in there to accomplish what I want:
[tool.ruff]
ignore = ["E402"]
Here, it helps if you open a folder in Positron, achieving the same outcome as you would in the VSCode on which the IDE is based. While I have only listed one check here, you also can have a comma-delimited list of quoted strings if you need to switch off more than one rule at once.
Using multi-line commenting in Perl to inactivate blocks of code during testing
26th December 2019Recently, I needed to inactivate blocks of code in a Perl script while doing some testing. Since this is something that I often do in other computing languages, I sought the same in Perl. To accomplish that, I need to use the POD methodology. This meant enclosing the code as follows.
=start
<< Code to be inactivated by inclusion in a comment >>
=cut
While the =start line could use any word after the equality sign, it seems that =cut is required to close the multi-line comment. If this was actual programming documentation, then the comment block should include some meaningful text for use with perldoc. However, that was not a concern here because the commenting statements would be removed afterwards anyway. It also is good practice not to leave commented code in a production script or program to avoid any later confusion.
In my case, this facility allowed me to isolate the code that I had to alter and test before putting everything back as needed. It also saved time since I did not need to individually comment out every executable line because multiple lines could be inactivated at a time.