android (3)
ant (2)
beautifulsoup (1)
debian (1)
decorators (1)
django (9)
dovecot (1)
encryption (1)
fix (4)
gotcha (2)
hobo (1)
htmlparser (1)
imaplib (2)
java (1)
json (2)
kerberos (2)
linux (7)
lxml (5)
markdown (4)
mechanize (6)
multiprocessing (1)
mysql (2)
nagios (2)
new_features (3)
open_source (5)
optparse (2)
parsing (1)
perl (2)
postgres (1)
preseed (1)
pxe (4)
pyqt4 (1)
python (41)
raid (1)
rails (1)
red_hat (1)
reportlab (4)
request_tracker (2)
rt (2)
ruby (1)
scala (1)
screen_scraping (7)
shell_scripting (8)
soap (1)
solaris (3)
sql (2)
sqlalchemy (2)
tips_and_tricks (1)
twitter (2)
ubuntu (1)
vmware (2)
windows (1)
zimbra (2)

I have moved the code repository to Google Code. In addition, the latest version respects youtube's URL get values, like hd=1.

Grab a clone like so:

hg clone python-markdown-video

This is only the version compatible with python markdown 2.0. The version for earlier versions of python markdown is now deprecated and will not be maintained.

Posted by Tyler Lesmann on October 20, 2009 at 9:33
Tagged as: markdown open_source python

Waylan Limberg tells me python-markdown will be releasing version 2.0 at the end of this week. This release breaks my extension and all others written for 1.7. My extension obsoleted within a less than a week of release. That would not do, so I have updated the code to work on 2.0! It's still under LGPL.

You can get it here or clone the Mercurial repository like so:

hg clone

Use and install are exactly the same as with the earlier version. Adding new services has changed and I will get to documenting that soon.

Posted by Tyler Lesmann on April 2, 2009 at 15:20 and commented on 6 times
Tagged as: django markdown open_source python

I'm a big fan of markdown, especially the fact that it can be extended so easily. I wanted to give the users of DeathCat Inc. the ability to embed video from popular services in their posts with only an URL, so I wrote up a new extension. To see it in action, go here. This code is licensed under LGPL.

You can get it here.

It is installable as many other python modules...

python install

..., but only has to be in your PYTHON_PATH. With Django, for instance, you can place it in the same directory as

Using my extension is like using any other extension for markdown.

>>> import markdown
>>> s = ""
>>> markdown.markdown(s, ['video'], safe_mode='escape')

Remember to set safe_mode to escape if you are passing untrusted users' input through markdown, extension or not. This extension supports arguments for setting the dimension of the video. By default, the dimensions are what the specific service gives for their example embed. If you don't like this size, then you can change it like so:

>>> markdown.markdown(s, ['video(youtube_width=720, youtube_height=400)'], safe_mode='escape')

If you want to integrate markdown and this extension with Django, then I recommend looking at this post.

This extension supports the following services:

  • Dailymotion
  • Metacafe
  • Veoh
  • Vimeo
  • Yahoo! video
  • Youtube

NOTE: works a little differently than the others because there is no way to construct a working object with the player URL. Instead of the URL to the page, you will use the URL to the flv file, like for example. This is located in Files and Links section of

Adding extra services is easy. Note: This portion is relevant to the extension for python-markdown 1.7. The first part is defining what URL for the video service should look like. You do this in the extendMarkdown method of VideoExtension.

# This regular expression looks for a youtube URL that do not start with parenthesis.
# It does this to avoid eating regular markdown links.
YOUTUBE_RE = r'([^(]|^)http://www\.youtube\.com/watch\?\S*v=(?P<youtubeid>[A-Za-z0-9_-]+)\S*'
# Here we plug our expression into the bit that builds the video embed html.
# We define this shortly.
# The next two lines allow control of markdown through instances of this class. = md
# This registers everything with markdown, so the code will be executed.

Next, we get to build the HTML. We need to add a new subclass of markdown.BasePattern to the module.

class Youtube(markdown.BasePattern):
    def handleMatch(self, m, doc):
        url = '' %'youtubeid')
        width = self.ext.getConfig('youtube_width')
        height = self.ext.getConfig('youtube_height')
        return FlashObject(doc, url, width, height)

For the most part, building the HTML is easy. I have defined a flash_object function that builds an object element that work in most cases. You only need to feed it your minidom instance, doc, an url, and width/height, both as strings. You will notice that I am using self.ext.getConfig to assign my width and height. These are the extension arguments. You will want to use these too. To do so, add a new key to the self.config dictionary of __init__ in VideoExtension.

'youtube_width': ['640', 'Width for Youtube videos'],
'youtube_height': ['385', 'Height for Youtube videos'],

The first part is the default value and the second bit is a description of the argument. If you need to define more HTML, then I suggest taking look at the Yahoo class.

Posted by Tyler Lesmann on April 2, 2009 at 8:16 and commented on 10 times
Tagged as: django markdown open_source python

For the longest time, I've been using markdown in the Django template engine. This is the dumb way of implementing markdown in Django. It's slow to render and it puts too much programming into the template system, which is against Django philosophy.

The smart way to add markdown functionality is by extending the save method of your models. On this little blog for instance, I have an Entry model. This is what the save method looks like.

def save(self):
    self.body = markdown.markdown(self.body_markdown, safe_mode='escape')
    super(Entry, self).save()

I have two fields that hold the different bodies. The body_markdown is the body of the Entry with markdown markup and the body field is the html version. No extra programming is required. Whenever an Entry is saved, a new html body is created using markdown. Then, the models.Model save method is called and the model is written to the database.

Now, instead of markdown parsing every page load as it would have through templates, it does it once per save. The only downside of this approach is you are using up more than twice as much space for each Entry. Disk space is cheaper than cycles, memory, and your visitors' patience though.

Posted by Tyler Lesmann on July 25, 2008 at 5:58
Tagged as: django markdown python