slideout menu

Welcome!

Julian's photo Hi there! I'm Julian M Bucknall, a programmer by trade, an actor by ambition, and an algorithms guy by osmosis. I chat here about pretty much everything but those occupations. Unless you're really lucky...

Most recently this is what I've come up with:

Issues using MathJax 2.5 with Chrome

So yesterday I wrote an article about the conditional support of MathJax in my posts here on the blog. The post required MathJax since I deliberately put an equation in it. Today I noticed that viewing that post in Chrome led to the equation being rendered three times across the page:

Chrome error with MathJax 2.5

Chrome displays three equations. Whut?

Even refreshing the page didn’t solve the issue. A mild bit of panic later – Does it work in FireFox? Yes. In Internet Explorer? Yes. In Safari on the Mac? Yes. On an iPad? Yes. – it was time for a bit more research.

It turns out that MathJax was updated to v2.5 on January 30, 2015 and I’d coded the <script> element to download the latest version:

<script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>

And there in the PR report about it was the hint:

If you are using the mathjax/latest address you might get a mixture of files in your browser cache, and so may need to clear your browser cache and for some browsers (e.g., Chrome) restart your browser in order to get a consistent version of all files.

I opened Chrome’s History page, clicked the Clear browsing data… button, made sure the Cached images and files option was checked, and cleared the browsing data. I restarted Chrome and everything worked as it should have.

Phew! Saved, at least until the next time…

Now playing:
Aphrodelics - Rollin' on Chrome [Wild Motherf***er Dub]
(from The K&D Sessions)


Conditionally loading MathJax with GraffitiCMS

A couple of years ago I did a series of posts about TVM, the Time Value of Money (1, 2, 3). Because they were mathematical in nature, I had to write a few math expressions and equations. Way back when I’d have written them out in the Equation Editor in Word, and taken screenshots, but this time I decided to go for a browser-based solution: MathJax. In essence, I’d write the expressions in LaTeX format, such as x = \frac {-b \pm \sqrt{b^2 - 4ac}} {2a}, and have it rendered as:

\[ x = \frac {-b \pm \sqrt{b^2 - 4ac}} {2a} \]

Writing maths on chalkboard

Eek, maths on a chalkboard!

This was a great solution, except for one thing: I didn’t really write that many mathematical expressions in my blog posts and MathJax was being loaded and executed for every single page no matter whether there were expressions to be rendered or not. In other words, the specialized infrequent need was dominating the more general use of my blog. The majority of pages were slower to load than they should be. What I wanted was a way for the page renderer to load MathJax only when it was necessary.

The first step was to be able to mark those posts that used MathJax in some way. Enter GraffitiCMS’ Custom Fields. I set up a custom checkbox field called UsesMathJax and then went back over my posts to find those that needed MathJax processing of LaTeX expressions. (It wasn’t as bad as all that: in essence I regex-searched for \[, some characters, followed by \] or the equivalent with ordinary parentheses in a loop for each post.) This post has been so marked.

Now that was done, the fun begins. I had to alter the views I use for the site so that the rendering engine (it’s NVelocity) knows to output the <script> element that references the MathJax library. I started off with a simple variable, #NeedsMathJax, that I set false at the beginning of layout.view and then was checked to be true at the end of the <body> element.

<body class="Graffiti-$where">

  <div id="wrapper">

    #set($NeedsMathJax = false)

    $childContent

    <!-- Other HTML -->

  </div><!--end of wrapper -->

  <script type="text/javascript" src="$macros.ThemeFile('minifiedBoyet.js')"></script>

  #if($NeedsMathJax == true)
  <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
  #end

  <!-- Other scripts -->

</body>

And then, for post.view, which is loaded by $childContent, I had this at the end of the HTML:

#if($post.Custom("UsesMathJax") == "on")
  #set($NeedsMathJax = true)
#end

(Note the string value that the custom checkbox field uses: “on” . Similarly if it’s unset it defaults to “off”.)

Except … it didn’t work. After a bit of investigation, it turns out that GraffitiCMS/NVelocity first evaluates $childContent before rendering layout.view. The value of $NeedsMathJax was being reset in layout.view after it had been properly set in post.view. The solution? Easy: just don’t have that initial setting of $NeedsMathJax to false. I was a little uncertain about removing it: after all, if the post doesn’t need MathJax then the variable won’t have been declared anywhere at all (let alone set to true) and what would happen then to the if statement? Turns out, not much, NVelocity seems to take the undefined variable in its stride (no exceptions are thrown) and certainly doesn’t evaluate it to be equal to true.

So you’ll be glad – I certainly am – to know that MathJax is now only loaded when it is needed. Like for this post.

Album cover for Sleeping With the PastNow playing:
John, Elton - Stone's Throw From Hurtin'
(from Sleeping With the Past)


Slide menu

You may have noticed. Or quite possibly, not. I won’t hold it against you; it is a bit nerdy. The thing is, I’ve revamped my blog so that the “ancillary” stuff is now hidden behind a “hamburger menu” over there on the left. Click the icon (it’s known in the trade as a “hamburger”) – or, if you are on a tablet or phone, touch it – and the extra stuff about me, the site, and other information slides in, pushing the normal blog content over to the right. This is my first tentative step to being “responsive”, at least in the web sense. The rest of the responsiveness will come later, when I change how posts are rendered in the browser.

Flying debris ahead

No idea what debris was flying

The extra content was always there on the site: at first it was always visible on the right, and after a while I decided to hide it all behind a popup with a label also on the right. Either solution just wasn’t great on a restricted screen, period. I did go through a period of trying to hide the extras (and the ad) depending on the browser width, but it never really worked well. So I decided to go for a slide-out panel instead. After a bit of investigation (there are, needless to say, a gazillion open-source sliding-panel libraries in JavaScript, as there are a gazillion libraries for other JavaScript functionality), I decided on jPanelMenu and I have to say, barring a quirk or two, it works just fine.

Quirks? Well, the first one is that my extras panel is long. It is no small menu as seems to be assumed by the library. Hence it gets displayed with a scrollbar. So, the first requirement was not only to “move” the panel (that is, restyle it) from the right side of the window to the left, but also to futz with the CSS so that there was enough room for a scrollbar on the right.

The next quirk is that the library duplicates the panel. For the longest time (OK, a couple of days, until I noticed), the extras content was being shown at the bottom of the page as well as in the slideout panel. Oops. A small change in CSS later (display:none to be precise) and that problem went away.

The next quirk was the way I’d originally written the extras panel: I’d used id instead of class for my element names. Since the library duplicated the HTML, that meant I suddenly had two copies of named elements that should have been unique in the DOM. The first time I noticed this was when I saw that the JavaScript that was supposed to be setting the event handlers on the Search box wasn’t actually working. Or rather it was only affecting the extras panel you couldn’t see. More changes later to remove the uniqueness requirements and everything worked fine.

So, apart from these minor quirks – and it only really took an evening’s worth of work to get it all working properly, albeit spread over a few days – I’m happy with the way the slideout panel works on this site. Even more so, the way it works nicely on a smaller, touch screen. As I said earlier: now I can think about how to display the posts more optimally on a small screen; that is, make the rest of the site more responsive.

Album cover for No AngelNow playing:
Dido - Slide
(from No Angel)


Using server-side MarkDown for comments

Nearly four years ago now, I “implemented” MarkDown for the comments here on my blog. At the time, Graffiti CMS (the blog engine I use) was being fairly regularly updated and I didn’t want to change my server-side code unnecessarily. I’d already run into merge issues in the past with new fixes from the CodePlex repository.

Wrong Way Not An Exit sign

Wrong Way - Not An Exit

Why the air-quotes for “implemented”? Because I had decided to do this via JavaScript in the browser. Essentially if you opened a blog post, the code would find the comments already made and then convert them using the AttackLabs JavaScript library. Because of the process comments go through on the server-side, this wasn’t exactly the best idea, let alone the fact that displaying a post meant all this extra time-consuming work in the browser. As it happened, those comments that had code blocks in them tended to produce some badly laid-out results.

Over the weekend, I’d finally had enough of the whole thing. Given that Graffiti CMS is pretty much no longer being updated – the scourge of many underfunded open-source projects you might argue (the last update was May 2013) – I decided to finally fork my source code. Time for some changes!

The original code in Graffiti.Core for saving a new comment did this:

        protected override void BeforeValidate()
        {
            base.BeforeValidate();

            //By default we allow no markup
            if(IsNew)
            {
                UniqueId = Guid.NewGuid();

                Body = Util.ConvertTextToHTML(Body);
               
                IGraffitiUser gu = GraffitiUsers.Current;

That call to Util.ConvertTextToHtml did three things: it encoded the raw text from the text input field (the comment body) to HTML entity characters where necessary (so, things like &lt; for <, &amp; for &, and so on), converted any url links it found into <a> elements, and then wrapped paragraphs into <p> elements. Unfortunately all that made code blocks in comments look pretty bloody awful. In essence, I’d have to go in and modify them by hand.

The code now looks like this:

        protected override void BeforeValidate()
        {
            base.BeforeValidate();

            //By default we allow no markup
            if(IsNew)
            {
                UniqueId = Guid.NewGuid();

                //Comments are now written in Markdown and converted
                //Body = Util.ConvertTextToHTML(Body);
                var markdownProcessor = new Markdown();
                Body = markdownProcessor.Transform(Body);
               
                IGraffitiUser gu = GraffitiUsers.Current;

Woah! What’s this Markdown class? I‘m using Jeff Attwood’s MarkdownSharp library (it’s available on NuGet from within Visual Studio, or you can download it here). So, what happens now is that you or I would write MarkDown text in the comment input field, it gets sent via a callback to the server-side code, the text gets transformed to HTML via this MarkDown converter on the server, and stored like that in the Comments table in the database. When it’s shown together with the post it’s associated with, no further processing is done: it’s already in the correct HTML.

(Aside: OK, let me ’fess up here. In reality this happened in two stages as I worked my way to this better solution. My first attempt was to convert all of the comments on this site to what might be called MarkDown text. Then all that happened was the MarkDown text would be sent along with the post HTML and the JavaScript code for the page would convert it on the fly to HTML using the AttackLabs library. In essence, I wrote some batch code that reversed what Graffiti CMS had already done to the comments when saving them (the first code above). Oh boy. Remember what they say about regular expressions? You have an issue, you solve it with regex, and now you have two issues? Yep, that was me in spades – I was drowning in not-quite-right regexes. Happily, in the end, I ended up with this way cleaner and clearer version.)

(Aside, 2ième partie: Hoo, boy has it been a while since I’ve written batch update code in C#. Quite a while…)

Stay tuned as I “fix” other parts of Graffiti CMS…

Album cover for G-Stone BookNow playing:
Kruder & Dorfmeister - Deep Shit pt1 & 2
(from G-Stone Book)


Declare that function! But, how?

So, I read a blog post about declaring functions in JavaScript recently. It was just about technically correct as far as it went, but, ow, the way it was written hurt (missing semicolons, invalid code samples, etc). I’ll decline to link to it, thanks very much, but instead I’ll bring out its main points together with a recommendation or two (that, in fact, the original blog post did not). There are two ways to declare a function in JavaScript, although we can spin ’em out a bit...

Read more »

Globals, IIFEs, this, and strict mode

It started like this: I was reading some JavaScript code, written – he says charitably – some years ago. Much simplified, it looked something like this, with all identifiers renamed to protect the guilty: timer = {}; timer.timerID = null ; timer.cancel = function () { if (timer.timerID !== null ) { clearTimeout(timer.timerID); timer.timerID = null ; } }; timer.start = function (delay, onDone) { timer.cancel(); timer.timerID = setTimeout(onDone, delay); }; Colored light Let’s just...

Read more »

Best supporting actor in a comedy?

Holy crap. Every now and then (and it’s very rare these days because of the business travel I have to do), I manage to get a role in a local theatre production. Yes, indeed, I’ve been known to act a little. In December, after some four years away from the stage apart from a very small role in The Wild Duck for Theatreworks in March 2013, I landed the role of Reverend Shandy in The Lying Kind , also for Theatreworks. The part was a hoot, as was the play, a strong British farce. We had...

Read more »

Back in the day: a PC Card adapter for USB 2.0

Time for a quick giggle as I look at some old hardware I used to use, some 14 years ago, before I take it off to recycling. This past weekend, in a box at the back of the cupboard, I found this: PC Card adapter for 2 USB 2.0 ports - top It’s an adapter for a laptop that didn’t have USB 2.0 ports but that did have a PC Card slot. PC Card adapter for 2 USB 2.0 ports - end Way back when, that’s exactly what I had: a big chunky laptop with USB 1.1 ports but no USB 2.0 ports. The laptop...

Read more »

Another chapter from the “Don’t be clever” coding style

A short and quick example of some baffling coding today. It so happens this past weekend I was updating some HTML and CSS and JavaScript on this site. One of the JavaScript source files (luckily not written by me) had this: function $$(id) { if (id.substring(1, 0) != "#" ) id = "#" + id; return $(id)[0]; } Start Well Your Day - Whut? So, in other words, it takes an element id, makes sure it starts with a ‘#’, calls jQuery to return the elements with that id (of which there should...

Read more »

Installing Yosemite like a pro

Way back when, I bought a black MacBook and an iPod Touch. I was – har, har – going to learn how to write Objective-C and earn millions selling apps. You know the kind of thing: Learn Objective-C … PROFIT!!!! Except Objective-C is a right royal pain in the neck – and this is coming from someone who loves JavaScript. Anyway, after a year or so, I had a better plan: use a Mac as my main laptop and get used to the Mac way. I bought a unibody 13-inch MacBook Pro, mid-2010 version...

Read more »

Extras

Search

About Me

I'm Julian M Bucknall, an ex-pat Brit living in Colorado, an atheist, a microbrew enthusiast, a Volvo 1800S owner, a Pet Shop Boys fanboy, a slide rule and HP calculator collector, an amateur photographer, a Altoids muncher.

DevExpress

I'm Chief Technology Officer at Developer Express, a software company that writes some great controls and tools for .NET and Delphi. I'm responsible for the technology oversight and vision of the company.

Validation

Validate markup as HTML5 (beta)     Validate CSS

Bottom swirl