Tue, 13 Dec 2005

Typography Testing

Just some experiments with various typography.

I happen to be one of those people that prefers to have more space between sentences than between words. Ideally, this should be about a space and a half; that's what most typography does and I think it looks good. When typing in ASCII, I put two spaces between sentences, because that's the closest approximation that looks good. Unfortunately, HTML collapses whitespace so you get things like:

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Fusce tincidunt orci vitae dolor. Nam tristique velit ac turpis tincidunt tincidunt. Morbi feugiat lacinia ante. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla facilisi. Fusce orci mi, tincidunt ut, aliquam vel, sodales ac, odio. In pellentesque purus. Aliquam enim augue, convallis dictum, condimentum ut, commodo a, augue. Fusce viverra justo ut risus. Curabitur tellus arcu, malesuada sit amet, dictum vel, iaculis nec, nisl.

Now, if we replace the double spaces with en spaces, we get:

Lorem ipsum dolor sit amet, consectetuer adipiscing elit.  Fusce tincidunt orci vitae dolor. Nam tristique velit ac turpis tincidunt tincidunt. Morbi feugiat lacinia ante. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla facilisi. Fusce orci mi, tincidunt ut, aliquam vel, sodales ac, odio. In pellentesque purus. Aliquam enim augue, convallis dictum, condimentum ut, commodo a, augue. Fusce viverra justo ut risus. Curabitur tellus arcu, malesuada sit amet, dictum vel, iaculis nec, nisl.

Not too bad. There's some extra spacing in there. The "elit. Fusce" sequence actually has an en space followed by a normal space, because I have a newline in my source at that point, and HTML doesn't consider the en space to be whitespace. This seems to work best with Firefox 1.0 on Linux. In Firefox 1.5 on Windows, for some reason, the paragraph with the en spaces has extra vertical space between lines. And Internet Explorer 5 for Windows doesn't display the en spaces; it puts empty squares in their place.

I also wouldn't mind using nice-looking quote marks for things. HTML has a tag for inline quoting: the <q> tag. Most browsers don't quite work properly with it. Here's a nice bit of quoted text:

“And then he said, ‘Stop, or, as my father used to say, “cut it out!”’”

When rendered with <q> tags, it looks like this:

And then he said, Stop, or, as my father used to say, cut it out!

Nobody gets it exactly right. Firefox 1.0 uses ASCII double quotes for everything. Firefox 1.5 correctly uses double curly and then single curly quotes, but it also uses single curly quotes on the innermost quote. w3m uses the ASCII backtick for all leading quotes and the ASCII single quote for all trailing quotes. Internet Explorer 5 doesn't render anything.

Terminal Function Key Escape Codes

I recently had the pleasure of trying to figure out a friend's terminal woes. His function keys weren't behaving properly. It turns out that his terminal was sending escape codes that differed from the terminfo definition his terminal was using. I set out to find what the correct solution was. These are my results. (Note that I use Debian GNU/Linux. Some of this may be Debian-specific.)

Most terminal emulators these days emulate some superset of a DEC VT100. (Not all of them emulate a VT100 exactly, though. cf. vttest.) The VT100 didn't have function keys in the sense that it didn't have keys labeled F1, F2, F3, etc. It did, however, have four keys over the numeric keypad labeled PF1 through PF4. These keys are generally regarded as analogous to F1 through F4 on a modern keyboard. They generated escape codes ^[OP through ^[OS. The appropriate $TERM type for a VT100 is vt100.

One of the best well known terminal emulators around, xterm, actually emulates (or strives to emulate) a DEC VT220. I'll get to xterm in a bit, but the VT220 was a more advanced terminal than the VT100. Among other things, it had twenty function keys, labeled F1 through F20. The first five were strictly for local terminal functions; the host never saw any escape codes from them. The remainder (F6 through F20) sent escape codes ^[[17~ to ^[[21~, ^[[23~ to ^[[26~, ^[[28~, ^[[29~, and ^[[31~ to ^[[34~. The appropriate $TERM type for a VT220 is vt220. (Note that, on my system, the vt220 $TERM type actually defines VT100 escape codes for F1 through F4. There's no definition for F5.)

This brings me to xterm. xterm has a long history, and the function key definitions have changed over time. The original xterm from the X Consortium (even before they became the Open Group) used escape codes based on the VT220, but extended to cover the range from F1 to F48. F1 through F12 generated, respectively, codes ^[[11~ to ^[[15~, ^[[17~ to ^[[21~, ^[[23~, and ^[[24~. Shift-F1 through Shift-F12 were used for F13 through F24, and generated codes from ^[[11;2~ to ^[[24;2~. Similarly Ctrl-F1 through Ctrl-F12 were used for F25 through F36 and generated codes ^[[11;5~ to ^[[24;5~, and Ctrl-Shift-F1 through Ctrl-Shift-F12 were used for F37 through F48 and generated codes ^[[11;6~ to ^[[24;6~. None of the base xterm $TERM types on my system correspond to this series of escape codes, though you can still get xterm to exhibit the old behavior by setting the OldXtermFKeys resource to 'true'.

The current XFree86 xterm mixes VT100 and VT220. Since the original VT220 didn't have F1 through F5, the XFree86 xterm uses the escape sequences from the VT100's PF1 through PF4 for F1 through F4 while retaining the VT220-based escape sequences from the X Consortium xterm for F5 through F12. So the differences from the earlier xterms are: F1 through F4 generate escape codes ^[OP through ^[OS, F13 to F16 generate ^[O2P to ^[O2S, F25 to F28 generate ^[O5P to ^[O5S, and F37 to F40 generate ^[O6P to ^[O6S. On my system, the $TERM types that have the appropriate function key definitions are xterm, xterm-debian, xterm-mono, and xterm-xfree86.

The GNOME project's terminal emulator is gnome-terminal. It generates the exact same escape codes as the XFree86 xterm and will work with the same $TERM settings. Note, however, that some function keys are bound to gnome-terminal actions and will not be passed through to applications running in the terminal. (For example, F1 calls up the GNOME help browser to view the gnome-terminal documentation.)

multi-gnome-terminal is based on gnome-terminal, but it implements multiple tabbed terminal sessions in a single window. It also does the function keys a little differently, though it's a bit more like the original VT220. F1 through F12 behave exactly the same as the XFree86 xterm. Shift-F1 through Shift-F10 function as F11 through F20 and generate escape codes from ^[[23~ to ^[[34~, just like the VT220. Note that this means there are two ways to get F11 and F12. (Actually, there are three, since Shift-F11 and Shift-F12 are also equivalent to F11 and F12.) On my system, the $TERM types with the appropriate function key definitions are xterm-color, xterm-r6, and xterm-vt220. xterm can be made to behave like this by setting the SunKeyboard resource to 'true'. Note that, like gnome-terminal, multi-gnome-terminal binds some function keys for its own use and may not pass then through to the programs in the terminal.

rxvt is a very popular xterm replacement. It uses the same escape sequences at the X11R6 xterm for F1 through F12. Shift-F1 through Shift-F12 work similarly to multi-gnome-terminal; they add ten to the number on the key (so there are again two ways to get F11 and F12). rxvt generates the same escape sequences as multi-gnome-terminal for F11 through F20, and uses ^[[23$ and ^[[24$ for F21 and F22, respectively. The sequence continues with Ctrl-F1 through Ctrl-F12 generating ^[[11^ through ^[[24^ for F23 through F34 (no overlap with previous sequences), Ctrl-Shift-F1 through Ctrl-Shift-F10 generating ^[[23^ through ^[[34^ for F33 through F42 (two-key overlap), and Ctrl-Shift-F11 and Ctrl-Shift-F12 generating ^[[23@ and ^[[24@ for F43 and F44. The base $TERM type for rxvt is rxvt, though it ships with several types for different circumstances, including rxvt-basic and rxvt-m. It also comes with rxvt-unicode, but on my system that definition only lists function keys up to F20.

GNU screen is also a terminal emulator, though it expects to run within another terminal environment (as opposed to displaying text in a graphical environment like xterm or displaying text on physical hardware like an actual terminal). As such, it translates many escape sequences from its containing terminal environment to the VT100-like environment it provides. It will recognize and translate the sequences for F1 through F12. For those, it will generate the same escape codes as the XFree86 xterm. It does not recognize F13 and above; those escape codes will pass through unchanged to the programs running within screen. (Note that the screen 'bindkey' command has a -k option that uses termcap capabilities to represent keys. It understands k1 through FA, which correspond to F1 through F20.) The $TERM type for screen is screen.

key VT100 VT220 X11R6 xterm XFree86 xterm rxvt MGT screen
F1^[OP ^[[11~ ^[OP ^[[11~^[OP ^[OP
F2^[OQ ^[[12~ ^[OQ ^[[12~^[OQ ^[OQ
F3^[OR ^[[13~ ^[OR ^[[13~^[OR ^[OR
F4^[OS ^[[14~ ^[OS ^[[14~^[OS ^[OS
F5 ^[[15~ ^[[15~ ^[[15~^[[15~ ^[[15~
F6 ^[[17~ ^[[17~ ^[[17~ ^[[17~^[[17~ ^[[17~
F7 ^[[18~ ^[[18~ ^[[18~ ^[[18~^[[18~ ^[[18~
F8 ^[[19~ ^[[19~ ^[[19~ ^[[19~^[[19~ ^[[19~
F9 ^[[20~ ^[[20~ ^[[20~ ^[[20~^[[20~ ^[[20~
F10 ^[[21~ ^[[21~ ^[[21~ ^[[21~^[[21~ ^[[21~
F11 ^[[23~ ^[[23~ ^[[23~ ^[[23~^[[23~ ^[[23~
F12 ^[[24~ ^[[24~ ^[[24~ ^[[24~^[[24~ ^[[24~
F13 ^[[25~ ^[[11;2~^[O2P ^[[25~^[[25~
F14 ^[[26~ ^[[12;2~^[O2Q ^[[26~^[[26~
F15 ^[[28~ ^[[13;2~^[O2R ^[[28~^[[28~
F16 ^[[29~ ^[[14;2~^[O2S ^[[29~^[[29~
F17 ^[[31~ ^[[15;2~^[[15;2~^[[31~^[[31~
F18 ^[[32~ ^[[17;2~^[[17;2~^[[32~^[[32~
F19 ^[[33~ ^[[18;2~^[[18;2~^[[33~^[[33~
F20 ^[[34~ ^[[19;2~^[[19;2~^[[34~^[[34~
F21 ^[[20;2~^[[20;2~^[[23$
F22 ^[[21;2~^[[21;2~^[[24$
F23 ^[[23;2~^[[23;2~^[[11^
F24 ^[[24;2~^[[24;2~^[[12^
F25 ^[[11;5~^[O5P ^[[13^
F26 ^[[12;5~^[O5Q ^[[14^
F27 ^[[13;5~^[O5R ^[[15^
F28 ^[[14;5~^[O5S ^[[17^
F29 ^[[15;5~^[[15;5~^[[18^
F30 ^[[17;5~^[[17;5~^[[19^
F31 ^[[18;5~^[[18;5~^[[20^
F32 ^[[19;5~^[[19;5~^[[21^
F33 ^[[20;5~^[[20;5~^[[23^
F34 ^[[21;5~^[[21;5~^[[24^
F35 ^[[23;5~^[[23;5~^[[25^
F36 ^[[24;5~^[[24;5~^[[26^
F37 ^[[11;6~^[O6P ^[[28^
F38 ^[[12;6~^[O6Q ^[[29^
F39 ^[[13;6~^[O6R ^[[31^
F40 ^[[14;6~^[O6S ^[[32^
F41 ^[[15;6~^[[15;6~^[[33^
F42 ^[[17;6~^[[17;6~^[[34^
F43 ^[[18;6~^[[18;6~^[[23@
F44 ^[[19;6~^[[19;6~^[[24@
F45 ^[[20;6~^[[20;6~
F46 ^[[21;6~^[[21;6~
F47 ^[[23;6~^[[23;6~
F48 ^[[24;6~^[[24;6~

Phil! Gold