Friday, December 31, 2010

Fixing WymEditor from stripping out YouTube embedded links

JavaScript/jQuery doesn't come with a routine to remove elements from an array, so we create one as follows. This code was inspired from the MooTools v1.3 code:
Array.prototype.remove = function(item)
    for(var i = this.length; i--;) {
        if(this[i] === item) this.splice(i,1);
    return this;

We'll later use this remove() function to remove <param> tag from being considered as a block tag, and insert param/embed tags an inline_tags.
var XhtmlSaxListener = WYMeditor.XhtmlSaxListener;
        WYMeditor.XhtmlSaxListener = function () {
            var listener =;
            return listener;
If we really wanted to be consistent, we could also use the following statements with the WymEditor patch, we can do the following:
WYMeditor.XhtmlValidator['_tags']["embed"] = {
WYMeditor.XhtmlValidator['_tags']['param'] = {
            "attributes" : ["type", "value", "name"],
            "required" : "name",
            "inside" : "object"

Copying a bunch of images defined in a CSS

Suppose we want to verify that all the images defined in a CSS file exist. We could also want to copy all of the images to a remote server dir. Using grep and awk, we can dump out a command line that will print an scp command that can then be piped to be executed.

grep -oi "../images/.[^)]*" /tmp/bla.css | awk '{print "scp " $0 ""}' | sh

The -o flag in grep will output only the matching field. Since non-greedy expressions can only be represented with the [^)]* field (Python/Perl allow for the .* syntax to denote non-greedy), we express this grep command match everything up to the closing parenthesis.

Sunday, December 19, 2010

Creating slideshow picture/audio clips

Picasa for Windows 7/Vista allows you the ability to create slideshows from images, as well as including audio clips that can be added to the presentation.   You can use Ubuntu's ffmpeg command to extract the audio, but there are several steps that also need to be done to equip your machine to do so.

1. First, you should verify that your Ubuntu installation has the 'multiverse' repository added. On Slicehost instances only the 'universe' install, so trying to proceed to the next steps will fail since there are package dependencies that are not included with just the basic universe repository.

deb lucid main restricted universe multiverse
deb-src lucid main restricted universe multiv

deb lucid-updates main restricted universe mu
deb-src lucid-updates main restricted univers
e multiverse

deb lucid-security main restricted universe m
deb-src lucid-security main restricted univer
se multiverse

2. Next, you need to install the Medibuntu instructions. One way is to install 'ffmpeg' manually but the quicker way is to install the Medibuntu packages. The instructions are listed here:

You can also execute this command which will use wget to add the Medibuntu to sourceslist, and the Medibuntu package repository, and install the medibuntu-keyring package:
sudo wget`lsb_release -cs`.list --output-document=/etc/apt/sources.list.d/medibuntu.list && sudo apt-get -q update && sudo apt-get --yes -q --allow-unauthenticated install medibuntu-keyring && sudo apt-get -q update
3. You should be able to run this command. Again, if you're missing the multiverse repository, the libavcodec-extra-52 will complain that it is missing a few dependencies (i.e. libmp3lame0) and fail to install.
apt-get install ffmpeg libavcodec-extra-52
4. The final step is to use ffmpeg to extract audio clips:
ffmpeg -i -vn

The -vn flag will remove the video and output an MP3 file with the extracted audio. From there, you can add the MP3 to your movie clip. Remember, only Picasa for Windows supports this feature. Picasa for Ubuntu will only allow you to create an .AVI file without any MP3 soundtracks.

Saturday, December 18, 2010

Converting JPG to GIFs with ls and awk...

ls *.jpg | awk -F "." '{print "convert " $1".jpg " $1".gif"}' | sh

Friday, December 17, 2010

The trouble with contenteditable and WYSWYG editors..

If you want to implement some type of WYSWYG editors, there are several options.  You can try out CkEditor (, which seems to be a re-write of the popular FCkEditor.  It's still 300kB gzip'd, and it has a lot of plug-ins.  You can also TinyMCE and WymEditor, and neither seem optimal since they add so many extra HTML tags and add to the code base.  There's WysiHat, which is used in Basecamp and developed by, but primarily leverages Prototype so JQuery/MooTools frameworks are out.

Enter the 'contenteditable' attribute, which lets you turn any DOM element into an editable field.  You can bold, highlight, italicize and the browser automatically adds the appropriate HTML tag.  The challenge of course is that different browsers add different tags when the Enter button is pressed.  The approach listed here is to intercept the Enter key and insert <br> tags to avoid cross-browser issues:

There isn't an answer on Stack Overflow threads about what to do with the browser to get the cursor position to be move to be situated after "<br>" tags are inserted.  I looked through the CKEditor source code and there's a specific plug-in called _source/plugins/enterkey/plugin.js that tries to deal with the issue. It looks like what ends up happening is that not only is a <br><br/> is added but also an extra bogus <br> is added, in addition to a <span>&nbsp;</span> gets inserted.  The code gets even more convoluted when you start working with IE and Opera browsers, so this general approach just seems a bit difficult in geneal.

The solution may be to post-replace these tags instead:

collapse() in Ran

A good explanation of JavaScript DOM ranges...

Collapsing a DOM Range

To empty a range, (that is, to have it select no part of the document), you collapse it. Collapsing a range resembles the behavior of a text box. When you have text in a text box, you can highlight an entire word using the mouse. However, if you left-click the mouse again, the selection is removed and the cursor is located between two letters. When you collapse a range, you are setting its locations between parts of a document, either at the beginning of the range selection or at the end. Figure 6 illustrates what happens when a range is collapsed.
JavaScript DOM Ranges : Figure 6
Figure 6You can collapse a range by using the collapse() method, which accepts a single argument: a Boolean value indicating which end of the range to collapse to. If the argument is true, then the range is collapsed to its starting point; if false, the range is collapsed to its ending point. To determine if a range is collapsed, you can use the collapsed property:
oRange.collapse(true);      //collapse to the starting point
alert(oRange.collapsed);    //outputs "true"
How to do range highlighting too:

Wednesday, December 15, 2010

The best du replacement...

sudo apt-get install ncdu

ncdu <dir>

It provides a high-level summary of all the dirs, and allows you to drill-in/drill-out to see which subdirs consume the most space.

Friday, December 10, 2010

What the r' in re.match() means.."\b(two)", "one two three).groups()
instead of:"\b(two)", "one two three).groups()

Regular expressions use the backslash character ('\') to indicate special forms or to allow special characters to be used without invoking their special meaning. This collides with Python’s usage of the same character for the same purpose in string literals; for example, to match a literal backslash, one might have to write '\\\\' as the pattern string, because the regular expression must be \\, and each backslash must be expressed as \\ inside a regular Python string literal.

The solution is to use Python’s raw string notation for regular expression patterns; backslashes are not handled in any special way in a string literal prefixed with 'r'. So r"\n" is a two-character string containing '\' and 'n', while "\n" is a one-character string containing a newline. Usually patterns will be expressed in Python code using this raw string notation.