When the wrong way is the right way: my standards box

TwitterGoogle+RedditLinkedInFacebookbuffer

I'm a meticulous person. I will correct a typo in a 2-year old post. I refactor like I vote: early and often. However, I was recently confronted with a very simple problem that stumped me completely. No, it wasn't FizzBuzz. The solution eluded me because it entirely broke what I thought of as good practice, especially given my experience in accessible web development. Having often been the go-to guy for thinking 'outside the box', I found myself inside one of my own creation. The ugly kludge of a solution was, in retrospect, a perfectly acceptable one given the circumstances. So why didn't I think of it?

My friend, who is not a developer, asked me to give him a hand off the cuff, at the end of the day and over IM. I had a few minutes to offer advice on solving his problem. He complained of "doubled bullets" on an HTML page (which was presumably rendered from an OCR or document export) similar to the following HTML fragment:

<ul>
  <li>
    <span class="bullet">• </span>
    <span>First item</span>
  </li>
  <li>
    <span class="bullet">• </span>
    <span>Second item</span>
  </li>
</ul>

Obviously, the doubled bullet was the result of a hard-coded bullet entity, which has a simple fix: find and replace the whole span string. Done.

What I didn't realize is that there were other, similar problems in the export parsing that had caused output like this:

<ul>
  <li>
    <span class="bullet">a) </span>
    <span>First item.</span>
  </li>
  <li>
    <span class="bullet">b) </span>
    <span>Second item.</span>
  </li>
</ul>

This is only a slightly bigger problem:

  1. Pattern match
    ^<span class="bullet">.*?</span>$
    to find relevant entities (there were a variable number of spaces after the letters throughout the document, or the <span> could be empty).
  2. Ascend to the parent `<ul>` and transform it into an `<ol type="a">`.
  3. Using the pattern from (1), delete all instances of the superfluous `<span>`.

The problem with this solution comes with the fact that there were 250 <ul>s in the document and changing the relevant parent <ul> to <ol> had to be done manually (not every `<ul>` was destined to become an `<ol>`, nor all of `type="a"`).

Sorry, dude, you're on your own!

Yes, I could have written a script to actually parse the DOM, ascend to targeted parent <ul>s by pattern matching ^<span class="bullet">[a-z].*?</span>$ (for `type="a"`) and ^<span class="bullet">[0-9]{1,2}.*?</span>$ (for `type="1"`) and perform the transformations that way.

I didn't realistically have the time or the desire to write such a script, and it was well past dinner time.

Returning from dinner, I see a new message: "OVERTHINKING 101"

The solution someone else proposed was:

ul, ol {
  list-style: none;
}

li {
  position: relative;
}

.bullet {
  position: absolute; left: -1em; top: 0px;
}

Are you serious?!

This, to me, was the ugliest kludge: it breaks semantic convention and doesn't address the fact that `<ul>` and `<ol>` mean something to machines. In my mind, it's akin to using `<p style="font-size: large; font-weight: bold">` for a header, rather than using an `<h1>`. In a vaguely similar vein, the proposed solution takes a semantically unordered list and coerces it into becoming a de facto ordered list with plain text.

But is that even a problem?

In this case, not really! That's the key to this issue. The document was destined for a very specific purpose and a very restricted audience. Visual presentation was the only thing that mattered to both the author and the readers.

I would never deploy this code in a production environment for general consumption because I feel that standards are a good thing and ought to be adhered to. However, I think wilfully disregarding them can be done effectively in certain circumstances and isn't a problem 100% of the time. I would never have devised this perfectly acceptable solution because I had built a cognitive box around my way of thinking, following standards so automatically that a good, quick solution never came to mind.

And that's precisely what my friend needed: a decent, quick solution that responded to his specific criteria (solely visual presentation).