Toward Better Inline Images

Toward Better Inline Images

The Markdown Image Hack has been retired. Information here is for historical interest.

I can now insert images using my own hacked version of Markdown 1.0’s inline image syntax. Yay! I love Markdown, because it allows me to avoid using actual HTML tags in my posts. However, its inline image support was quite basic.

The modification I’ve done allows me to type:

    !@[images/boogah.jpg](index?p=36 "juicy!")(L120)

…instead of…

     <a class="image-left" title="Juicy!"
        <img src="/wp-content/images/boogah-120.jpg"
     width="120" height="133" alt="Juicy!" />

!@images/test1.jpg( L100) So what’s the big deal, you ask? Markdown already has image support, but it doesn’t support width or additional formatting. And personally speaking, it’s also my first dabbling into the WordPress’ plugin architecture and PHP coding. It was also a painful re-union with regular expressions, of which Markdown makes heavy use in the course of doing its texty magic.

!@images/test2.jpg( R100) As much as I like PictPress, I still wanted more flexibility in placement of the images, and I wanted to be able to add text to individual pages for my portfolio. PictPress was almost there, but not quite. I realized that I could achieve the same functionality manually by just using the more and nextpage tags. One feature I wanted, though, was the automatic image caching, because it makes file image management less of a hassle…I hate cutting thumbnails!

I’m pleased that this hack mostly works and looks pretty good, though I am wondering how I might have implemented this cleaner. If you’re curious read on, or skip to the downloading part

The Lowdown

While Markdown does have inline support for images already, I wanted something that produced some nicer thumbnail layouts. I also liked the idea of automatic thumbnail creation, which is something PictPress does. So I started with the Michel Fortin’s port of PHP-Markdown, and starting chipping away.

!@images/test2.jpg( R50) !@images/test1.jpg( L50) The code I added to Markdown creates cached files of the name origname-nnncached.jpg, where nnn is the width in pixels, and stores them in the same directory as the original uploaded file. This automatic resize-and-cache was inspired by PictPress’ resize.php code, though I’m using it within the Markdown code itself instead as a replacement for img src. I also decided not to create a separate cache directory, figuring I could use recursive rm commands instead to purge when I needed to.

!@images/test2.jpg( R160) !@images/test1.jpg( R80) The general approach I took was to look at Markdown’s code to see where its inline image parsing was. This was illuminating because to that point, I didn’t really know how WordPress worked. WordPress 1.2 plugins can make many many passes at the text for every page view request. Wow. I see the advantage of the static Movable Type system here…rebuilding your MT site may suck for immediate gratification, but the tradeoff is loading down the server. I’ve noticed that this site is a bit sluggish to load already (but I am also using phpcgi on my host so files are created under my uid).

!@images/test3.jpg( N450) For the centered image, my layout maxes out at 450 pixels. I made a centering attribute, but it probably wouldn’t actually center for anything less than 450 pixels; the reason for having a ‘C’ attribute is so the image-center class doesn’t add margin on the left and right. Yeah yeah, I’m fussy.

The Hack

In the PHP-Markdown code, I duplicated the _DoImages() function and made a new variation called _DoCachedImages(). These functions handle the parsing for the image syntax. I had originally tried to extend the _DoImages() functionality with the existing syntax, but didn’t realize it was broken in the 1.0b4 version that shipped with my install of WordPress. After getting the latest version, I still wasn’t sure what the best way to handle having two optional parameters in a regular expression, so for the sake of limiting damage to core functions, I split out my own routine.

Markdown does a lot of interesting things to ensure its simple markup language works in the context of an xhtml-compliant page, so there is a particular order to how things are done. Most of it I have not yet grasped, so I inserted my own call to _DoCachedImages() right next to the original _DoImages() call in _RunSpanGamut().

A consequence of doing it here are “block-level formatting” conflicts. Markdown has already created wrapping paragraph tags at this point, so that means you can’t insert divs with any of the inline markup. I couldn’t figure out how to scan and create block-level hash keys from markdown syntax, so I went with a simpler thumbnail layout that just uses borders and padding. So no nice PictPress dropshadows :(

As for _DoCachedImages() itself, all it does is handle my variation on the inline image syntax. At the time the filter is invoked, it will know the URL for the A tag, and the relative URI for the image, and the requested size and alignment. This is everything needed to emit the proper bit of html.

Some decisions I made:

  • The URI for the image is always the one you uploaded to your wp-contents folder, no matter what size you’ve specified. _DoCachedImages() generates the thumbnail files and substitutes the appropriate thumbnail URI for you. The idea is to not have to worry about the names of thumbnails at all. You also don’t have to include wp-contents in the URI, because we will always assume you’ve uploaded there.

  • There are three kinds of alignment: L (left), R(right) and N(center, no margin). They are case-insensitive, and part of the requested thumbnail width. So a “right aligned 250pixel thumbnail” is expressed as “R250”. If you leave out the parameter, the code is supposed to show the full image, but that doesn’t really make sense so I may change that.

  • The alignment letters are used to output the HTML using different CSS classes that you can define in wp-layout.css. The CSS is unremarkable-they just have different padding and margin values set-but they’re exposed if you want to sex them up. Here’s an example: a.image-left { float: left; margin: 4px 16px 8px 0px; } a.image-left img { display: block; border: 1px solid #9999aa; background-color: #fff; vertical-align: text-top; padding: 4px; } There is probably a better way of doing this…I’m a CSS novice, no relation at all to guru Dave Shea.


p>:: Continued in Inline Image Hack


  1. Curioso 15 years ago

    GPL means that you are free to redistribute your modified code as long as you keep it under GPL, i.e. others may do the same.

    And as for me, I am happy as long as you acknowledge where your code came from.

  2. Bobd314 15 years ago

    For some reason, I always get a “file not found” error on mine..