Tue, 13 Dec 2005
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.
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~ |