VT100 Line Drawing

One of those totally useful1 things that crosses my mind occasionally is recompiling a version of dc that won’t choke on characters above code point 127. Among other reasons, occasionally code golf questions come up that really want box drawing characters used for some reason, and it just isn’t possible in dc. Except, I got to thinking… it absolutely is on a VT100, and xterm supports the same escape codes. I just haven’t really explored them. By moving into the “DEC Special Character and Line Drawing Set”, printing the characters in the 96-126 range (127 is still DEL) yields:

`: ♦      a: ▒      b: →      c: ƒ
d: r      e: ↴      f: °      g: ±
h: ↴      i: ↓      j: ┘      k: ┐
l: ┌      m: └      n: ┼      o: ⎺
p: ⎻      q: ─      r: ⎼      s: ⎽
t: ├      u: ┤      v: ┴      w: ┬
x: │      y: ≤      z: ≥      {: π
|: ≠      }: £      ~: ·

The above table was generated in dc with the following code:

96[AP]sF[ddP[: ]P27P[(0]PP27P[(B      ]P1+dd4%0=F127>M]dsMx

To switch character sets, we just need to send the appropriate escape code: 27P[(0]P to switch to the special characters, and 27P[(B]P to switch back2. ASCII code 27 (decimal) is ESC. ( is the escape code to ‘Designate G0 Character Set (ISO 2022)’, and 0 and B are the graphics set and ASCII set respectively.

Aside from not being super useful, it’s also not very golfy. There is one more trick that can be used to cut down on code if we’re going to be switching back and forth a lot: Shift Out (ASCII 14) and Shift In (ASCII 15). Shifting out switches us to the G1 character set; shifting in switches us back to G0. We can reassign G1 instead of G0 by using ) instead of (, so, 27P[(0]P. Then when we need to switch to the special characters, we shift out with 14P and back in with 15P.


  1. This is a lie, and we all know it. ↩︎
  2. (B is the code for US ASCII, UK should be (A. I haven’t looked through the DEC tables to see what the difference is, nor do I know if modern terminal emulators in a UK locale operate under this character set by default. ↩︎