Archive for May, 2010

Updated WordPress Code Highlighter to GeSHi 1.0.8.6

Wednesday, May 12th, 2010

Today I've been tracking down a little rendering bug with MarsEdit and WordPress. It's in the pre tags that run through the Code Highlighter plugin that I've been using for quite a while. It's the "less-than-sign". If I use the HTML escape code then I get that as the literal text in the MarsEdit preview pane as well as the WordPress page. But if I place the single character, MarsEdit thinks it's the start of a tag, and gets confused on the syntax highlighting.

So the two questions are: why can't the Code Highlighter handle the HTML escape for the less-than-sign, and why is MarsEdit not rendering it properly? I'm going to attack the first, and let Daniel handle the second.

First thing I noticed was that the Code Highlighter is based on the GeSHi engine and the version it's working on was 1.0.7.x whereas the current version is 1.0.8.6. So let's see if we can update the GeSHi engine in the plugin without breaking anything.

Turns out, it's a pretty simple encapsulation of the GeSHi engine. I was able to drop in the new version without too much trouble. In the doing, I've upgraded the languages that this guy can work with considerably. That's a very nice little perk.

Unfortunately, this didn't solve the problem with the less-than-sign. I did a cursory look in the GeSHi code and didn't see where it'd be doing any conversions. I'll probably spend a little more time on it - just to see if it's possible. But even if that doesn't come to anything, we have a far better selection of supported languages:

4cs            div            lscript       python
abap           dos            lsl2          qbasic
actionscript   dot            lua           rails
actionscript3  eiffel         m68k          rebol
ada            email          make          reg
apache         erlang         mapbasic      robots
applescript    fo             matlab        rsplus
apt_sources    fortran        mirc          ruby
asm            freebasic      mmix          sas
asp            fsharp         modula3       scala
autohotkey     gambas         mpasm         scheme
autoit         gdb            mxml          scilab
avisynth       genero         mysql         sdlbasic
awk            gettext        newlisp       smalltalk
bash           glsl           nsis          smarty
basic4gl       gml            oberon2       sql
bf             gnuplot        objc          systemverilog
bibtex         groovy         ocaml-brief   tcl
blitzbasic     haskell        ocaml         teraterm
bnf            hq9plus        oobas         text
boo            html4strict    oracle11      thinbasic
c              idl            oracle8       tsql
c_mac          ini            pascal        typoscript
caddcl         inno           per           vb
cadlisp        intercal       perl          vbnet
cfdg           io             perl6         verilog
cfm            java           php-brief     vhdl
cil            java5          php           vim
clojure        javascript     pic16         visualfoxpro
cmake          jquery         pike          visualprolog
cobol          kixtart        pixelbender   whitespace
cpp-qt         klonec         plsql         whois
cpp            klonecpp       povray        winbatch
csharp         latex          powerbuilder  xml
css            lisp           powershell    xorg_conf
cuesheet       locobasic      progress      xpp
d              logtalk        prolog        z80
dcs            lolcode        properties
delphi         lotusformulas  providex
diff           lotusscript    purebasic

[5/13] UPDATE: I was doing some more digging into the GeSHi engine - actually the Code Highlighter plugin, and I found what I thought was going to be a good place to fix this problem. In the codehighlighter.php file, we see:

  1. if ($lang != null) {
  2. $tabstop = 2;
  3.  
  4. $code = trim($matches[5], '\r\n');
  5. $code = str_replace('< /pre>', '</pre>', $code);
  6.  
  7. $geshi =& new GeSHi($code, $lang);
  8. $geshi->set_tab_width($tabstop);

where it's clear in the comments that he's allowing for the special case use of the pre tag, and I decided to try a simple modification of that for these less-than and greater-than signs I'm having trouble with:

  1. if ($lang != null) {
  2. $tabstop = 2;
  3.  
  4. $code = trim($matches[5], '\r\n');
  5. $code = str_replace('< /pre>', '</pre>', $code);
  6. $code = str_replace('\&\l\t\;', '<', $code);
  7. $code = str_replace('\&\g\t\;', '>', $code);
  8.  
  9. $geshi =& new GeSHi($code, $lang);
  10. $geshi->set_tab_width($tabstop);

This is a little odd in the way I have to show it, but it's pretty simple to understand - you replace the HTML escape sequence with the single character in the code. From there, you let the GeSHi engine do it's thing.

What I found was that it worked wonderfully! What a treat. Now I can use either method, and hopefully Daniel will have a fix for MarsEdit sooner rather than later.

The next thing I wanted to tackle with the Code Highlighter was the line numbers. There was far too much space between the lines in a code sample with line numbers. Turns out, there's a style for that in GeSHi. Simply edit the geshi.php file:

  1. /**
  2.   * Line number styles
  3.   * @var string
  4.   */
  5. var $line_style1 = 'font-weight: normal; vertical-align:top;';
  6.  
  7. /**
  8.   * Line number styles for fancy lines
  9.   * @var string
  10.   */
  11. var $line_style2 = 'font-weight: bold; vertical-align:top;';

to be:

  1. /**
  2.   * Line number styles
  3.   * @var string
  4.   */
  5. var $line_style1 = 'margin: 0; font-weight: normal; vertical-align:top;';
  6.  
  7. /**
  8.   * Line number styles for fancy lines
  9.   * @var string
  10.   */
  11. var $line_style2 = 'margin: 0; font-weight: bold; vertical-align:top;';

and the extra border space that the default WordPress theme puts into the li tag will be removed and it'll look much better.

The last little annoyance is the blank lines that start, and end, the code section when you use line numbers. It's just plain annoying. It makes it hard to get the numbers right, and it's whitespace that's not needed. It's a little more involved, but not too bad. In the geshi.php file, you need to change:

  1. // Get code into lines
  2. /** NOTE: memorypeak #2 */
  3. $code = explode("\n", $parsed_code);
  4. $parsed_code = $this->header();

to:

  1. // Get code into lines
  2. /** NOTE: memorypeak #2 */
  3. $code = explode("\n", $parsed_code);
  4. // remove a blank first and last line
  5. if ('' == trim($code[count($code) - 1])) {
  6. unset($code[count($code) - 1]);
  7. $code = array_values($code);
  8. }
  9. if ('' == trim($code[0])) {
  10. unset($code[0]);
  11. $code = array_values($code);
  12. }
  13. $parsed_code = $this->header();

Now I can imagine a way that might be a little more efficient, but I'm not worried at this point. It's not all that bad, and it's very solid. If the first or last lines are empty of code, they get removed and the array is re-indexed. Simple.

With this, I have a really nicely workable solution for my code. Nice.

A Little Wrinkle in AJAX – Failed Requests

Wednesday, May 12th, 2010

AJAX.jpg

I was working on a few problems this morning and ran into one that I thought I'd solved with a simple binary flag. Well... let's do the set-up.

We have a web page with a JavaScript timer on it, and every so often, it fires off a request to the server to get new data. It's a poor man's push notification system, but it works - expect when it doesn't. Case in point: what happens when the requests are taking longer to service at the server than the timer's interval? Well, they still get sent, and they stack up at the server, and slow things down even more.

It's a mess. We need to have some idea that the request is in process, and if so, we don't want to send anther to the server. It'd just make things worse. So my first cut looked a lot like this:

  var requesting = false;
 
  function refreshData() {
    if (!requesting) {
      requesting = true;
      ...
    }
  }
 
  function handleResponse() {
    ...
    requesting = false;
  }

And while it's not a good design, the idea is simple - have a global variable that indicates if there's a pending request, and if so, then just skip the current request as the timer will issue another in just a little bit. Should work great... and it does - except when it doesn't.

Where it fails is in the failure on the server. If the request fails, then the handleResponse() code might not be called. Some cases it will and some it won't - it depends on the library doing the call. In my case, that's the Google Visualization Query, and that seems to be about 50-50, depending on the server's condition.

When it fails, the flag will never get reset and from that point on, no requests will get sent to the server. That's not good. What I needed was a much more secure method of knowing when it's busy, with the ability to detect when it had failed.

What I came up with was the idea of a simple timeout. That, coupled with a global timeout limit should be able to do the trick:

  var requestTimeout = null;
 
  function refreshData() {
    var now = new Date();
    if ((requestTimeout == null) || (now > requestTimeout)) {
      requestTimeout = now;
      requestTimeout.setSeconds(requestTimeout.getSeconds() + ServletTimeout);
      ...
    }
  }
 
  function handleResponse() {
    ...
    requestTimeout = null;
  }

In this code sample, we're going to get the current date/time and compare the timeout to that value. If we've passed the timeout, or there is none, then we can hit it again - setting the new timeout to the appropriate distance in the future.

In my tests, this works great with servers that die on the page, and it also doesn't allow too many requests to buffer up on the server. Hopefully, there aren't any other gotchas that I missed with this guy.

MarsEdit 3.0.1 is Out

Wednesday, May 12th, 2010

MarsEdit 3

This morning I noticed that MarsEdit 3.0.1 was out and included in the fixes is the bug I reported about using the file:// URL in the template preview! This is really nice because now I don't have to go through apache to get to a file on my box. Very nice, indeed.

Still a great way to post to WordPress... love it to pieces.

UPDATE: I found a little bug in the HTML highlighting in 3.0.1 and sent it to Daniel. The point was that in a pre block, the "less-than-sign" should not be the start of a tag - necessarily, and in one of my code samples, it was in an expression and the rest of the editor window was messed up because of that. I'm not sure how he'll solve it, but I'm sure he'll give it a go.

Unfortunate Quick Trip to the Dentist

Tuesday, May 11th, 2010

This morning at breakfast I felt a nasty CRUNCH! when biting down on my cereal, and didn't think a lot of it at the time. It's Smart Start, and it's got nuts and crunchy bits, so I thought Wow, that's one crunchy bit and finished by breakfast. When I was done, I noticed something a little different on my last upper molar. It was missing a piece!

Yeah, I'm a serious dental-phobic, and so the thought if having a chipped molar was pretty upsetting. I was at work, so I had to stay calm, but inside, I was freaking out. It was not a great time. So I did what any chicken in my position would do - I texted my wife and asked her what I should do.

OK, I'm not proud that I'm a chicken, but at least I have the good sense to surround myself with people that love me enough to pick up the slack when I need it.

She asked if I wanted to get into the dentist's office. Yeah... I did.

She was kind enough to call and get me in today at 1:30.

So I'm taking off to catch the only train that will get me home in time to see the dentist. Too bad it's a local, and will take me about two hours door to door.

Not looking forward to this.

UPDATE: they 'reconstructed' the tooth by taking out the remainder of the old filling on that one tooth, and building up the tooth with a new filling. While I'm not going to say it was "fun" or "easy", it was done with a minimum of pain, and I was out and home to recover by 3:00.

Google Chrome (dev) 5.0.396.0 is Out

Tuesday, May 11th, 2010

This morning I noticed that Google Chrome 5.0.396.0 (dev) was out and since I've been using Chrome for a week or so now, it's nice to stay up to date as this guy is evolving pretty darn fast. I can't say as I noticed anything bad, but I didn't notice anything, and that's good too.

The Coolest Language Ever Created

Monday, May 10th, 2010

I've been coding on and off in Objective-C for several years, and recently I've decided to get back into it to work on a little project that I've done several times over, but this time I just wanted to do it in Objective-C and on the Mac. It's been a while, and I wanted to make sure I still remembered all the neat things the platform had to offer.

Holy Cow! I had forgotten how elegant and beautiful Objective-C is and the Cocoa frameworks in particular are. The code is just so incredibly expressive and wonderful, it's hard to imagine why someone would purposefully choose to not code in this language.

Amazing.

Writing the C++ equivalent of the copy constructor is so wonderful:

- (id) copyWithZone:(NSZone*)zone
/*"
**   This is the standard copy method for the Legend so that we can make
**   clean copies without having to worry about all the details. It's a nice
**   deep copy, where the contents of the returned Legend are the same as
**   this instance's.
"*/
{
    // simply use the allocWithZone and populate it properly - easy
    return [[[Legend allocWithZone:zone] initWithMap:[self getMap]] autorelease];
}

where I had already created the setMap and getMap methods because they are the setters and getters for the class. It's so easy.

Yup, the more I code in ObjC, the more I realize I shouldn't be coding in anything else. It's just too much fun.

UPDATE: I read about headerDoc in the Xcode docs, and it seems to be the new AutoDoc documentation generator. So I changed the comments on my code to be more in-line with that, and as a benefit, they look more like my C++ comments, and that's a big win in my book:

/*!
 This is the standard copy method for the Legend so that we can make
 clean copies without having to worry about all the details. It's a nice
 deep copy, where the contents of the returned Legend are the same as
 this instance's.
 */
- (id) copyWithZone:(NSZone*)zone
{
    // simply use the allocWithZone and populate it properly - easy
    return [[[Legend allocWithZone:zone] initWithMap:[self getMap]] autorelease];
}

Magical Market Ride

Monday, May 10th, 2010

I'm in the financial business, and as such, many people think I know something "special" about the markets or trading. I don't. What I know is how to build systems, and the little domain knowledge I need to do it well in this industry. However, the bounce that happened the other day was something totally unrelated to how the markets really work.

Something silly happened and programmed trades weren't smart enough to see that it was an isolated, very short term spike. Bad coders made the Big Bounce, nothing else. Maybe a little panic, but for the most part, bad coders.

Look at today:

Monday Rebound

All the losses are gone... things are back up, everything is working it's way back. It was a very obvious problem that didn't effect the fundamentals of any of the companies.

Bit of a Shocker – Tons of Broken Web Pages

Monday, May 10th, 2010

Crazy Lemon the Coder

Well, this morning I got a nice shocker - several of my web tools were broken in London, but working fine in Chicago. Since the server is in Chicago, I started looking at the network as the issue. Everything here worked fine, but nothing there was working. Well... the basic page was loading, but nothing else.

What a pain. I was able to see the server was up and returning data. I was able to make it work for me. But they were dead. So I asked them to have a look at the JavaScript console log in Chrome and let me know what it said.

The answer was simply astounding: it couldn't find the Java applet on the page.

Now a bit of background for this one. My web app needs to have some sense of authorization. It's got P/L data for the entire organization for a long time. There's a desire to have this somewhat controlled. OK, fine by me, corporations can choose to filter their data as they see fit. I just needed to put something into the JavaScript to make it possible to read the logged in user running the web browser (Chrome or Firefox).

I solved this a while ago, but recently my teammate Steve decided that I didn't need to have the applet tag visible, and so he changed all the applet tags from:

  <applet archive="firecache.jar" code="Bridge"
   height=10 width=10>

to:

  <applet archive="firecache.jar" code="Bridge"
   height=1 width=1 style="display: none;">

He said I had made a mistake in leaving it visible, and too big. I remember doing tests on it, and thought I had tested this, but hey... maybe it's an update to Chrome, and it's working better now.

Yeah... I should have trusted myself.

It's important to realize that I have a multi-level process of getting the authenticated username: first, we check for a cookie, if that's not there, then we hit the applet, and if that's not available, then we throw up a login panel. The problem was, with the applet not accessible, the JavaScript stopped at that step and we never say the login panel.

So I changed the code to ignore the cookie, and quickly reproduced the problem. Now I knew what it was. Then I changed the HTML on the page to:

  <applet archive="firecache.jar" code="Bridge"
   height=1 width=1>

leaving it "small" is OK with me, but I have to have it "visible" so that it's accessible to the JavaScript engine.

When I did that, I had the page working again. Whew! All I had to do now was to fix up the thirty-some other pages and check it all in and put it in UAT.

It didn't take too long, but it was a pain to look stupid to the London users, but I took the bullet for Steve. It is my web app, not his, and while he didn't test his changes, I didn't either, and that's my fault. I'll be a lot more careful about Steve's work in the future.

I do not like looking stupid to the London users.

Adobe Flash Player 10.1.53.38 (Release Candidate) is Out

Friday, May 7th, 2010

This morning I saw that the latest release candidate of Flash Player for Mac OS X was out, and with the recent announcements of the hardware-accelerated library from Apple, it's been a stated promise from Adobe that they will use this in the final release of the 10.1 Flash PLayer. If so, this may be the cut that includes it. The timing is right, which is just great.

So I'm hoping that soon we'll have a decent Flash Player that uses hardware acceleration on my laptop.

Mr. Market’s Wild Ride

Thursday, May 6th, 2010

I tell you it's been an interesting afternoon in the markets - Dow loosing 700 points in 15 min and then making back 600 in the next 20 min... what a wild ride! I'm sure there are a lot more interesting ways to spend the day, but I've never been in a place where an hour was as hectic as that hour.

Wild Afternoon

People were far too hectic for the systems they built - prices were delayed, and in this market that's a major issue. But hey, when you've been trying to tell them what they need, and they keep putting it off, well... now they see the value.

I'm sure it'll bounce back up the rest of the way in the coming days, but it was pretty interesting to see it happen.

UPDATE: It seems that the prevailing theory is that this spike in PG (Procter & Ganble) was the trigger that started the massive drop:

PG: 60.75 -1.41 (-2.27%) - The Procter & Gamble Company

from there, it was panic. Nothing fundamental changed, just automated trading systems with traders monitoring them not really thinking about what they were seeing. Pretty amazing story of humans and group panic.