Extra Pepperoni

To content | To menu | To search

Markdown

http://daringfireball.net/projects/markdown/

Entries feed - Comments feed

Tuesday, June 5 2007

Markdown.cgi v1.3: Fixing the Markdown Source

Whoops! I wrote Markdown.cgi so I could easily preview Markdown content in BBEdit, but 1.2 broke this. As a fix, instead of using .markdown for source and .text to see the HTML output, v1.3 goes back to using .text files, and now ?markdown appended to the URL returns the Markdown source.

I considered allowing additional query arguments, but Apple's sh and expr string matching is quite limited, and I don't want to make the whole thing any slower or more complicated than necessary. Fortunately, it would be easy to change the 'magic' query string. Just change the 'markdown' literal on line 7.

I also moved the downloadable (.txt) script, to make the older versions available, and so I can avoid pointing people to old versions.

http://www.reppep.com/~pepper/code/Markdown.cgi/

Tuesday, May 29 2007

Markdown.cgi v1.2

Almost immediately after I announced Markdown.cgi, Adam pointed out that it was now impossible to get the source of a Markdown file, since the CGI was automatically rendering the files to XHTML.

To fix this, I have renamed my Markdown source files from .text to .markdown, and made the CGI look for .markdown files, instead of using the .text filename supplied in the URL. This minor change means the source is now available as .markdown, while the HTML version is available as .text. The Apache configuration does not have to change at all.

Additionally, I updated the comments to mention that Markdown.pl requires blank lines between block elements, so one should follow the initial title line.

The new version of Markdown.cgi is v1.2. You can download and rename Markdown.txt, but here it is for reference:

#!/bin/sh
# Markdown v1.2 2007/05/28
# Build an HTML page (with headers) from Markdown.pl output.

# v1.2: Source is .markdown, available without modification.
# Access as .text to get HTML version.

INCLUDES=/home/web/www.reppep.com/include
REALFILE=`dirname $PATH_TRANSLATED`/`basename $PATH_TRANSLATED .text`.markdown
TITLE=`head -1 $REALFILE | cut -f2`


echo "Content-type: text/html"
echo

cat $INCLUDES/head1.incl
echo $TITLE
cat $INCLUDES/head2.incl

# If we already have an H1, don't insert one.
if ! grep --silent '^# ' $REALFILE
 then
  echo -n '<h1>'
  echo -n $TITLE
  echo '</h1>'
  echo
fi

/usr/local/bin/Markdown.pl < $REALFILE

cat $INCLUDES/foot.incl

exit 0

# http://www.extrapepperoni.com/category/computers/markdown/
# http://daringfireball.net/projects/markdown/

# To use, copy Markdown.cgi (this wrapper, which you may have to rename
# from Markdown.txt) and Markdown.pl (from Daring Fireball) into your
# cgi-bin/ and make them executable
# ("chmod +x Markdown.cgi Markdown.pl"), set the correct path for
# INCLUDES below, and install head1.incl (HTML header up to <title>),
# head2.incl (HTML header starting with </title>), and foot.incl in
# that directory.

# Markdown.cgi reads the page's title from the first line, starting
# after the first tab and ending before the second.
# Your document's title should be inside an HTML comment, set off by tabs.
# Follow the title line with a blank line (Markdown.pl requires blank
# lines between block elements).
# The title line contains 5 parts:
# 1) the HTML comment open delimiter (less-bang-dash-dash)
# 2) a tab
# 3) the title text
# 4) a tab
# 5) the HTML comment close delimiter (dash-dash-greater)
# For example (not counting the # on the next line):
#<!--   Markdown.cgi: A Simple Wrapper for Markdown.pl  -->

# Add the following to your Apache httpd configuration
# (likely httpd.conf or a virtual host .conf file):
#   AddHandler markdown .text
#   Action markdown /cgi-bin/Markdown.cgi
#   AddType text/html .text
#   ScriptAlias /cgi-bin/ /home/web/www.reppep.com/cgi-bin/
#   AddType text/html .pl

Thursday, May 24 2007

Markdown.cgi: Markdown in Apache httpd

I've written a couple articles for TidBITS since they started using John Gruber's Markdown format, and despite actually liking HTML as a writing format, I was impressed with Markdown's simplicity and efficiency (no <p>s are a big time savings!).

So I installed PHP Markdown Extra here on Extra Pepperoni, and got hooked on writing in Markdown. Unfortunately, there's no Markdown plug-in for plain Apache -- lots of ways to parse Markdown in your blogging software or wiki or CMS, but I want to be able to write a .text file and serve it up 'directly' from Apache on www.reppep.com.

Update: Markdown.cgi has been updated. Check my Markdown category for the latest.

Markdown is designed to run as a simple filter, so it's well suited to drop-in installation in a lot of places, without having to build customized versions for a particular application's APIs. There are several implementations -- the original Perl script, as well as versions in PHP (which I use in WordPress, slightly hacked), Python, Ruby, JavaScript, etc. http://markdown.infogami.com/ keeps a list.

Since I couldn't find an Apache handler (plug-in) or a CGI for Markdown, I wrote a very simple wrapper for Gruber's Markdown.pl. Conceptually, my wrapper spits out an HTML header, uses Markdown.pl to render the requested page as (X)HTML, and then appends an (X)HTML footer. The reality is slightly more complicated, due to the vagaries of figuring out the document's title, and conditionally inserting it back into the output as an <H1> tag. Even so, the whole thing is under 60 lines, mostly whitespace and comments.

Markdown.cgi also solves a problem which has wasted a significant amount of my time. BBEdit's built-in Preview tool can use Markdown.pl to generate HTML, which it then passes to WebKit for previewing in a formatted window. But if you put the pages on a real active website, BBEdit has another feature I really like, whereby it will actually calculate a live URL for the page to be previewed, request that URL from the web server, and preview that instead.

This is great, but if you're writing Markdown, BBEdit shows you the unrendered Markdown code (as served up by the web server), instead of rendering the Markdown file from disk. To make matters worse, BBEdit's Preview is live in real time, but continuously re-rendering a Markdown document as you type makes BBEdit stall badly on my 1.5GHz PBG4, so I've stopped using it as a live preview. I instead trained myself to use Markdown.pl as a UNIX script, which I manually trigger to generate a temporary HTML document. I then view this document in BBEdit's live Preview. Among other things, I frequently found myself editing the scratch HTML document, and having to copy my changes back to the Markdown source. Yuck.

Now that my web servers can serve up Markdown .text documents in HTML format, I can skip that whole mess, and go back to previewing .text documents (using Safari or BBEdit's live Preview) with server-side HTML conversion, seeing exactly what surfers see, as Siegel intended.

Tip: If you're reading about or trying out Markdown, don't read the syntax page -- skip to the simple crib sheet on the Dingus page. It's much simpler (and shorter!).


To implement this, I added some lines to my Apache httpd (1.3) configuration, inside the main vhost block:

Action markdown /cgi-bin/Markdown.cgi
AddHandler markdown .text
AddType text/html .text
ScriptAlias /cgi-bin/ /home/web/www.reppep.com/cgi-bin/
AddType text/html .pl

Here is Markdown.cgi, although I had to rename this copy Markdown.txt so you can download it:

#!/bin/sh
# Markdown v1.1.1 2007/05/24
# Build an HTML page (with headers) from Markdown.pl output.

INCLUDES=/home/web/www.reppep.com/include
TITLE=`head -1 $PATH_TRANSLATED | cut -f2`
echo "Content-type: text/html"
echo

cat $INCLUDES/head1.incl
echo $TITLE
cat $INCLUDES/head2.incl

# If we already have an H1, don't insert one.
if ! grep --silent '^# ' $PATH_TRANSLATED
 then
  echo -n '<h1>'
  echo -n $TITLE
  echo '</h1>'
  echo
fi

/usr/local/bin/Markdown.pl < $PATH_TRANSLATED

cat $INCLUDES/foot.incl

exit 0

# http://www.extrapepperoni.com/2007/05/24/markdowncgi-using-markdown-in-apache-httpd/
# http://daringfireball.net/projects/markdown/

# To use, copy Markdown.cgi (this wrapper, which you may have to rename
# from Markdown.txt) and Markdown.pl (from Daring Fireball) into your
# cgi-bin/ and make them executable
# ("chmod +x Markdown.cgi Markdown.pl"), set the correct path for
# INCLUDES below, and install head1.incl (HTML header up to <title>),
# head2.incl (HTML header starting with </title>), and foot.incl in
# that directory.

# Markdown.cgi reads the page's title from the first line, starting
# after the first tab and ending before the second.
# Your document's title should be inside an HTML comment, set off by tabs.
# The title line contains 5 parts:
# 1) the HTML comment open delimiter (less-bang-dash-dash)
# 2) a tab
# 3) the title text
# 4) a tab
# 5) the HTML comment close delimiter (dash-dash-greater)
# For example (not counting the # on the next line):
#<!--   Markdown.cgi: A Simple Wrapper for Markdown.pl  -->

# Add the following to your Apache httpd configuration
# (likely httpd.conf or a virtual host .conf file):
#   AddHandler markdown .text
#   Action markdown /cgi-bin/Markdown.cgi
#   AddType text/html .text
#   ScriptAlias /cgi-bin/ /home/web/www.reppep.com/cgi-bin/
#   AddType text/html .pl

My header and footer are dead simple, but easy to replace with something more sophisticated.

head1.incl:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>

head2.incl:

    </title>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
</head>
<body>

foot.incl:

<hr />

<p align="center"><small><a href="./">home</a></small></p>

</body>
</html>