Morse code translator

C# (213 characters)

I'm sure this wont stand long, but at least I got the technique here first!

class P{static void Main(string[] a){foreach(var t in a[0]){var c="";for(int i=" ETIANMSURWDKGOHVF L PJBXCYZQ  54 3   2       16       7   8 90".IndexOf(t);i>0;i/=2)c="-."[i--%2]+c;System.Console.Write(c+"  ");}}}

And in readable format:

class P
{
    static void Main(string[] a)
    {   
        foreach(var t in a[0])
        {
            var c="";
            for(int i=" ETIANMSURWDKGOHVF L PJBXCYZQ  54 3   2       16       7   8 90".IndexOf(t);i>0;i/=2)c="-."[i--%2]+c;
            System.Console.Write(c+" ");
        }
    }
}

For a brief explanation, the string of characters is a heap in which the left child is a dot and the right child is a dash. To build the letter, you traverse back up and reverse the order.


Golfscript - 74 chars

This answer supports only uppercase and digits. The letters are separated by newlines and words are separated by 2 newlines

{." ETIANMSURWDKGOHVF L PJBXCYZQ"?)"?/'#! 08<>"@))10%=or 2base(;{!45+}%n}%

Analysis

    { }%          as usual works like a map over the array
    .             push a copy of the char onto the stack
    " ETIAN..."   this is a lookup table for the uppercase characters
    ?             like a string.find returns the index of the char in the string
                  or -1 if it is not found (ie it's a digit)
    )             increment that index so E=>2 T=>3 I=>4 etc. notice that if the
                  char is not an uppercase letter or space this is now 0 (False)
    "?/'#!..."    this is a lookup table for the digits. it will be used in the
                  reverse way to the other lookup table.
    @             pull that copy we made of the char to the top of the stack
    ))%10         convert ascii digit to a number by adding 2 and taking mod 10.
                  It's important to do it this way because all the uppercase
                  letters hit this code too, and we need to make sure they fall
                  in the range 0..9 or the next step will fail.
    =             pull the nth char from the string eg "Hello"1= gives "e"
    or            remember if the uppercase lookup fails we have a 0 result, so
                  the digit lookup will be used
    2base         convert to base 2 so E=>[1 0], T=>[1 1], I=>[1 0 0] etc.
    (;            pop the front of the list and throw it away so E=>[0], T=>[1]
    {!45+}%       negate each bit and add 45, this gives ascii value of . and -
    n             newline separates each word. this could be 32 if you wanted to
                  separate the words with spaces for a cost of 1 stroke

Golfscript - 85 chars

This is shorter than my SO answer due to the relaxed requirements here The input must be uppercase/digits and the punctuation characters ".,?"

{." ETIANMSURWDKGOHVF!L!PJBXCYZQ"?)"UsL?/'#! 08<>"@".,?"58,48>+?=or
2base(;{!45+}%n}%

Since the punctuation is not even required here, I may shorten the answer even more

My answer from SO
Golfscript - 107 chars

newline at the end of the input is not supported, so use something like this

echo -n Hello, Codegolfers| ../golfscript.rb morse.gs

Letters are a special case and converted to lowercase and ordered in their binary positions. Everything else is done by a translation table

' '/{{.32|"!etianmsurwdkgohvf!l!pjbxcyzq"?)"UsL?/'#! 08<>"@".,?0123456789"?=or
2base(;>{'.-'\=}%' '}%}%'/'*

tr + sed (347)

tr a-z A-Z | sed 's/0/--O/g;s/1/.-O/g;s/2/.J/g;s/3/..W/g;s/4/.V/g;s/5/.H/g;
 s/6/-.H/g;s/7/-B/g;s/8/-Z/g;s/9/--G/g;s/X/-U/g;s/V/.U/g;s/U/.A/g;
 s/Q/-K/g;s/K/-A/g;s/A/.T/g;s/J/.O/g;s/O/-M/g;s/Y/-W/g;s/W/.M/g;
 s/M/-T/g;s/T/- /g;s/H/.S/g;s/B/-S/g;s/S/.I/g;s/L/.D/g;s/Z/-D/g;
 s/D/-I/g;s/I/.E/g;s/C/-R/g;s/F/.R/g;s/R/.N/g;s/P/.G/g;s/G/-N/g;
 s/N/-E/g;s/E/. /g'