a blog by Marius Gedminas

Footnotes on the Web

Every now and the I see a web page that tries to use footnotes and fails. Usually it is a longish article, and all the footnotes are unhelpfully placed at the very end. Effectively they are more like endnotes than footnotes1.

1 It can be argued that endnotes on the web are placed on a different web page from the main text, while footnotes are placed on the same web page. This is completely irrelevant to the rest of this post.

The difference between a footnote and an endnote in paper books is that you can easily find the footnote on the same page that you're looking at, while you have to work hard (turn pages, use bookmarks) to find the endnote. Footnotes are convenient, endnotes are not. I have to admit that I haven't the slightest idea why people ever use endnotes. I suppose it's because they're easier to typeset.

Footnotes are called this way because they are placed at the bottom (foot) of the page. When people write articles or books on the web they naturally tend to put the footnotes at the foot of the webpage. But there is one very important difference between paper pages and web pages: you can see the entire page of a book at once, but you can only see one screenful of a long web page without scrolling. Footnotes are convenient because moving your eyes to a different part of the text in front of you is easy.

Scrolling on the web is like turning pages of a book2. If you cannot see both the footnote and the text that the footnote refers to, then you cannot easily jump between the two with just your eyes. You have to use the mouse (or the keyboard), you lose concentration, it becomes harder to find the place where you stopped reading before you started looking for the footnote.

2 Clicking on next/previous links is like putting down the book you're reading now and picking up another book from the table. Not everyone has ultra-low-latency high-bandwidth links.

People generally try to correct this problem by making the footnote marker into a hyperlink that points to the text of the footnote. This solution is inadequate because footnote markers are small and therefore hard to hit (Fitt's Law). It usually takes me more time to move the mouse around and click on the footnote marker that it takes me to hit End, then maybe PageUp or two and find the relevant footnote visually.

A much better solution is to put the footnotes immediately after the paragraph that mentions them. This keeps the footnote and its marker close together (but not too close as to interrupt the reader's flow), and hopefully on the same screenful of text. Indent the footnotes and render them in a smaller font, so that readers may easily skip them.

I did not invent this footnote presentation style - I found it on the web somewhere, a while ago. I wish I remembered where and could give credit where credit is due. Obvious things are sometimes hard to invent.

Using the SchoolTool test runner to run Zope 3 tests

The SchoolTool test runner has a couple of features that the Zope 3 test runner does not have.

  • When an error occurs while rendering a Zope Page Template, the SchoolTool test runner can show you the location in the template as well as the relevant TALES expression in the traceback.
  • You can instruct the SchoolTool test runner to limit recursive directory tree walks to a subdirectory in your source three -- this shaves off whooping 6 seconds when you want to test a single Zope 3 package. (This is very important when running a small subset of unit tests that take e.g. 2 to 6 seconds to run, when you want to have a quick change - run tests - fix cycle.)
  • The SchoolTool test runner can warn you if you have test classes that are not included in the test suite.

Here's how you can use it for a Zope 3 package called "ivija" (which happens to be a Zope 3 based application that I'm currently working on):

  1. Download test.py and save it as st-test.py. Place or symlink it into your Zope 3 root directory (~/Zope3 in my case).
  2. Create a shell script called test and put it wherever you want it (I keep it in ~/Zope3/src/ivija):
    #!/bin/sh
    ZOPE3_HOME=$HOME/Zope3
    TEST=$ZOPE3_HOME/st-test.py
    cd $ZOPE3_HOME
    python2.3 $TEST -wpv --search-in src/ivija "$@"
    
  3. When you want to run the tests, just run them as ./test [options].

Here's how long the Zope 3 test runner takes to walk through all subdirectories and find out which test modules need to be imported:

mg: ~/ivija$ time ./test.py nosuchtest
Configuration file found.
Running UNIT tests from /home/mg/Zope3
not a package src/ivija/reportgen/zLOG/tests
not a package src/ivija/reportgen/StructuredText/tests
No unit tests to be run.
Running FUNCTIONAL tests from /home/mg/Zope3
No functional tests to be run.

real    0m8.438s
user    0m7.050s
sys     0m1.290s

Here's how long the SchoolTool test runner takes to walk through just the ivija package subdirectories:

mg: ~/ivija$ time ./test nosuchtest
/home/mg/Zope3/src/ivija/reportgen/zLOG/tests is not a package
/home/mg/Zope3/src/ivija/reportgen/StructuredText/tests is not a package

----------------------------------------------------------------------
Ran 0 tests in 0.000s

OK

real    0m0.338s
user    0m0.200s
sys     0m0.010s

Not bad, huh?

Update: The SchoolTool test runner is no longer maintained. In the meantime the Zope 3 test runner gained a lot of features not present in the SchoolTool test runner.