git.y1.nz

rvis

Minimal terminal colorizer.
download: https://git.y1.nz/archives/rvis.tar.gz
README | Files | Log | Refs

dec-parser.html

      1 <!-- RETRIEVED FROM http://vt100.net/emu/dec_ansi_parser -->
      2 <!-- ON 2026-06-09 BY EMMA WEAVER -->
      3 
      4 <?xml version="1.0" encoding="UTF-8"?>
      5 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
      6 <head>
      7 <meta charset="utf-8"/>
      8 <meta name="viewport" content="width=device-width"/>
      9 <title>A parser for DEC’s ANSI-compatible video terminals</title>
     10 <link href="../terminal.css" rel="stylesheet"/>
     11 <link href="dap_style.css" rel="stylesheet"/>
     12 <link href="../dark-support.css" rel="stylesheet"/>
     13 <link rel="icon" href="/cover-logo-096.png" sizes="96x96"/>
     14 <script type="application/ld+json">
     15 {
     16     "@context": "http://schema.org",
     17     "@type": "WebPage",
     18     "name": "A parser for DEC’s ANSI-compatible video terminals",
     19     "author": {
     20         "@type": "Person",
     21         "name": "Paul Flo Williams"
     22     },
     23     "datePublished": "2002-03-11",
     24     "dateModified": "2017-08-25"
     25 }
     26 </script>
     27 </head>
     28 <body>
     29 <header>
     30 <nav class="breadcrumbs">
     31 <ol>
     32 <li><a href="../" title="Home"><svg xmlns="http://www.w3.org/2000/svg" width="92" height="16" version="1.1" id="vt100-net-site-logo">
     33   <title>VT100.net</title>
     34   <style>
     35   .blk { fill: #000000 }
     36   .g25 { fill: #626262 }
     37   .g50 { fill: #9b9b9b }
     38   .g75 { fill: #cccccc }
     39   .grd { fill: #006600 }
     40   .grl { fill: #00ff00 }
     41   .scanlines { fill: black; stroke: #5e5e5e; stroke-width: 0.4; paint-order:stroke fill markers }
     42   .dotnet { fill: #404040 }
     43   @media (prefers-color-scheme: dark) {
     44     .blk { fill: #626262 }
     45     .g25 { fill: #9b9b9b }
     46     .g50 { fill: #cccccc }
     47     .g75 { fill: #ffffff }
     48     .scanlines { fill: #00ff00; stroke: #009900 }
     49     .dotnet { fill: #909090 }
     50   }
     51   </style>
     52   <g id="term">
     53     <rect class="g50" x="05" y="02" width="9" height="1"/>
     54     <rect class="blk" x="14" y="02" height="1" width="1"/>
     55     <rect class="g50" x="04" y="03" width="11" height="8"/>
     56     <rect class="g25" x="05" y="03" width="9" height="7"/>
     57     <rect class="blk" x="15" y="03" height="8" width="1"/>
     58     <rect class="blk" x="06" y="04" width="8" height="6"/>
     59     <rect class="grd" x="07" y="05" width="6" height="4"/>
     60     <rect class="grl" x="08" y="05" width="1" height="1"/>
     61     <rect class="grl" x="10" y="05" width="1" height="1"/>
     62     <rect class="grl" x="07" y="06" width="1" height="1"/>
     63     <rect class="grl" x="09" y="06" width="1" height="1"/>
     64     <rect class="grl" x="08" y="07" width="1" height="1"/>
     65     <rect class="grl" x="10" y="07" width="1" height="1"/>
     66     <rect class="blk" x="05" y="11" height="1" width="10"/>
     67     <rect class="blk" x="07" y="12" width="1" height="1"/>
     68     <rect class="g25" x="08" y="12" width="4" height="1"/>
     69     <rect class="blk" x="12" y="12" width="1" height="1"/>
     70     <rect class="g25" x="03" y="13" width="13" height="1"/>
     71     <rect class="g75" x="04" y="13" width="1" height="1"/>
     72     <rect class="g75" x="06" y="13" width="1" height="1"/>
     73     <rect class="g75" x="08" y="13" width="1" height="1"/>
     74     <rect class="g75" x="10" y="13" width="1" height="1"/>
     75     <rect class="g75" x="12" y="13" width="1" height="1"/>
     76     <rect class="g75" x="14" y="13" width="1" height="1"/>
     77     <rect class="blk" x="16" y="13" width="1" height="1"/>
     78     <rect class="g25" x="02" y="14" width="15" height="1"/>
     79     <rect class="blk" x="17" y="14" width="1" height="1"/>
     80     <rect class="blk" x="02" y="15" width="16" height="1"/>
     81   </g>
     82   <g id="g1754" style="display:inline">
     83     <g class="scanlines">
     84       <path d="m 21.632883,3.3333123 c 0,0.2613338 0.07467,0.4666675 0.186667,0.4666675 h 1.418669 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666675 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.418669 c -0.112,0 -0.186667,0.2053337 -0.186667,0.4666675 z m 5.37601,0 c 0,0.2613338 0.07467,0.4666675 0.186667,0.4666675 h 1.418669 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666675 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.418669 c -0.112001,0 -0.186667,0.2053337 -0.186667,0.4666675 z m -5.37601,1.86667 c 0,0.2613338 0.07467,0.4666675 0.186667,0.4666675 h 1.418669 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666675 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.418669 c -0.112,0 -0.186667,0.2053337 -0.186667,0.4666675 z m 5.37601,0 c 0,0.2613338 0.07467,0.4666675 0.186667,0.4666675 h 1.418669 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666675 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.418669 c -0.112001,0 -0.186667,0.2053337 -0.186667,0.4666675 z m -4.480009,1.86667 c 0,0.2613339 0.07467,0.4666676 0.186667,0.4666676 h 1.41867 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666676 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.41867 c -0.112,0 -0.186667,0.2053337 -0.186667,0.4666675 z m 3.584007,0 c 0,0.2613339 0.07467,0.4666676 0.186667,0.4666676 h 1.418669 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666676 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.418669 c -0.112,0 -0.186667,0.2053337 -0.186667,0.4666675 z m -3.584007,1.8666701 c 0,0.2613338 0.07467,0.4666675 0.186667,0.4666675 h 1.41867 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666675 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.41867 c -0.112,0 -0.186667,0.2053337 -0.186667,0.4666675 z m 3.584007,0 c 0,0.2613338 0.07467,0.4666675 0.186667,0.4666675 h 1.418669 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666675 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.418669 c -0.112,0 -0.186667,0.2053337 -0.186667,0.4666675 z m -2.688005,1.8666696 c 0,0.261334 0.07467,0.466668 0.186667,0.466668 h 3.210673 c 0.112,0 0.186667,-0.205334 0.186667,-0.466668 c 0,-0.261333 -0.07467,-0.466667 -0.186667,-0.466667 h -3.210673 c -0.112,0 -0.186667,0.205334 -0.186667,0.466667 z m 0,1.86667 c 0,0.261334 0.07467,0.466668 0.186667,0.466668 h 3.210673 c 0.112,0 0.186667,-0.205334 0.186667,-0.466668 c 0,-0.261333 -0.07467,-0.466667 -0.186667,-0.466667 h -3.210673 c -0.112,0 -0.186667,0.205334 -0.186667,0.466667 z m 0.896002,1.86667 c 0,0.261334 0.07467,0.466668 0.186667,0.466668 h 1.418669 c 0.112,0 0.186667,-0.205334 0.186667,-0.466668 c 0,-0.261333 -0.07467,-0.466667 -0.186667,-0.466667 h -1.418669 c -0.112,0 -0.186667,0.205334 -0.186667,0.466667 z" id="path1765"/>
     85       <path d="m 30.342891,3.3333123 c 0,0.2613338 0.07467,0.4666675 0.186667,0.4666675 h 6.794678 c 0.112001,0 0.186667,-0.2053337 0.186667,-0.4666675 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -6.794678 c -0.112001,0 -0.186667,0.2053337 -0.186667,0.4666675 z m 2.688004,1.86667 c 0,0.2613338 0.07467,0.4666675 0.186667,0.4666675 h 1.41867 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666675 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.41867 c -0.112,0 -0.186667,0.2053337 -0.186667,0.4666675 z m 0,1.86667 c 0,0.2613339 0.07467,0.4666676 0.186667,0.4666676 h 1.41867 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666676 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.41867 c -0.112,0 -0.186667,0.2053337 -0.186667,0.4666675 z m 0,1.8666701 c 0,0.2613338 0.07467,0.4666675 0.186667,0.4666675 h 1.41867 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666675 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.41867 c -0.112,0 -0.186667,0.2053337 -0.186667,0.4666675 z m 0,1.8666696 c 0,0.261334 0.07467,0.466668 0.186667,0.466668 h 1.41867 c 0.112,0 0.186667,-0.205334 0.186667,-0.466668 c 0,-0.261333 -0.07467,-0.466667 -0.186667,-0.466667 h -1.41867 c -0.112,0 -0.186667,0.205334 -0.186667,0.466667 z m 0,1.86667 c 0,0.261334 0.07467,0.466668 0.186667,0.466668 h 1.41867 c 0.112,0 0.186667,-0.205334 0.186667,-0.466668 c 0,-0.261333 -0.07467,-0.466667 -0.186667,-0.466667 h -1.41867 c -0.112,0 -0.186667,0.205334 -0.186667,0.466667 z m 0,1.86667 c 0,0.261334 0.07467,0.466668 0.186667,0.466668 h 1.41867 c 0.112,0 0.186667,-0.205334 0.186667,-0.466668 c 0,-0.261333 -0.07467,-0.466667 -0.186667,-0.466667 h -1.41867 c -0.112,0 -0.186667,0.205334 -0.186667,0.466667 z" id="path1767"/>
     86       <path d="m 40.490903,3.3333123 c 0,0.2613338 0.07467,0.4666675 0.186667,0.4666675 h 1.418669 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666675 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.418669 c -0.112,0 -0.186667,0.2053337 -0.186667,0.4666675 z m -0.896002,1.86667 c 0,0.2613338 0.07467,0.4666675 0.186667,0.4666675 h 2.314671 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666675 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -2.314671 c -0.112,0 -0.186667,0.2053337 -0.186667,0.4666675 z m -0.896001,1.86667 c 0,0.2613339 0.07467,0.4666676 0.186667,0.4666676 h 3.210672 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666676 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -3.210672 c -0.112,0 -0.186667,0.2053337 -0.186667,0.4666675 z m 1.792003,1.8666701 c 0,0.2613338 0.07467,0.4666675 0.186667,0.4666675 h 1.418669 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666675 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.418669 c -0.112,0 -0.186667,0.2053337 -0.186667,0.4666675 z m 0,1.8666696 c 0,0.261334 0.07467,0.466668 0.186667,0.466668 h 1.418669 c 0.112,0 0.186667,-0.205334 0.186667,-0.466668 c 0,-0.261333 -0.07467,-0.466667 -0.186667,-0.466667 h -1.418669 c -0.112,0 -0.186667,0.205334 -0.186667,0.466667 z m 0,1.86667 c 0,0.261334 0.07467,0.466668 0.186667,0.466668 h 1.418669 c 0.112,0 0.186667,-0.205334 0.186667,-0.466668 c 0,-0.261333 -0.07467,-0.466667 -0.186667,-0.466667 h -1.418669 c -0.112,0 -0.186667,0.205334 -0.186667,0.466667 z m -1.792003,1.86667 c 0,0.261334 0.07467,0.466668 0.186667,0.466668 h 5.002676 c 0.112,0 0.186667,-0.205334 0.186667,-0.466668 c 0,-0.261333 -0.07467,-0.466667 -0.186667,-0.466667 h -5.002676 c -0.112,0 -0.186667,0.205334 -0.186667,0.466667 z" id="path1769"/>
     87       <path class="scanlines" d="m 47.80491,3.3333123 c 0,0.2613338 0.07467,0.4666675 0.186667,0.4666675 h 3.210673 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666675 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -3.210673 c -0.112,0 -0.186667,0.2053337 -0.186667,0.4666675 z m -0.896002,1.86667 c 0,0.2613338 0.07467,0.4666675 0.186667,0.4666675 h 1.41867 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666675 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.41867 c -0.112,0 -0.186667,0.2053337 -0.186667,0.4666675 z m 3.584007,0 c 0,0.2613338 0.07467,0.4666675 0.186667,0.4666675 h 1.418669 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666675 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.418669 c -0.112,0 -0.186667,0.2053337 -0.186667,0.4666675 z m -4.480008,1.86667 c 0,0.2613339 0.07467,0.4666676 0.186667,0.4666676 h 1.418669 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666676 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.418669 c -0.112,0 -0.186667,0.2053337 -0.186667,0.4666675 z m 5.37601,0 c 0,0.2613339 0.07467,0.4666676 0.186667,0.4666676 h 1.418669 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666676 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.418669 c -0.112001,0 -0.186667,0.2053337 -0.186667,0.4666675 z m -5.37601,1.8666701 c 0,0.2613338 0.07467,0.4666675 0.186667,0.4666675 h 1.418669 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666675 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.418669 c -0.112,0 -0.186667,0.2053337 -0.186667,0.4666675 z m 5.37601,0 c 0,0.2613338 0.07467,0.4666675 0.186667,0.4666675 h 1.418669 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666675 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.418669 c -0.112001,0 -0.186667,0.2053337 -0.186667,0.4666675 z m -5.37601,1.8666696 c 0,0.261334 0.07467,0.466668 0.186667,0.466668 h 1.418669 c 0.112,0 0.186667,-0.205334 0.186667,-0.466668 c 0,-0.261333 -0.07467,-0.466667 -0.186667,-0.466667 h -1.418669 c -0.112,0 -0.186667,0.205334 -0.186667,0.466667 z m 5.37601,0 c 0,0.261334 0.07467,0.466668 0.186667,0.466668 h 1.418669 c 0.112,0 0.186667,-0.205334 0.186667,-0.466668 c 0,-0.261333 -0.07467,-0.466667 -0.186667,-0.466667 h -1.418669 c -0.112001,0 -0.186667,0.205334 -0.186667,0.466667 z m -4.480009,1.86667 c 0,0.261334 0.07467,0.466668 0.186667,0.466668 h 1.41867 c 0.112,0 0.186667,-0.205334 0.186667,-0.466668 c 0,-0.261333 -0.07467,-0.466667 -0.186667,-0.466667 h -1.41867 c -0.112,0 -0.186667,0.205334 -0.186667,0.466667 z m 3.584007,0 c 0,0.261334 0.07467,0.466668 0.186667,0.466668 h 1.418669 c 0.112,0 0.186667,-0.205334 0.186667,-0.466668 c 0,-0.261333 -0.07467,-0.466667 -0.186667,-0.466667 h -1.418669 c -0.112,0 -0.186667,0.205334 -0.186667,0.466667 z m -2.688005,1.86667 c 0,0.261334 0.07467,0.466668 0.186667,0.466668 h 3.210673 c 0.112,0 0.186667,-0.205334 0.186667,-0.466668 c 0,-0.261333 -0.07467,-0.466667 -0.186667,-0.466667 h -3.210673 c -0.112,0 -0.186667,0.205334 -0.186667,0.466667 z" id="path1771"/>
     88       <path class="scanlines" d="m 56.514917,3.3333123 c 0,0.2613338 0.07467,0.4666675 0.186667,0.4666675 h 3.210672 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666675 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -3.210672 c -0.112,0 -0.186667,0.2053337 -0.186667,0.4666675 z m -0.896002,1.86667 c 0,0.2613338 0.07467,0.4666675 0.186667,0.4666675 h 1.418669 c 0.112001,0 0.186667,-0.2053337 0.186667,-0.4666675 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.418669 c -0.112,0 -0.186667,0.2053337 -0.186667,0.4666675 z m 3.584007,0 c 0,0.2613338 0.07467,0.4666675 0.186667,0.4666675 h 1.418669 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666675 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.418669 c -0.112001,0 -0.186667,0.2053337 -0.186667,0.4666675 z m -4.480008,1.86667 c 0,0.2613339 0.07467,0.4666676 0.186667,0.4666676 h 1.418669 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666676 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.418669 c -0.112001,0 -0.186667,0.2053337 -0.186667,0.4666675 z m 5.376009,0 c 0,0.2613339 0.07467,0.4666676 0.186667,0.4666676 h 1.418669 c 0.112001,0 0.186667,-0.2053337 0.186667,-0.4666676 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.418669 c -0.112,0 -0.186667,0.2053337 -0.186667,0.4666675 z m -5.376009,1.8666701 c 0,0.2613338 0.07467,0.4666675 0.186667,0.4666675 h 1.418669 c 0.112,0 0.186667,-0.2053337 0.186667,-0.4666675 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.418669 c -0.112001,0 -0.186667,0.2053337 -0.186667,0.4666675 z m 5.376009,0 c 0,0.2613338 0.07467,0.4666675 0.186667,0.4666675 h 1.418669 c 0.112001,0 0.186667,-0.2053337 0.186667,-0.4666675 c 0,-0.2613338 -0.07467,-0.4666675 -0.186667,-0.4666675 h -1.418669 c -0.112,0 -0.186667,0.2053337 -0.186667,0.4666675 z m -5.376009,1.8666696 c 0,0.261334 0.07467,0.466668 0.186667,0.466668 h 1.418669 c 0.112,0 0.186667,-0.205334 0.186667,-0.466668 c 0,-0.261333 -0.07467,-0.466667 -0.186667,-0.466667 h -1.418669 c -0.112001,0 -0.186667,0.205334 -0.186667,0.466667 z m 5.376009,0 c 0,0.261334 0.07467,0.466668 0.186667,0.466668 h 1.418669 c 0.112001,0 0.186667,-0.205334 0.186667,-0.466668 c 0,-0.261333 -0.07467,-0.466667 -0.186667,-0.466667 h -1.418669 c -0.112,0 -0.186667,0.205334 -0.186667,0.466667 z m -4.480008,1.86667 c 0,0.261334 0.07467,0.466668 0.186667,0.466668 h 1.418669 c 0.112001,0 0.186667,-0.205334 0.186667,-0.466668 c 0,-0.261333 -0.07467,-0.466667 -0.186667,-0.466667 h -1.418669 c -0.112,0 -0.186667,0.205334 -0.186667,0.466667 z m 3.584007,0 c 0,0.261334 0.07467,0.466668 0.186667,0.466668 h 1.418669 c 0.112,0 0.186667,-0.205334 0.186667,-0.466668 c 0,-0.261333 -0.07467,-0.466667 -0.186667,-0.466667 h -1.418669 c -0.112001,0 -0.186667,0.205334 -0.186667,0.466667 z m -2.688005,1.86667 c 0,0.261334 0.07467,0.466668 0.186667,0.466668 h 3.210672 c 0.112,0 0.186667,-0.205334 0.186667,-0.466668 c 0,-0.261333 -0.07467,-0.466667 -0.186667,-0.466667 h -3.210672 c -0.112,0 -0.186667,0.205334 -0.186667,0.466667 z" id="path1773"/>
     89     </g>
     90     <g class="dotnet">
     91       <path d="m 65.076956,12.647997 q 0.466667,0 0.784001,0.336 q 0.336001,0.336001 0.336001,0.802669 q 0,0.504 -0.354668,0.858668 q -0.354667,0.354667 -0.858668,0.354667 q -0.448001,0 -0.802668,-0.298667 q -0.336001,-0.298667 -0.336001,-0.746668 q 0,-0.541335 0.354668,-0.914669 q 0.354667,-0.392 0.877335,-0.392 z" id="path1756"/>
     92       <path d="m 68.362297,13.394665 l 1.661336,-4.6480086 q 0.112,-0.2240004 0.09333,-0.5040009 q -0.01867,-0.2800005 -0.224001,-0.2800005 q -0.410667,0 -0.933335,0.4293341 q -0.504001,0.4106674 -0.578668,0.4106674 q -0.205333,0 -0.205333,-0.3920007 q 0,-0.3920007 0.858668,-1.1013353 q 0.858668,-0.7093346 1.680003,-0.7093346 q 1.064002,0 0.634668,1.86667 q -0.01867,0.093333 0.056,0.1306669 q 0.07467,0.037333 0.149334,-0.018667 q 1.997336,-1.9786702 3.714673,-1.9786702 q 0.634668,0 0.765335,0.7840014 q 0.149333,0.7653347 -0.168001,1.6426696 l -1.437336,4.1253411 q -0.112,0.317334 0.149334,0.317334 q 0.392001,0 0.914668,-0.448001 q 0.522668,-0.448001 0.616001,-0.448001 q 0.130667,0 0.130667,0.242667 q 0,0.522668 -0.952001,1.306669 q -0.952002,0.765335 -1.75467,0.765335 q -0.821335,0 -0.821335,-0.765335 q 0,-0.28 0.112,-0.578668 l 1.493336,-4.2560073 q 0.597335,-1.6426696 -0.01867,-1.6426696 q -0.840001,0 -1.848003,1.1573354 q -1.008002,1.1573354 -1.773336,2.6133385 q -0.746668,1.437335 -1.269336,2.893338 q -0.186667,0.560001 -0.448001,0.578668 q -0.224,0.01867 -0.560001,-0.186667 q -0.317334,-0.186667 -0.317334,-0.280001 q 0,-0.224 0.280001,-1.026668 z" id="path1758"/>
     93       <path d="m 79.487639,10.071992 q 0,0.130667 0.112,0.130667 q 1.026669,0 1.829337,-0.8026681 q 0.821335,-0.8213348 0.821335,-1.6053362 q 0,-0.4480008 -0.672001,-0.4480008 q -0.448001,0 -1.269336,1.0266685 q -0.821335,1.0080018 -0.821335,1.6986696 z m 2.370671,-3.4720061 q 1.792003,0 1.792003,1.4373359 q 0,1.0453352 -1.512002,1.9600035 q -1.493336,0.8960017 -2.725339,0.8960017 q -0.130667,0 -0.224,0.317334 q -0.09333,0.298667 -0.09333,0.616001 q 0,0.728001 0.280001,1.250669 q 0.28,0.522668 0.858668,0.522668 q 0.373334,0 0.802668,-0.205334 q 0.429334,-0.224001 0.728002,-0.448001 q 0.298667,-0.224 0.354667,-0.224 q 0.261334,0 0.261334,0.448 q 0,0.429335 -0.989335,1.064002 q -0.989336,0.616001 -1.978671,0.616001 q -0.914668,0 -1.437336,-0.821334 q -0.522667,-0.821335 -0.522667,-1.885337 q 0,-2.053337 1.400002,-3.7893403 q 1.400003,-1.7546698 3.005339,-1.7546698 z" id="path1760"/>
     94       <path d="m 87.663666,4.9759829 q 0.317334,0 0.317334,0.4666675 q 0,0.4480009 -0.280001,1.5306695 h 1.885337 q 0.485334,0 0.485334,0.2800005 q 0,0.186667 -0.298667,0.4853342 q -0.280001,0.2800005 -0.560001,0.2800005 h -1.736003 l -1.362669,5.1333429 q -0.07467,0.317334 0.149333,0.317334 q 0.392001,0 0.914668,-0.448001 q 0.522668,-0.448001 0.616002,-0.448001 q 0.130666,0 0.130666,0.242667 q 0,0.522668 -0.914668,1.306669 q -0.896001,0.765335 -1.69867,0.765335 q -0.821334,0 -0.821334,-0.765335 q 0,-0.130667 0.112,-0.578668 l 1.456002,-5.5253429 h -0.877334 q -0.429335,0 -0.429335,-0.2613338 q 0,-0.2426671 0.242668,-0.5040009 q 0.261333,-0.2800005 0.541334,-0.2800005 h 0.746668 l 0.261334,-1.0453352 q 0.03733,-0.2240005 0.373334,-0.5786678 q 0.354667,-0.373334 0.746668,-0.373334 z" id="path1762"/>
     95     </g>
     96   </g>
     97 </svg></a></li>
     98 <li><a href="./" title="Emulation">Emulation</a></li>
     99 </ol>
    100 </nav>
    101 </header>
    102 
    103 <h1>A parser for DEC’s ANSI-compatible video terminals</h1>
    104 <h2 id="DESIGN">Design Aims</h2>
    105 <p>This document presents a state machine for a parser for escape and control sequences, suitable
    106 for use in a VT emulator. It is claimed to have two important properties:</p>
    107 <ul>
    108 <li><p><strong>Completeness</strong> – it specifies the actions and transitions for every incoming
    109 character for every state of the parser. In particular, it covers the behaviour of the C0 controls (0/0
    110 to 1/15) and characters 10/0 to 15/15 for every state.</p>
    111 <p><em>Completeness</em> does not mean that this state diagram contains all the information you need
    112 to write a terminal emulator! There are no details here of the mapping of character sets or of cursor
    113 movement behaviour, to name just two examples. However, it does specify how every incoming character affects the parser’s
    114 state.</p></li>
    115 <li><p><strong>Correctness</strong> – if you were to feed this parser a stream of characters that
    116 is random or deliberately <em>pathological</em>, it is claimed that this parser will exhibit the same
    117 visible behaviour as any one of DEC’s 8-bit ANSI-compatible terminals, from VT220 to VT525. A VT100-series parser would be
    118 simpler still, as the VT100 only supports 7-bit characters.</p></li>
    119 </ul>
    120 <p>During the discussion of this design, I will mention some real terminal emulators by name. This is for
    121 comparative purposes only and no criticism is intended of decisions made by the authors or maintainers of
    122 the applications referred to. After all, I am not presenting a product to the world, merely an <em>ideal
    123 software model</em> and I am free to ignore efficiency!</p>
    124 <p>In this document, “VT500” is used as shorthand for the VT500 series of terminals, the VT510, VT520 and VT525.</p>
    125 <h3>Why <em>DEC-compatible</em>, not just <em>ANSI-compatible</em>?</h3>
    126 <p>All of DEC’s terminals from the VT100 onward are compatible with ANSI X3.64-1979, “Additional Controls for Use with American National
    127 Standard Code for Information Interchange”, hereafter referred to just as X3.64.
    128 However, X3.64 defines many implementation-dependent features and error conditions <em>without defining recovery procedures</em>. A sample of these is
    129 given below; a more detailed treatment appears later.</p>
    130 <ul>
    131 <li><p>Occurrences of characters 00-1F or 7F-FF in an escape sequence or control sequence is an error condition whose
    132 recovery is not specified.</p></li>
    133 <li><p>For control sequences, the maximum length of parameter string is defined by implementation.</p></li>
    134 <li><p>For control sequences, occurrences of a parameter character after an intermediate character is an error
    135 condition.</p></li>
    136 </ul>
    137 <p>A terminal is a closed
    138 box that doesn’t normally report errors in its input stream to the host, so it must define a recovery
    139 procedure for all the circumstances left undefined by X3.64. DEC defined the recoveries for their
    140 terminals, so emulators should match these exactly<a href="#FOOTMATCH">¹</a>.</p>
    141 <h2 id="DIAGRAM">The State Diagram</h2>
    142 
    143 <svg xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" id="svg1" version="1.1" viewBox="60 0 1400 1030" font-family="Helvetica" sodipodi:docname="20230121_extracted_ansi_diagram_resaved.svg" inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)">
    144   <title id="title2">VT500-Series Parser</title>
    145   <metadata id="metadata4">
    146     <rdf:RDF>
    147       <cc:Work rdf:about="">
    148         <dc:format>image/svg+xml</dc:format>
    149         <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
    150         <dc:title>VT500-Series Parser</dc:title>
    151         <dc:creator>
    152           <cc:Agent>
    153             <dc:title>Paul Flo Williams &lt;paul@frixxon.co.uk&gt;</dc:title>
    154           </cc:Agent>
    155         </dc:creator>
    156         <dc:rights>
    157           <cc:Agent>
    158             <dc:title/>
    159           </cc:Agent>
    160         </dc:rights>
    161         <dc:source>http://vt100.net/emu/dec_ansi_parser</dc:source>
    162         <dc:language>en</dc:language>
    163         <cc:license rdf:resource="http://creativecommons.org/licenses/by-nc-sa/3.0/"/>
    164       </cc:Work>
    165       <cc:License rdf:about="http://creativecommons.org/licenses/by-nc-sa/3.0/">
    166         <cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
    167         <cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
    168         <cc:requires rdf:resource="http://creativecommons.org/ns#Notice"/>
    169         <cc:requires rdf:resource="http://creativecommons.org/ns#Attribution"/>
    170         <cc:prohibits rdf:resource="http://creativecommons.org/ns#CommercialUse"/>
    171         <cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
    172         <cc:requires rdf:resource="http://creativecommons.org/ns#ShareAlike"/>
    173       </cc:License>
    174     </rdf:RDF>
    175   </metadata>
    176   <defs id="defs12">
    177     <marker style="overflow:visible;" id="Dot_l" refX="0.0" refY="0.0" orient="auto" inkscape:stockid="Dot_l">
    178       <path transform="scale(0.8) translate(7.125493, 1)" style="fill-rule:evenodd;marker-start:none;marker-end:none;stroke:none" d="M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 -12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z " id="path41"/>
    179     </marker>
    180     <marker style="overflow:visible;" id="Arrow2L" refX="0.0" refY="0.0" orient="auto" inkscape:stockid="Arrow2L">
    181       <path transform="scale(1.1) translate(-5,0)" d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z " style="font-size:12.0;fill-rule:evenodd;stroke:none;stroke-width:0.62500000;stroke-linejoin:round;" id="path2097" sodipodi:nodetypes="cccc"/>
    182     </marker>
    183     <marker inkscape:stockid="Arrow2Lend" orient="auto" refY="0.0" refX="0.0" id="Arrow2Lend" style="overflow:visible;" inkscape:isstock="true">
    184       <path id="path4163" fill="#000000" d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z " transform="scale(1.1) rotate(180) translate(1,0)"/>
    185     </marker>
    186   </defs>
    187   <sodipodi:namedview id="base" snaptoguides="true" guidetolerance="5mm" showgrid="true" inkscape:zoom="0.8623457" inkscape:cx="625.03935" inkscape:cy="418.0458" inkscape:window-width="2560" inkscape:window-height="1389" inkscape:window-x="0" inkscape:window-y="27" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:window-maximized="1" inkscape:current-layer="svg1"/>
    188   <style>
    189   .diagbox { fill: white }
    190   .interstate { stroke: black; stroke-width: 1pt }
    191   .stateboxdup { stroke: black; fill: #ccc; stroke-dasharray: 5,5 }
    192     /* markers */
    193     #Arrow2L path { fill: black }
    194     #Arrow2Lend path { fill: black }
    195     #Dot_l path { fill: black }
    196     /* end of markers */
    197   text { fill: black }
    198   .statesep { stroke: black; stroke-width: 1pt }
    199   .state rect { fill: #eeee9f; stroke: black; stroke-width: 1pt }
    200 
    201   @media (prefers-color-scheme: dark) {
    202     .diagbox { fill: black }
    203     .interstate { stroke: white; stroke-width: 1pt }
    204     .stateboxdup { stroke: white; fill: #666; stroke-dasharray: 5,5 } /* light: fill=#ccc */
    205     /* markers */
    206     #Arrow2L path { fill: white }
    207     #Arrow2Lend path { fill: white }
    208     #Dot_l path { fill: white }
    209     /* end of markers */
    210     text { fill: white }
    211     .statesep { stroke-width: 1pt; stroke: white }
    212     .state rect { fill: #066; stroke: white; stroke-width: 1pt } /* light: #eeee9f */
    213   }
    214   </style>
    215   <rect class="diagbox" x="0" y="0" width="1489" height="1150" id="rect15"/>
    216   <text id="legend-dcs-entry-to-dcs-inter" font-size="12px" x="1175.797859" y="411.404413"><tspan id="tspan17">20-2F / collect</tspan></text>
    217   <text id="legend-dcs-entry-to-dcs-ignore" font-size="12px" x="1127.071297" y="519.615350"><tspan id="tspan20">3A</tspan></text>
    218   <text id="legend-dcs-inter-to-dcs-ignore" font-size="12px" x="1302.993172" y="499.365350"><tspan id="tspan23">30-3F</tspan></text>
    219   <text id="legend-dcs-param-to-dcs-inter" font-size="12px" x="1259.961922" y="747.427850"><tspan id="tspan26">20-2F / collect</tspan></text>
    220   <text id="legend-dcs-param-to-dcs-ignore" font-size="12px" x="1140" y="725"><tspan id="tspan29">3A,3C-3F</tspan></text>
    221   <text id="legend-dcs-entry-to-dcs-param" font-size="12px" x="1066.5887" y="642.77313"><tspan id="tspan32">30-39,3B / param</tspan><tspan x="1066.5887" dy="15" id="tspan34">3C-3F / collect</tspan></text>
    222   <text id="legend-dcs-entry-to-dcs-pass" font-size="12px" x="972.032234" y="658.201288"><tspan id="tspan37">40-7E</tspan></text>
    223   <text id="legend-dcs-param-to-dcs-pass" font-size="12px" x="1208.071297" y="812.607538"><tspan id="tspan40">40-7E</tspan></text>
    224   <text id="legend-dcs-inter-to-dcs-pass" font-size="12px" x="1389.055672" y="673.388788"><tspan id="tspan43">40-7E</tspan></text>
    225   <text id="legend-escape-to-sos" font-size="12px" x="865.086922" y="307.623163"><tspan id="tspan46">58,5E,5F</tspan></text>
    226   <text id="legend-escape-to-escape-inter" font-size="12px" x="632.844734" y="218.396600"><tspan id="tspan49">20-2F / collect</tspan></text>
    227   <text id="legend-escape-inter-to-ground" font-size="12px" x="412.625984" y="144.357538"><tspan id="tspan52">30-7E / esc_dispatch</tspan></text>
    228   <text id="legend-escape-to-ground" font-size="12px" x="475" y="235"><tspan id="tspan55">30-4F,51-57,59,5A,</tspan><tspan x="475" dy="15" id="tspan57">5C,60-7E / esc_dispatch</tspan></text>
    229   <text id="legend-escape-to-csi-entry" font-size="12px" x="691.063484" y="622.763788"><tspan id="tspan60">5B</tspan></text>
    230   <text id="legend-csi-entry-to-csi-param" font-size="12px" x="458" y="540"><tspan id="tspan63">30-39,3B / param</tspan><tspan x="458.18848" dy="15" id="tspan65">3C-3F / collect</tspan></text>
    231   <text id="legend-csi-entry-to-csi-ignore" font-size="12px" x="514.508797" y="765.779413"><tspan id="tspan68">3A</tspan></text>
    232   <text id="legend-cgi-inter-to-csi-ignore" font-size="12px" x="243.665047" y="767.045038"><tspan id="tspan71">30-3F</tspan></text>
    233   <text id="legend-csi-entry-to-csi-inter" font-size="12px" x="381.43427" y="887.65723"><tspan id="tspan74">20-2F / collect</tspan></text>
    234   <text id="legend-csi-inter-to-ground" font-size="12px" x="75.087791" y="494.86545"><tspan id="tspan77">40-7E / csi_dispatch</tspan></text>
    235   <text id="legend-escape-to-osc" font-size="12px" x="795" y="500"><tspan id="tspan80">5D</tspan></text>
    236   <text id="legend-escape-to-dcs-entry" font-size="12px" x="898" y="419"><tspan id="tspan83">50</tspan></text>
    237   <text id="diagram-title" style="font-weight:bold;font-size:22px" x="600" y="45"><tspan id="tspan86">VT500-Series Parser</tspan></text>
    238   <text id="diagram-credits" style="font-size:12px" x="600" y="65"><tspan id="tspan89">Copyright 2002‒2017 Paul Flo Williams</tspan></text>
    239   <g id="explain-gr" transform="translate(750,910)">
    240     <rect x="0" y="0" width="225" height="110" fill="#eeeeee" opacity="0.5" stroke="black" stroke-width="1pt" id="rect92"/>
    241     <text x="5" y="17" font-size="12px" id="text106"><tspan font-weight="bold" id="tspan94">Treatment of codes A0‒FF</tspan><tspan x="5" dy="15" id="tspan96">In all cases shown here, codes</tspan><tspan x="5" dy="15" id="tspan98">A0‒FF (GR area) are treated identically</tspan><tspan x="5" dy="15" id="tspan100">to codes 20‒7F (GL area). This</tspan><tspan x="5" dy="15" id="tspan102">symmetry does not extend to the C0</tspan><tspan x="5" dy="15" id="tspan104">and C1 areas.</tspan></text>
    242   </g>
    243   <path id="path-start-to-ground" class="interstate" style="fill:none;fill-rule:evenodd;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow2L);marker-end:url(#Dot_l);" d="M 159.44882,114.51324 L 120.31138,76.100571"/>
    244   <path id="path-esc-inter-to-ground" class="interstate" style="fill:none;fill-rule:evenodd;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow2L);" d="M 312.37472,148.57730 L 566.76806,152.20114"/>
    245   <path id="path-escape-to-sos" class="interstate" style="fill:none;fill-rule:evenodd;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow2L);" d="M 911.75732,201.48532 L 805.21652,379.77809"/>
    246   <path id="path-escape-to-escape-inter" class="interstate" style="fill:none;fill-rule:evenodd;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow2L);" d="M 603.73119,194.96242 L 705.92339,380.50285"/>
    247   <path id="path-escape-to-dcs-entry" class="interstate" style="fill:none;fill-rule:evenodd;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow2L);" d="M 970.46347,427.61273 L 828.40907,418.91552"/>
    248   <path id="path-dcs-entry-to-dcs-inter" class="interstate" style="fill:none;fill-rule:evenodd;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow2L);" d="M 1283.5630,427.61273 L 1122.6646,425.43843"/>
    249   <path id="path-dcs-inter-to-dcs-ignore" class="interstate" style="fill:none;fill-rule:evenodd;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow2L);" d="M 1305.3059,553.72225 L 1355.3149,464.57587"/>
    250   <path id="path-dcs-entry-to-dcs-ignore" class="interstate" style="fill:none;fill-rule:evenodd;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow2L);" d="M 1174.1231,550.09842 L 1116.1417,463.12634"/>
    251   <path id="path-dcs-entry-to-dcs-param" class="interstate" style="fill:none;fill-rule:evenodd;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow2L);" d="M 1063.5961,724.76735 L 1063.2337,464.57586"/>
    252   <path id="path-dcs-param-to-dcs-ignore" class="interstate" style="fill:none;fill-rule:evenodd;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow2L);" d="M 1196.5909,638.52003 L 1122.6646,732.73978"/>
    253   <path id="path-escape-to-osc" class="interstate" style="fill:none;fill-rule:evenodd;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow2L);" d="M 803.04222,623.29992 L 775.50106,452.97959"/>
    254   <path id="path-csi-inter-to-csi-ignore" class="interstate" style="fill:none;fill-rule:evenodd;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow2L);" d="M 337.74159,716.79491 L 240.62276,817.53756"/>
    255   <path id="path-csi-entry-to-csi-ignore" class="interstate" style="fill:none;fill-rule:evenodd;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow2L);" d="M 454.42912,714.62060 L 573.89138,835.23219"/>
    256   <path id="path-csi-entry-to-csi-param" class="interstate" style="fill:none;fill-rule:evenodd;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow2L);" d="M 431.23657,526.18110 L 605.48095,832.33312"/>
    257   <path id="path-csi-entry-to-csi-inter" class="interstate" style="fill:none;fill-rule:evenodd;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow2L);" d="M 261.64101,863.92267 L 568.21760,873.34465"/>
    258   <path id="path-csi-inter-to-ground" class="interstate" style="fill:none;fill-rule:evenodd;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow2L);" d="M 222.41975,196.50738 L 152.72140,817.64272"/>
    259   <path id="path-escape-to-csi-entry" class="interstate" style="fill:none;fill-rule:evenodd;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow2L);" d="M 685.70881,824.81756 L 734.90765,452.75134"/>
    260   <path id="path-dcs-param-to-dcs-inter" class="interstate" style="fill:none;fill-rule:evenodd;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow2L);" d="M 1367.3177,472.22587 C 1364.2428,704.89539 1232.0210,768.44388 1166.4225,768.44388"/>
    261   <path id="path-dcs-inter-to-dcs-pass" class="interstate" style="fill:none;fill-rule:evenodd;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow2L);" d="M 1382.6923,853.51687 L 1381.6674,464.02607"/>
    262   <path id="path-dcs-param-to-dcs-pass" class="interstate" style="fill:none;fill-rule:evenodd;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow2L);" d="M 1293.5195,863.76664 L 1156.1727,805.34301"/>
    263   <path id="path-dcs-entry-to-dcs-pass" class="interstate" style="fill:none;fill-rule:evenodd;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow2L);marker-end:none;" d="M 1291.4695,907.84059 C 1168.4724,964.21426 1043.4254,940.63986 989.10166,864.79161 C 908.12857,737.69461 1027.0258,465.05104 1027.0258,465.05104"/>
    264   <path id="path-escape-to-ground" class="interstate" style="fill:none;fill-rule:evenodd;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow2L);" d="M 313.64260,172.93294 C 441.42291,173.61626 568.17826,392.61942 685.70881,393.30274"/>
    265   <!-- ground -->
    266   <g id="anywhere-to-ground" transform="translate(197,18)">
    267     <rect class="stateboxdup" x="0" y="0" width="70" height="35" rx="7" ry="7" id="rect131"/>
    268     <text x="35" y="20" font-size="12px" text-anchor="middle" id="text133">anywhere</text>
    269   </g>
    270   <line class="interstate" x1="232" y1="53" x2="232" y2="118" marker-end="url(#Arrow2Lend)" id="line136"/>
    271   <text x="236" y="68" font-size="12px" id="text144"><tspan x="236" dy="0" id="tspan138">18,1A / execute</tspan><tspan x="236" dy="15" id="tspan140">80-8F,91-97,99,9A / execute</tspan><tspan x="236" dy="15" id="tspan142">9C / (no action)</tspan></text>
    272   <g id="state-ground" class="state" transform="translate(162,118)">
    273     <rect x="0" y="0" width="140" height="70" rx="10" ry="10" id="rect146"/>
    274     <text x="70" y="18" text-anchor="middle" font-size="12px" id="text148">ground</text>
    275     <line class="statesep" x1="10" y1="24" x2="130" y2="24" id="line150"/>
    276     <text x="10" y="35" font-size="8px" id="text156"><tspan x="10" dy="0" id="tspan152">event 00-17,19,1C-1F / execute</tspan><tspan x="10" dy="9" id="tspan154">event 20-7F / print</tspan></text>
    277   </g>
    278   <!-- escape -->
    279   <g id="anywhere-to-escape" transform="translate(723,300)">
    280     <rect class="stateboxdup" x="0" y="0" width="70" height="35" ry="7" rx="7" id="rect159"/>
    281     <text x="35" y="20" font-size="12px" text-anchor="middle" id="text161">anywhere</text>
    282   </g>
    283   <line class="interstate" x1="758" y1="335" x2="758" y2="380" marker-end="url(#Arrow2Lend)" id="line164"/>
    284   <text x="762" y="350" font-size="12px" id="text168"><tspan id="tspan166">1B</tspan></text>
    285   <g id="state-escape" class="state" transform="translate(688,380)">
    286     <rect x="0" y="0" width="140" height="70" rx="10" ry="10" id="rect170"/>
    287     <text x="70" y="18" text-anchor="middle" font-size="12px" id="text172">escape</text>
    288     <line class="statesep" x1="10" y1="24" x2="130" y2="24" id="line174"/>
    289     <text x="10" y="35" font-size="8px" id="text182"><tspan x="10" dy="0" id="tspan176">entry / clear</tspan><tspan x="10" dy="9" id="tspan178">event 00-17,19,1C-1F / execute</tspan><tspan x="10" dy="9" id="tspan180">event 7F / ignore</tspan></text>
    290   </g>
    291   <!-- escape intermediate -->
    292   <g id="state-escape-intermediate" class="state" transform="translate(568,115)">
    293     <rect x="0" y="0" width="140" height="70" rx="10" ry="10" id="rect185"/>
    294     <text x="70" y="18" text-anchor="middle" font-size="12px" id="text187">escape intermediate</text>
    295     <line class="statesep" x1="10" y1="24" x2="130" y2="24" id="line189"/>
    296     <text x="10" y="35" font-size="8px" id="text197"><tspan x="10" dy="0" id="tspan191">event 00-17,19,1C-1F / execute</tspan><tspan x="10" dy="9" id="tspan193">event 20-2F / collect</tspan><tspan x="10" dy="9" id="tspan195">event 7F / ignore</tspan></text>
    297   </g>
    298   <!-- csi entry -->
    299   <g id="anywhere-to-csi-entry" transform="translate(605,753)">
    300     <rect class="stateboxdup" x="0" y="0" width="70" height="35" ry="7" rx="7" id="rect200"/>
    301     <text x="35" y="20" font-size="12px" text-anchor="middle" id="text202">anywhere</text>
    302   </g>
    303   <line class="interstate" x1="640" y1="788" x2="640" y2="833" marker-end="url(#Arrow2Lend)" id="line205"/>
    304   <text x="644" y="803" font-size="12px" id="text209"><tspan id="tspan207">9B</tspan></text>
    305   <g id="state-csi-entry" class="state" transform="translate(570,833)">
    306     <rect x="0" y="0" width="140" height="70" rx="10" ry="10" id="rect211"/>
    307     <text x="70" y="18" text-anchor="middle" font-size="12px" id="text213">csi entry</text>
    308     <line class="statesep" x1="10" y1="24" x2="130" y2="24" id="line215"/>
    309     <text x="10" y="35" font-size="8px" id="text223"><tspan x="10" dy="0" id="tspan217">entry / clear</tspan><tspan x="10" dy="9" id="tspan219">event 00-17,19,1C-1F / execute</tspan><tspan x="10" dy="9" id="tspan221">event 7F / ignore</tspan></text>
    310   </g>
    311   <path class="interstate" d="M 640,903 L 640,933 C 640,943 630,953 620,953 L 90,953 C 80,953 70,943 70,933 L 70 180 C 70,170 80,160 90,160 L 162,160" fill="none" marker-end="url(#Arrow2Lend)" id="path226"/>
    312   <text id="legend-csi-entry-to-ground" x="507" y="943" font-size="12px"><tspan id="tspan228">40-7E / csi_dispatch</tspan></text>
    313   <!-- csi param -->
    314   <g id="state-csi-param" class="state" transform="translate(308,446)">
    315     <rect x="0" y="0" width="140" height="70" rx="10" ry="10" id="rect231"/>
    316     <text x="70" y="18" text-anchor="middle" font-size="12px" id="text233">csi param</text>
    317     <line class="statesep" x1="10" y1="24" x2="130" y2="24" id="line235"/>
    318     <text x="10" y="35" font-size="8px" id="text243"><tspan x="10" dy="0" id="tspan237">event 00-17,19,1C-1F / execute</tspan><tspan x="10" dy="9" id="tspan239">event 30-39,3B / param</tspan><tspan x="10" dy="9" id="tspan241">event 7F / ignore</tspan></text>
    319   </g>
    320   <line class="interstate" x1="321" y1="446" x2="249" y2="188" marker-end="url(#Arrow2Lend)" id="line246"/>
    321   <text id="legend-csi-param-to-ground" style="font-size:12px" x="309.69904" y="375.69104"><tspan id="tspan248">40-7E / csi_dispatch</tspan></text>
    322   <line class="interstate" x1="337" y1="518" x2="200" y2="809" marker-end="url(#Arrow2Lend)" id="line251"/>
    323   <text id="legend-csi-param-to-csi-inter" style="font-size:12px" x="218.985359" y="589.857538"><tspan id="tspan253">20-2F / collect</tspan></text>
    324   <path id="path-csi-param-to-csi-ignore" class="interstate" style="fill:none;fill-rule:evenodd;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow2L);" d="M 372,629 L 372,516"/>
    325   <text id="legend-csi-param-to-csi-ignore" style="font-size:12px" x="381.618172" y="590.490350"><tspan id="tspan257">3A,3C-3F</tspan></text>
    326   <!-- csi intermediate -->
    327   <g id="state-csi-intermediate" class="state" transform="translate(109,819)">
    328     <rect x="0" y="0" width="140" height="70" rx="10" ry="10" id="rect260"/>
    329     <text x="70" y="18" text-anchor="middle" font-size="12px" id="text262">csi intermediate</text>
    330     <line class="statesep" x1="10" y1="24" x2="130" y2="24" id="line264"/>
    331     <text x="10" y="35" font-size="8px" id="text272"><tspan x="10" dy="0" id="tspan266">event 00-17,19,1C-1F / execute</tspan><tspan x="10" dy="9" id="tspan268">event 20-2F / collect</tspan><tspan x="10" dy="9" id="tspan270">event 7F / ignore</tspan></text>
    332   </g>
    333   <!-- csi ignore -->
    334   <g id="state-csi-ignore" class="state" transform="translate(310,639)">
    335     <rect x="0" y="0" width="140" height="70" rx="10" ry="10" id="rect275"/>
    336     <text x="70" y="18" text-anchor="middle" font-size="12px" id="text277">csi ignore</text>
    337     <line class="statesep" x1="10" y1="24" x2="130" y2="24" id="line279"/>
    338     <text x="10" y="35" font-size="8px" id="text285"><tspan x="10" dy="0" id="tspan281">event 00-17,19,1C-1F / execute</tspan><tspan x="10" dy="9" id="tspan283">event 20-3F,7F / ignore</tspan></text>
    339   </g>
    340   <path id="path-csi-ignore-to-ground" class="interstate" style="marker-start:url(#Arrow2L)" d="M 380,744 L 380,709"/>
    341   <text id="legend-csi-ignore-to-ground" font-size="12px" x="384" y="724"><tspan id="tspan289">40-7E</tspan></text>
    342   <g id="csi-ignore-to-ground" transform="translate(345,754)">
    343     <rect class="stateboxdup" x="0" y="0" width="70" height="35" ry="7" rx="7" id="rect292"/>
    344     <text x="35" y="20" font-size="12px" text-anchor="middle" id="text294">ground</text>
    345   </g>
    346   <!-- dcs entry -->
    347   <g id="anywhere-to-dcs-entry" transform="translate(1015,314)">
    348     <rect class="stateboxdup" x="0" y="0" width="70" height="35" ry="7" rx="7" id="rect297"/>
    349     <text x="35" y="20" font-size="12px" text-anchor="middle" id="text299">anywhere</text>
    350   </g>
    351   <line class="interstate" x1="1050" y1="349" x2="1050" y2="394" marker-end="url(#Arrow2Lend)" id="line302"/>
    352   <text id="legend-anywhere-to-dcs-entry" style="font-size:12px" x="1054" y="364"><tspan id="tspan304">90</tspan></text>
    353   <g id="state-dcs-entry" class="state" transform="translate(980,394)">
    354     <rect x="0" y="0" width="140" height="70" rx="10" ry="10" id="rect307"/>
    355     <text x="70" y="18" text-anchor="middle" font-size="12px" id="text309">dcs entry</text>
    356     <line class="statesep" x1="10" y1="24" x2="130" y2="24" id="line311"/>
    357     <text x="10" y="35" font-size="8px" id="text319"><tspan x="10" dy="0" id="tspan313">entry / clear</tspan><tspan x="10" dy="9" id="tspan315">event 00-17,19,1C-1F / ignore</tspan><tspan x="10" dy="9" id="tspan317">event 7F / ignore</tspan></text>
    358   </g>
    359   <!-- dcs param -->
    360   <g id="state-dcs-param" class="state" transform="translate(1023,734)">
    361     <rect x="0" y="0" width="140" height="70" rx="10" ry="10" id="rect322"/>
    362     <text x="70" y="18" text-anchor="middle" font-size="12px" id="text324">dcs param</text>
    363     <line class="statesep" x1="10" y1="24" x2="130" y2="24" id="line326"/>
    364     <text x="10" y="35" font-size="8px" id="text334"><tspan x="10" dy="0" id="tspan328">event 00-17,19,1C-1F / ignore</tspan><tspan x="10" dy="9" id="tspan330">event 30-39,3B / param</tspan><tspan x="10" dy="9" id="tspan332">event 7F / ignore</tspan></text>
    365   </g>
    366   <!-- dcs intermediate -->
    367   <g id="state-dcs-intermediate" class="state" transform="translate(1293,393)">
    368     <rect x="0" y="0" width="140" height="70" rx="10" ry="10" id="rect337"/>
    369     <text x="70" y="18" text-anchor="middle" font-size="12px" id="text339">dcs intermediate</text>
    370     <line class="statesep" x1="10" y1="24" x2="130" y2="24" id="line341"/>
    371     <text x="10" y="35" font-size="8px" id="text349"><tspan x="10" dy="0" id="tspan343">event 00-17,19,1C-1F / ignore</tspan><tspan x="10" dy="9" id="tspan345">event 20-2F / collect</tspan><tspan x="10" dy="9" id="tspan347">event 7F / ignore</tspan></text>
    372   </g>
    373   <!-- dcs ignore -->
    374   <g id="state-dcs-ignore" class="state" transform="translate(1161,559)">
    375     <rect x="0" y="0" width="140" height="70" rx="10" ry="10" id="rect352"/>
    376     <text x="70" y="18" font-size="12px" text-anchor="middle" id="text354">dcs ignore</text>
    377     <line class="statesep" x1="10" y1="24" x2="130" y2="24" id="line356"/>
    378     <text x="10" y="35" font-size="8px" id="text360"><tspan x="10" dy="0" id="tspan358">event 00-17,19,1C-1F,20-7F / ignore</tspan></text>
    379   </g>
    380   <line class="interstate" x1="1231" y1="629" x2="1231" y2="674" marker-end="url(#Arrow2Lend)" id="line363"/>
    381   <text id="legend-dcs-ignore-to-ground" style="font-size:12px" x="1235" y="644"><tspan id="tspan365">9C</tspan></text>
    382   <g id="dcs-ignore-to-ground" transform="translate(1196,674)">
    383     <rect class="stateboxdup" x="0" y="0" width="70" height="35" ry="7" rx="7" id="rect368"/>
    384     <text x="35" y="20" font-size="12px" text-anchor="middle" id="text370">ground</text>
    385   </g>
    386   <!-- dcs passthrough -->
    387   <g id="state-dcs-passthrough" class="state" transform="translate(1300,863)">
    388     <rect x="0" y="0" width="140" height="70" rx="10" ry="10" id="rect373"/>
    389     <text x="70" y="18" font-size="12px" text-anchor="middle" id="text375">dcs passthrough</text>
    390     <line class="statesep" x1="10" y1="24" x2="130" y2="24" id="line377"/>
    391     <text x="10" y="35" font-size="8px" id="text387"><tspan x="10" dy="0" id="tspan379">entry / hook</tspan><tspan x="10" dy="9" id="tspan381">event 00-17,19,1C-1F,20-7E / put</tspan><tspan x="10" dy="9" id="tspan383">event 7F / ignore</tspan><tspan x="10" dy="9" id="tspan385">exit / unhook</tspan></text>
    392   </g>
    393   <line class="interstate" x1="1370" y1="933" x2="1370" y2="978" marker-end="url(#Arrow2Lend)" id="line390"/>
    394   <text id="legend-dcs-pass-to-ground" style="font-size:12px;" x="1374" y="948"><tspan id="tspan392">9C</tspan></text>
    395   <g id="dcs-pass-to-ground" transform="translate(1335,978)">
    396     <rect class="stateboxdup" x="0" y="0" width="70" height="35" ry="7" rx="7" id="rect395"/>
    397     <text x="35" y="20" font-size="12px" text-anchor="middle" id="text397">ground</text>
    398   </g>
    399   <!-- osc string -->
    400   <g id="anywhere-to-osc-string" transform="translate(804,552)">
    401     <rect class="stateboxdup" x="0" y="0" width="70" height="35" ry="7" rx="7" id="rect400"/>
    402     <text x="35" y="20" font-size="12px" text-anchor="middle" id="text402">anywhere</text>
    403   </g>
    404   <line class="interstate" x1="839" y1="587" x2="839" y2="632" marker-end="url(#Arrow2Lend)" id="line405"/>
    405   <text x="843" y="602" font-size="12px" id="text409"><tspan id="tspan407">9D</tspan></text>
    406   <g id="state-osc-string" class="state" transform="translate(769,632)">
    407     <rect x="0" y="0" width="140" height="70" rx="10" ry="10" id="rect411"/>
    408     <line class="statesep" x1="10" y1="24" x2="130" y2="24"/>
    409     <text text-anchor="middle" font-size="12px" x="70" y="18" id="text415">osc string</text>
    410     <text font-size="8px" text-anchor="start" x="10" y="35" id="text425"><tspan x="10" dy="0" id="tspan417">entry / osc_start</tspan><tspan x="10" dy="9" id="tspan419">event 00-17,19,1C-1F / ignore</tspan><tspan x="10" dy="9" id="tspan421">event 20-7F / osc_put</tspan><tspan x="10" dy="9" id="tspan423">exit / osc_end</tspan></text>
    411   </g>
    412   <line class="interstate" x1="839" y1="702" x2="839" y2="747" marker-end="url(#Arrow2Lend)" id="line428"/>
    413   <text x="843" y="717" font-size="12px" id="text432"><tspan id="tspan430">9C</tspan></text>
    414   <g id="osc-to-ground" transform="translate(804,747)">
    415     <rect class="stateboxdup" x="0" y="0" width="70" height="35" ry="7" rx="7" id="rect434"/>
    416     <text x="35" y="20" font-size="12px" text-anchor="middle" id="text436">ground</text>
    417   </g>
    418   <!-- sos/pm/apc string -->
    419   <g id="anywhere-to-sos" transform="translate(944,42)">
    420     <rect class="stateboxdup" x="0" y="0" width="70" height="35" ry="7" rx="7" id="rect439"/>
    421     <text x="35" y="20" font-size="12px" text-anchor="middle" id="text441">anywhere</text>
    422   </g>
    423   <line class="interstate" x1="979" y1="77" x2="979" y2="122" marker-end="url(#Arrow2Lend)" id="line444"/>
    424   <text id="legend-anywhere-to-sos" style="font-size:12px;" x="983" y="92"><tspan id="tspan446">98,9E,9F</tspan></text>
    425   <g id="state-sos" class="state" transform="translate(909,122)">
    426     <rect x="0" y="0" width="140" height="70" rx="10" ry="10" id="rect449"/>
    427     <line class="statesep" x1="10" y1="24" x2="130" y2="24"/>
    428     <text x="70" y="18" font-size="12px" text-anchor="middle" id="text453">sos/pm/apc string</text>
    429     <text x="10" y="35" font-size="8px" id="text457"><tspan id="tspan455">event 00-17,19,1C-1F,20-7F / ignore</tspan></text>
    430   </g>
    431   <line class="interstate" x1="979" y1="192" x2="979" y2="237" marker-end="url(#Arrow2Lend)" id="line460"/>
    432   <text x="983" y="207" font-size="12px" id="text464"><tspan id="tspan462">9C</tspan></text>
    433   <g id="sos-to-ground" transform="translate(944,237)">
    434     <rect class="stateboxdup" x="0" y="0" width="70" height="35" ry="7" rx="7" id="rect466"/>
    435     <text x="35" y="20" font-size="12px" text-anchor="middle" id="text468">ground</text>
    436   </g>
    437 </svg>
    438 
    439 <p>The UML State Diagram should be readable to anyone who has seen a picture of a state machine
    440 before, but here are some notes on reading it.</p>
    441 <ul>
    442 <li><p>Rounded boxes are <dfn>states</dfn>. A horizontal line separates the name of the state
    443 from the event list. The event list contains several event/action pairs, as shown below.</p>
    444 <p class="example">entry / osc_start<br/>
    445 event 01-17,19,1C-1F / ignore<br/>
    446 event 20-7F / osc_put<br/>
    447 exit / osc_end</p>
    448 <p>The <em>entry</em> event happens when a state is first entered. The <em>events</em>
    449 list incoming symbols which cause an action to take place while remaining in that state.
    450 The action associated with the <em>exit</em> event happens when an incoming symbol
    451 causes a transition from this state to another state (or even back to the same state). When going
    452 from one state to another, the actions take place in this order:</p>
    453 <ol>
    454 <li><em>exit</em> action from old state</li>
    455 <li>transition action</li>
    456 <li><em>entry</em> action to new state</li>
    457 </ol></li>
    458 <li><p>States with grey backgrounds are duplicates of a state described more fully
    459 somewhere else on the diagram. They are present to prevent too many lines crossing. Transitions shown
    460 with grey lines serve as reminders that certain events cause a change of state from anywhere.</p></li>
    461 <li><p>All events in this diagram are the hex values of the incoming bytes. Although we are used to presenting
    462 sequences in the form <code>ESC [ 3 m</code> for readability, using hex values instead of ASCII
    463 characters emphasises that these sequences are not dependent on the character encoding in use.</p></li>
    464 <li><p>Section numbers (e.g. §3.5.6) refer to ANSI X3.64.</p></li>
    465 <li><p>There are no explicit actions shown for incoming codes in the GR area (A0-FF). In all states, these
    466 codes are treated identically to GL codes 20-7F. This behaviour is suggested in Appendix H of X3.64:</p>
    467 <blockquote class="xstd">
    468 <p>In an 8-bit code, the bit
    469 combinations of columns 10 to 15
    470 (except 10/0 and 15/15) are permitted
    471 to represent:</p>
    472 <ul>
    473 <li>parameters, intermediates, and
    474     finals of a control sequence;</li>
    475 <li>the contents of a control
    476     string;</li>
    477 <li>the operand of a single-shift
    478     character.</li>
    479 </ul>
    480 <p>In these situations, the bit
    481 combinations in the range 10/1 to
    482 15/14 have the same meanings as the
    483 corresponding bit combinations in
    484 the range 2/1 to 7/14.</p>
    485 </blockquote></li>
    486 </ul>
    487 <h2 id="STATES">State Definitions</h2>
    488 <dl>
    489 <dt id="STGRO">ground</dt>
    490 <dd><p>This is the initial state of the parser, and the state used to consume all characters other than components of
    491 escape and control sequences.</p>
    492 <p>GL characters (20 to 7F) are printed. I have included 20 (SP) and 7F (DEL) in this area, although both
    493 codes have special behaviour. If a 94-character set is mapped into GL, 20 will cause a space to be displayed,
    494 and 7F will be ignored. When a 96-character set is mapped into GL, both 20 and 7F may cause a character
    495 to be displayed. Later models of the VT220 included the DEC Multinational Character Set (MCS), which has 94
    496 characters in its supplemental set (i.e. the characters supplied in addition to ASCII), so terminals only
    497 claiming VT220 compatibility can always ignore 7F. The VT320 introduced ISO Latin-1, which has 96 characters
    498 in its supplemental set, so emulators with a VT320 compatibility mode need to treat 7F as a printable character.</p></dd>
    499 <dt id="STESC">escape</dt>
    500 <dd><p>This state is entered whenever the C0 control ESC is received. This will immediately cancel any
    501 escape sequence, control sequence or control string in progress. If an escape sequence or control sequence
    502 was in progress, “cancel” means that the sequence will have no effect, because the final character that
    503 determines the control function (in conjunction with any intermediates) will not have been received.
    504 However, the ESC that cancels a control string may occur after the control function has been determined
    505 and the following string has had some effect on terminal state. For example, some soft characters may already
    506 have been defined. Cancelling a control string does not undo these effects.</p>
    507 <p>A control string that started with DCS, OSC, PM or APC is usually terminated by the C1 control ST
    508 (String Terminator). In a 7-bit environment, ST will be represented by <code>ESC \</code> (1B 5C).
    509 However, receiving the ESC character will “cancel” the control string, so the ST control function that is
    510 invoked by the arrival of the following “\” is essentially a “no-op” function. Does this point seem like
    511 pure trivia? Maybe, but I worried for ages about whether the control string recogniser needed a one character
    512 lookahead in order to know whether <code>ESC \</code> was going to terminate it. The actual solution
    513 became clear when I was using ReGIS on a VT330: sending ESC immediately caused the graphics output cursor
    514 to disappear from the screen, so I knew that the control string had already finished before the “\” arrived.
    515 Many of the clues that enabled me to derive this state diagram have been as subtle as that.</p></dd>
    516 <dt id="STESCINT">escape intermediate</dt>
    517 <dd><p>This state is entered when an intermediate character arrives in an escape sequence. Escape sequences
    518 have no parameters, so the control function to be invoked is determined by the intermediate and final
    519 characters. In this parser there is just one <em>escape intermediate</em>, and the parser uses the <a href="#ACCOL"><em>collect</em></a>
    520 action to remember intermediate characters as they arrive, for processing by the <a href="#ACESCDIS"><em>esc_dispatch</em></a> action
    521 when the final character arrives. An alternate approach (and the one adopted by <span class="tt">xterm</span>) is to have
    522 multiple copies of this state and choose the next appropriate one as each intermediate character arrives.
    523 I think that this alternate approach is merely an optimisation; the approach presented here doesn’t require
    524 any more states if the repertoire of supported control functions increases.</p>
    525 <p>This state is only split from the <a href="#STESC"><em>escape</em></a> state because certain escape sequences are the 7-bit
    526 representations of C1 controls that change the state of the parser. Without these “compatibility sequences”,
    527 there could just be one escape state to collect intermediates and dispatch the sequence when a final character
    528 was received.</p></dd>
    529 <dt id="STCSIENT">csi entry</dt>
    530 <dd><p>This state is entered when the control function CSI is recognised, in 7-bit or 8-bit form. This state
    531 will only deal with the
    532 first character of a control sequence, because the characters 3C-3F can only appear as the first character
    533 of a control sequence, if they appear at all. Strictly speaking, X3.64 says that the entire string is “subject
    534 to private or experimental interpretation” if the first character is one of 3C-3F, which allows sequences like <code>CSI ?::&lt;? F</code>, but Digital’s
    535 terminals only ever used one private-marker character at a time. As far as I am aware, only characters 3D (=), 3E (&gt;) and 3F (?) were
    536 used by Digital.</p>
    537 <p>C0 controls are executed immediately during the recognition of a control sequence. C1 controls will cancel
    538 the sequence and then be executed. I imagine this treatment of C1 controls is prompted by the consideration that the 7-bit (ESC Fe) and
    539 8-bit representations of C1 controls should act in the same way. When the first character of the 7-bit representation, ESC,
    540 is received, it will cancel the control sequence, so the 8-bit representation should do so as well.</p></dd>
    541 <dt id="STCSIPAR">csi param</dt>
    542 <dd><p>This state is entered when a parameter character is recognised in a control sequence. It then
    543 recognises other parameter characters until an intermediate or final character appears. Further occurrences
    544 of the private-marker characters 3C-3F or the character 3A, which has no standardised meaning, will cause
    545 transition to the <a href="#STCSIIGN"><em>csi ignore</em></a> state.</p></dd>
    546 <dt id="STCSIINT">csi intermediate</dt>
    547 <dd><p>This state is entered when an intermediate character is recognised in a control sequence. It then
    548 recognises other intermediate characters until a final character appears. If any more parameter characters
    549 appear, this is an error condition which will cause a transition to the <a href="#STCSIIGN"><em>csi ignore</em></a> state.</p>
    550 <p>Neither X3.64 nor Digital defined any control sequences with more than one intermediate character, although X3.64
    551 doesn’t place any limit on the possible number.</p></dd>
    552 <dt id="STCSIIGN">csi ignore</dt>
    553 <dd><p>This state is used to consume remaining characters of a control sequence that is still being
    554 recognised, but has already been disregarded as malformed. This state will only exit when a final character
    555 is recognised, at which point it transitions to <a href="#STGRO"><em>ground</em></a> state without dispatching the control
    556 function. This state may be entered because:</p>
    557 <ol>
    558 <li>a private-marker character 3C-3F is recognised in any place other than the first character of the control sequence,</li>
    559 <li>the character 3A appears anywhere, or</li>
    560 <li>a parameter character 30-3F occurs after an intermediate character has been recognised.</li>
    561 </ol>
    562 <p>C0 controls will still be executed while a control sequence is being ignored.</p></dd>
    563 <dt id="STDCSENT">dcs entry</dt>
    564 <dd><p>This state is entered when the control function DCS is recognised, in 7-bit or 8-bit form. X3.64 doesn’t define
    565 any structure for device control strings, but Digital made them appear like control sequences followed by a data
    566 string, with a form and length dependent on the control function. This state is only used to recognise
    567 the first character of the control string, mirroring the <a href="#STCSIENT"><em>csi entry</em></a> state.</p>
    568 <p>C0 controls other than CAN, SUB and ESC are <strong>not</strong> executed while recognising the first part of a device control string.</p></dd>
    569 <dt id="STDCSPAR">dcs param</dt>
    570 <dd><p>This state is entered when a parameter character is recognised in a device control string. It then
    571 recognises other parameter characters until an intermediate or final character appears. Occurrences of the
    572 private-marker characters 3C-3F or the undefined character 3A will cause a transition to the <a href="#STDCSIGN"><em>dcs ignore</em></a>
    573 state.</p></dd>
    574 <dt id="STDCSINT">dcs intermediate</dt>
    575 <dd><p>This state is entered when an intermediate character is recognised in a device control string. It
    576 then recognises other intermediate characters until a final character appears. If any more parameter
    577 characters appear, this is an error condition which will cause a transition to the <a href="#STDCSIGN"><em>dcs ignore</em></a> state.</p></dd>
    578 <dt id="STDCSPAS">dcs passthrough</dt>
    579 <dd><p>This state is a shortcut for writing state machines for all possible device control strings into the
    580 main parser. When a final character has been recognised in a device control string, this state will establish
    581 a channel to a handler for the appropriate control function, and then pass all subsequent characters through
    582 to this alternate handler, until the data string is terminated (usually by recognising the ST control function).</p>
    583 <p>This state has an exit action so that the control function handler can be informed when the data string has
    584 come to an end. This is so that the last soft character in a DECDLD string can be completed when there is no other means
    585 of knowing that its definition has ended, for example.</p></dd>
    586 <dt id="STDCSIGN">dcs ignore</dt>
    587 <dd><p>This state is used to consume remaining characters of a device control string that is still being
    588 recognised, but has already been disregarded as malformed. This state will only exit when the control function
    589 ST is recognised, at which point it transitions to <a href="#STGRO"><em>ground</em></a> state. This state may be entered because:</p>
    590 <ol>
    591 <li>a private-marker character 3C-3F is recognised in any place other than the first character of the control string,</li>
    592 <li>the character 3A appears anywhere, or</li>
    593 <li>a parameter character 30-3F occurs after an intermediate character has been recognised.</li>
    594 </ol>
    595 <p>These conditions are only errors in the first part of the control string, until a final character has
    596 been recognised. The data string that follows is not checked by this parser.</p></dd>
    597 <dt id="STOSCSTR">osc string</dt>
    598 <dd><p>This state is entered when the control function OSC (Operating System Command) is recognised.
    599 On entry it prepares an external parser for OSC strings and passes all printable characters to a handler
    600 function. C0 controls other than CAN, SUB and ESC are ignored during reception of the control string.</p>
    601 <p>The only control functions invoked by OSC strings are DECSIN (Set Icon Name) and DECSWT (Set Window Title),
    602 present on the multisession VT520 and VT525 terminals. Earlier terminals treat OSC in the same way as PM and APC, ignoring the
    603 entire control string.</p></dd>
    604 <dt id="STSOS">sos/pm/apc string</dt>
    605 <dd><p>The VT500 doesn’t define any function for these control strings, so this state ignores all
    606 received characters until the control function ST is recognised.</p></dd>
    607 <dt id="STANY">anywhere</dt>
    608 <dd><p>This isn’t a real state. It is used on the state diagram to show transitions that can occur
    609 from any state to some other state. These invariant transitions are:</p>
    610 <ul>
    611 <li><p>On the VT220, VT420 and VT500, the C0 controls CAN and SUB cancel any escape sequence, control sequence or
    612 control string in progress and return to ground state. SUB will also display the error character, a reversed
    613 question mark, “␦”. The programmer’s information for the VT320 says that CAN and SUB “no longer” cancel these
    614 sequences, so there must have been a rethink when the VT420 was being designed.</p></li>
    615 <li><p>All C1 controls cancel any escape sequence, control sequence or
    616 control string in progress and are executed. Control functions special to this parser, i.e. DCS, SOS, CSI, OSC, PM and APC, cause
    617 a transition to their appropriate states. All other C1 control functions (even those with no defined meaning), cause a
    618 transition to <a href="#STGRO"><em>ground</em></a> state.</p></li>
    619 </ul>
    620 <p>On terminals earlier than the VT500, there would have been one other invariant action: the C0 control NUL
    621 was ignored on input to the terminal and would not take part in any processing. Its only purpose was as a
    622 time-fill character. However, the VT500 defines a control function DECNULM (Null Mode), which allows NUL to
    623 be passed to an attached printer. So in this parser, NUL is treated the same as other C0 controls.</p></dd>
    624 </dl>
    625 <h2 id="ACTIONS">Action Definitions</h2>
    626 <p>An event may cause one of these actions to occur with or without a change of state.</p>
    627 <dl>
    628 <dt id="ACIGN">ignore</dt>
    629 <dd><p>The character or control is not processed. No observable difference in the terminal’s state would
    630 occur if the character that caused this action was not present in the input stream. (Therefore, this action can only occur within a state.)</p></dd>
    631 <dt id="ACPRI">print</dt>
    632 <dd><p>This action only occurs in <a href="#STGRO"><em>ground</em></a> state. The current code should be mapped to a glyph
    633 according to the character set mappings and shift states in effect, and that glyph should be displayed. 20 (SP) and 7F (DEL) have special
    634 behaviour in later VT series, as described in <a href="#STGRO"><em>ground</em></a>.</p></dd>
    635 <dt id="ACEXE">execute</dt>
    636 <dd><p>The C0 or C1 control function should be executed, which may have any one of a variety of effects,
    637 including changing the cursor position, suspending or resuming communications or changing the shift states in
    638 effect. There are no parameters to this action.</p></dd>
    639 <dt id="ACRES">clear</dt>
    640 <dd><p>This action causes the current private flag, intermediate characters, final character and parameters to be forgotten. This occurs on entry
    641 to the <a href="#STESC">escape</a>, <a href="#STCSIENT">csi entry</a> and <a href="#STDCSENT">dcs entry</a> states, so that erroneous sequences
    642 like <code>CSI 3 ; 1 CSI 2 J</code> are handled correctly.</p></dd>
    643 <dt id="ACCOL">collect</dt>
    644 <dd><p>The private marker or intermediate character should be stored for later use in selecting a control
    645 function to be executed when a final character arrives. X3.64 doesn’t place any limit on the number of
    646 intermediate characters allowed before a final character, although it doesn’t define any control sequences
    647 with more than one. Digital defined escape sequences with two intermediate characters, and
    648 control sequences and device control strings with one. If more than two intermediate characters arrive, the
    649 parser can just flag this so that the dispatch can be turned into a null operation.</p></dd>
    650 <dt id="ACPAR">param</dt>
    651 <dd><p>This action collects the characters of a parameter string for a control sequence or device control sequence
    652 and builds a list of parameters. The characters processed by this action are the digits 0-9 (codes 30-39) and
    653 the semicolon (code 3B). The semicolon separates parameters. There is no limit to the number of characters
    654 in a parameter string, although a maximum of 16 parameters need be stored. If more than 16 parameters arrive,
    655 all the extra parameters are silently ignored.</p>
    656 <p>The VT500 Programmer Information is inconsistent regarding the maximum value that a parameter can take. In
    657 section 4.3.3.2 of EK-VT520-RM it says that “any parameter greater than 9999 (decimal) is set to 9999 (decimal)”.
    658 However, in the description of DECSR (Secure Reset), its parameter is allowed to range from 0 to 16383. Because individual
    659 control functions need to make sure that numeric parameters are within specific limits,
    660 the supported maximum is not critical, but it must be at least 16383.</p>
    661 <p>Most control functions support default values for their parameters. The default value for a parameter is
    662 given by either leaving the parameter blank, or specifying a value of zero. Judging by previous threads on the
    663 newsgroup <a href="news:comp.terminals">comp.terminals</a>, this causes some confusion, with the occasional
    664 assertion that zero is the default parameter value for control functions. This is not the case: many control
    665 functions have a default value of 1, one (GSM) has a default value of 100, and some have no default. However,
    666 in all cases the default value is <em>represented</em> by either zero or a blank value.</p>
    667 <p>In the standard ECMA-48, which can be considered X3.64’s successor<a href="#FOOTECMA48">²</a>,
    668 there is a distinction between a parameter with an empty value (representing the default value), and one
    669 that has the value zero. There used to be a mode, ZDM (Zero Default Mode), in which the two cases were treated identically,
    670 but that is now deprecated in the fifth edition (1991). Although a VT500 parser needs to treat both empty and zero
    671 parameters as representing the default, it is worth considering future extensions by distinguishing them internally.</p></dd>
    672 <dt id="ACESCDIS">esc_dispatch</dt>
    673 <dd><p>The final character of an escape sequence has arrived, so determined the control function to be executed
    674 from the intermediate character(s) and final character, and execute it. The intermediate characters are available
    675 because <a href="#ACCOL"><em>collect</em></a> stored them as they arrived.</p></dd>
    676 <dt id="ACCSIDIS">csi_dispatch</dt>
    677 <dd><p>A final character has arrived, so determine the control function to be executed from private marker,
    678 intermediate character(s) and final character, and execute it, passing in the parameter list. The private marker and intermediate characters are
    679 available because <a href="#ACCOL"><em>collect</em></a> stored them as they arrived.</p>
    680 <p>Digital mostly used private markers to extend the parameters of existing X3.64-defined control functions,
    681 while keeping a similar meaning. A few examples are shown in the table below.</p>
    682 <table class="major">
    683 <thead>
    684 <tr>
    685 <th>No Private Marker</th>
    686 <th>With Private Marker</th>
    687 </tr>
    688 </thead>
    689 <tbody>
    690 <tr>
    691 <td>SM, Set ANSI Modes</td>
    692 <td>SM, Set Digital Private Modes</td>
    693 </tr>
    694 <tr>
    695 <td>ED, Erase in Display</td>
    696 <td>DECSED, Selective Erase in Display</td>
    697 </tr>
    698 <tr>
    699 <td>CPR, Cursor Position Report</td>
    700 <td>DECXCPR, Extended Cursor Position Report</td>
    701 </tr>
    702 </tbody>
    703 </table>
    704 <p>In the cases above, <em>csi_dispatch</em> needn’t know about the private marker at all, as long as it is
    705 passed along to the control function when it is executed. However, the VT500 has a single case where
    706 the use of a private marker selects an entirely different control function (DECSTBM, Set Top and Bottom
    707 Margins and DECPCTERM, Enter/Exit PCTerm or Scancode Mode), so this action needs to use the private
    708 marker in its choice. <span class="tt">xterm</span> takes the same approach for efficiency, even though it doesn’t
    709 support DECPCTERM.</p>
    710 <p>The selected control function will have access to the list of parameters, which it will use some or all
    711 of. If more parameters are supplied than the control function requires, only the earliest parameters will be
    712 used and the rest will be ignored. If too few parameters are supplied, default values will be used. If the
    713 control function has no default values, defaulted parameters will be ignored; this may result in the control
    714 function having no effect. For example, if the SM (Set Mode)
    715 control function is invoked with the sequence <code>CSI 2;0;5 h</code>, the second parameter will be ignored because
    716 SM has no default value.</p></dd>
    717 <dt id="ACHOO">hook</dt>
    718 <dd><p>This action is invoked when a final character arrives in the first part of a device control string.
    719 It determines the control function from the private marker, intermediate character(s) and final character,
    720 and executes it, passing in the parameter list. It also selects a handler function for the rest of the
    721 characters in the control string. This handler function will be called by the <a href="#ACPUT"><em>put</em></a> action for every
    722 character in the control string as it arrives.</p>
    723 <p>This way of handling device control strings has been selected because it allows the simple plugging-in of
    724 extra parsers as functionality is added. Support for a fairly simple control string like DECDLD (Downline Load) could be
    725 added into the main parser if soft characters were required, but the main parser is no place for complicated
    726 protocols like ReGIS.</p></dd>
    727 <dt id="ACPUT">put</dt>
    728 <dd><p>This action passes characters from the data string part of a device control string to a handler that
    729 has previously been selected by the <a href="#ACHOO"><em>hook</em></a> action. C0 controls are also passed to the handler.</p></dd>
    730 <dt id="ACUNH">unhook</dt>
    731 <dd><p>When a device control string is terminated by ST, CAN, SUB or ESC, this action calls the previously
    732 selected handler function with an “end of data” parameter. This allows the handler to finish neatly.</p></dd>
    733 <dt id="ACOSCSTA">osc_start</dt>
    734 <dd><p>When the control function OSC (Operating System Command) is recognised, this action initializes an
    735 external parser (the “OSC Handler”) to handle the characters from the control string. OSC control strings are not structured
    736 in the same way as device control strings, so there is no choice of parsers.</p></dd>
    737 <dt id="ACOSCPUT">osc_put</dt>
    738 <dd><p>This action passes characters from the control string to the OSC Handler as they arrive. There is
    739 therefore no need to buffer characters until the end of the control string is recognised.</p></dd>
    740 <dt id="ACOSCEND">osc_end</dt>
    741 <dd><p>This action is called when the OSC string is terminated by ST, CAN, SUB or ESC, to allow the OSC handler
    742 to finish neatly.</p></dd>
    743 </dl>
    744 <h2 id="GAPS">What X3.64 Doesn’t Say</h2>
    745 <p>As I said above, X3.64 deliberately leaves some decisions to implementers. It doesn’t define recovery
    746 from error conditions, and some limits are implementation dependent. The following sections define
    747 DEC’s method of coping with all of these sections of the standard.</p>
    748 <ul>
    749 <li><p><strong>X3.64:</strong> <cite>§2.2.3 Classes of Bit Combinations</cite></p>
    750 <blockquote class="xstd">
    751 <p>Example: The format of an Escape sequence
    752 as defined in ANSI X3.41-1974 and used in
    753 this standard is:</p>
    754 <pre>     ESC I...I F</pre>
    755 <span class="ellipsis">[...]</span>
    756 <p>(4) <span class="hilite">The occurrence of characters in the
    757 inclusive ranges of 0/0 to 1/15 and 7/15
    758 to 15/15 is an error condition whose
    759 recovery is not specified.</span></p>
    760 </blockquote>
    761 <p><strong>DEC:</strong> The C0 controls 00-1F are executed, 7F is ignored, C1 controls 80-9F are executed (cancelling the escape
    762 sequence) and
    763 GR codes A0-FF are treated as GL codes 20-7F.</p></li>
    764 <li><p><strong>X3.64:</strong> <cite>§3.2.1 Software Control Strings</cite></p>
    765 <blockquote class="xstd">
    766 <p>The opening delimiters for the
    767 software strings are:</p>
    768 <table class="emb">
    769 <tbody>
    770 <tr>
    771 <td style="text-align:center">Name</td>
    772 <td>Mnemonic</td>
    773 </tr>
    774 <tr>
    775 <td>Operating System Command</td>
    776 <td>OSC</td>
    777 </tr>
    778 <tr>
    779 <td>Privacy Message</td>
    780 <td>PM</td>
    781 </tr>
    782 <tr>
    783 <td>Application Program Command</td>
    784 <td>APC</td>
    785 </tr>
    786 </tbody>
    787 </table>
    788 <p>The string is terminated by the occurrence
    789 of a String Terminator (see 3.2.3). <span class="hilite">The
    790 occurrence of other control characters
    791 and/or characters from columns 10 to 15
    792 within such a string are error conditions
    793 whose recovery is not specified by this
    794 standard.</span></p>
    795 </blockquote>
    796 <p><strong>DEC:</strong> None of Digital’s terminals define any meaning for received Privacy Message or Application
    797 Program Command strings. C0 controls, GL characters and GR characters are ignored. C1 controls
    798 will cancel the sequence.</p>
    799 <p>The VT500 defines two Operating System Commands, DECSIN (Set Icon Name) and DECSWT (Set Window Title).
    800 C0 controls are ignored in these sequences. C1 controls will cancel the sequence.</p></li>
    801 <li><p><strong>X3.64:</strong> <cite>§3.2.2 Device Control Strings</cite></p>
    802 <blockquote class="xstd">
    803 <p>These strings take
    804 the form of the introducer character DCS
    805 followed by one or more bit combinations
    806 representing the function.  These may be
    807 characters from columns 2 to 7, excluding
    808 7/15 (2/0 to 7/14)</p>
    809 <span class="ellipsis">[...]</span>
    810 <p><span class="hilite">The occurrence of
    811 other control characters and/or characters
    812 from columns 10 to 15 within such a string
    813 are error conditions whose recovery is not
    814 specified by this standard.</span></p>
    815 </blockquote>
    816 <p><strong>DEC:</strong> On Digital’s terminals, device control strings have structure
    817 that is not specified by X3.64. The first section of a device control string has the same
    818 structure as a control sequence, up to what would be the final character of a control
    819 sequence. At that point, the device function is determined from the intermediate and
    820 final characters, and the rest of the string has a meaning specific to the selected
    821 device function. In the first section, C0 controls are ignored. In the second section,
    822 C0 controls may or may not have a meaning to the device function. If they have no meaning
    823 for the device function (e.g. when defining soft characters with DECDLD) they will be silently
    824 ignored. If they have a meaning for the device function (e.g. when in ReGIS mode), they will
    825 be acted upon.</p></li>
    826 <li><p><strong>X3.64:</strong> <cite>§3.5 Control Sequence Functions</cite></p>
    827 <blockquote class="xstd">
    828 <p>The general form of a control sequence
    829 function is as follows:</p>
    830 <pre>    CSI P...P I...I F</pre>
    831 <span class="ellipsis">[...]</span>
    832 <p> (2) P...P is called the “parameter
    833 string.” The minimum length is zero, and
    834 <span class="hilite">the maximum length is defined by the
    835 implementation.</span>  However, all bit
    836 combinations are from 3/0 to 3/15
    837 inclusive.</p>
    838 <span class="ellipsis">[...]</span>
    839 <p> (5) <span class="hilite">The occurrence of bit combinations
    840 from columns 0 and 1 (0/0 to 1/15), from
    841 columns 8 to 15 (8/0 to 15/15), or
    842 position 7/15 in control sequences are
    843 error conditions whose recovery is not
    844 specified by this standard.</span></p>
    845 </blockquote>
    846 <p><strong>DEC:</strong> There is no limit to the number of characters in the parameter
    847 string, but a maximum of 16 parameters will be processed. All parameters beyond the 16th will
    848 be silently ignored. In a control sequence the C0 controls 00-1F are executed, 7F is ignored, C1 controls 80-9F are executed
    849 (cancelling the control sequence) and
    850 GR codes A0-FF are treated as GL codes 20-7F.</p></li>
    851 <li><p><strong>X3.64:</strong> <cite>§3.5.1 Parameter Values</cite></p>
    852 <blockquote class="xstd">
    853 <p>The bit combination 3/10 is reserved for
    854 future standardization.</p>
    855 </blockquote>
    856 <p><strong>DEC:</strong> Character 3A (ASCII colon) will cause the control sequence to be ignored,
    857 though <strong>not</strong> cancelled. All characters up to a valid final character will be collected,
    858 but then no action will take place.</p></li>
    859 <li><p><strong>X3.64:</strong> <cite>§3.5.5 Selective Parameters</cite></p>
    860 <blockquote class="xstd">
    861 <p>The maximum number of
    862 parameters in a selective Control Sequence
    863 is implementation-defined, as is the order
    864 of performance and the effect of
    865 conflicting or unusual combinations.</p>
    866 </blockquote>
    867 <p><strong>DEC:</strong> There can be a maximum of 16 parameters in
    868 a control sequence. All parameters beyond the 16th will
    869 be silently ignored. Parameters are processed from first to last, with
    870 conflicts simply resolved by allowing later parameters to override the
    871 effects of earlier ones. This means that the sequence <code>CSI 7;0 m</code>
    872 will not set the reverse video attribute, because the parameter ‘7’ is cancelled
    873 by the ‘0’.</p></li>
    874 <li><p><strong>X3.64:</strong> <cite>§3.5.6 Structure of Control Sequences</cite></p>
    875 <blockquote class="xstd">
    876 <p>For both numeric and selective parameters
    877 the complete control sequence structure
    878 is:</p>
    879 <p> CSI P11...P1m 3/11 P21...P2m 3/11 ... 3/11 Pn1...Pnm I...I F</p>
    880 <p> If P11 is 3/0 to 3/11, inclusive, the
    881 parameter string is interpreted according
    882 to the standard format described below.</p>
    883 <p>If P11 is 3/12 to 3/15, inclusive, the
    884 entire parameter string is subject to
    885 private or experimental interpretation.</p>
    886 <span class="ellipsis">[...]</span>
    887 <p> (2) Px1...Pxm is a numeric or selective
    888 parameter.  Pxy is 3/0 to 3/9 inclusive
    889 for standardized parameters.  <span class="hilite">Occurrences
    890 of 3/12 to 3/15 inclusive are undefined.</span></p>
    891 <span class="ellipsis">[...]</span>
    892 <p>NOTE: <span class="hilite">The occurrence of bit combinations
    893 in the following inclusive ranges: 0/0 to
    894 1/15, or 7/15 to 15/15, or the occurrence
    895 of a P after an I has been encountered is
    896 an error condition whose recovery is not
    897 specified by this standard.</span></p>
    898 </blockquote>
    899 <p><strong>DEC:</strong> Occurrences of 3C to 3F in positions other than
    900 the first character of the parameter string cause the entire control sequence
    901 to be ignored. In a control sequence the C0 controls 00-1F are executed, 7F is ignored, C1 controls 80-9F are executed
    902 (cancelling the control sequence) and
    903 GR codes A0-FF are treated as GL codes 20-7F.</p></li>
    904 </ul>
    905 <h2 id="IMPLEMENTATION">An Implementation</h2>
    906 <p>As of 2005, Josh Haberman has implemented this parser in C and placed it in the public domain.
    907 You will also need Ruby to create the parser tables at compile time. It’s on <a href="https://github.com/haberman/vtparse">GitHub</a>.</p>
    908 <h2 id="QUESTIONS">Any Questions?</h2>
    909 <p>If you have any questions about this document, please send them to me, no matter how trivial you think they are.
    910 Even if the answer is already stated here, it may need clarification (or writing in bigger letters!)
    911 If you try to write the parser for a terminal emulator from this specification and you find you need a leap of logic,
    912 I’ve not done my job properly, and I’d like to hear about it.</p>
    913 <h2 id="FOOTNOTES">Footnotes</h2>
    914 <ol class="footnotes">
    915 <li id="FOOTMATCH"><p>It is debatable how far it is necessary to go with making an emulator match the
    916 error-recovery behaviour of the terminal, for two
    917 reasons. Firstly, for the practical reason that information on error recovery isn’t contained in DEC’s terminal
    918 manuals and discovering it means taking detailed and seemingly-endless notes about the terminal’s
    919 behaviour when certain bizarre sequences are sent to it. (OK, I’ve done that!)</p>
    920 <p>Secondly, how often would erroneous sequences be sent
    921 to the terminal anyway? I would answer this by saying that people who write applications for terminals
    922 don’t always read the manuals and may rely on some observed behaviour of the terminal without realising
    923 that they are seeing the effects of error recovery. It appears to be common knowledge among emulator
    924 writers (<a href="http://groups.google.com/groups?selm=odhghg2ymj.fsf%40donald.xylogics.com">and their critics</a>) that the sequence <code>CSI 2 LF C</code> moves
    925 the cursor two columns right and one row down. How many realise that this behaviour is not specified in
    926 X3.64, but just happens to have been the error recovery chosen by the designers of the VT100?
    927 The lesson I take from this is that if you’re going to emulate a real terminal, you should match
    928 all observable behaviour.</p></li>
    929 <li id="FOOTECMA48"><p>With its first edition having been published in 1976, <a href="http://www.ecma-international.org/publications/standards/Ecma-048.htm">ECMA-48</a> “Control Functions for Coded Character Sets” predates ANSI X3.64
    930 and has been updated for longer. As ECMA make their standards available free of charge, I find
    931 it surprising that anyone ever bothered claiming conformance with ANSI X3.64.</p></li>
    932 </ol>
    933 <footer>
    934 <div class="citation">Citation: Williams, Paul Flo. “A parser for DEC’s ANSI-compatible video terminals.” <i>VT100.net</i>. <a href="https://vt100.net/emu/dec_ansi_parser">https://vt100.net/emu/dec_ansi_parser</a></div>
    935 <!--
    936 <div>Copyright 2002&#x2012;2017 <a href="https://hisdeedsaredust.com">Paul Flo Williams</a>.</div>
    937 <div>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.</div>
    938 <div>[<a href="#CHANGELIST" onclick="document.getElementById('CHANGELIST').style.display='block';return true;">Changed 2017-08-25</a>]</div>
    939 <dl id="CHANGELIST" style="display:none">
    940 <dt class="date">2017-08-25</dt>
    941 <dd class="desc">
    942 <p>I re-read this document for the first time in years and noticed that the SVG version of the parser diagram
    943 was utterly broken, so I’ve reworked it and, in doing so, removed the old PNG export, as I think that
    944 browser support for SVG is now good enough to use directly within this specification.</p>
    945 <p>Minor changes to the diagram:</p>
    946 <ol>
    947 	<li>The “convenience” states now have dashed lines round them, to indicate that they are
    948 		only there to make the diagram clearer.</li>
    949 	<li>I’ve moved all incoming convenience links to the top of states, and outgoing ones to
    950 		the bottom, which makes it look more consistent.</li>
    951 	<li>The convenience state “anywhere” that led directly into “ground” used to be green, but
    952 		that made it look important, as if it was a real state, so I’ve de-emphasised it to match
    953 		the others.</li>
    954 </ol>
    955 </dd>
    956 	<dt class="date">2005-09-13</dt>
    957 	<dd class="desc"><ul>
    958 <li><p>Removed description of sequence type <em>dispatch</em> into <em>esc_dispatch</em> and <em>csi_dispatch</em> to clarify
    959 the different handling of escape and control sequences.</p></li>
    960 <li><p>Added <em>clear</em> action to make it explicit when intermediate characters and parameters are reset.</p></li>
    961 <li><p>Josh has supplied an implementation of this parser, placed in the Public Domain.</p></li>
    962 <li><p>Added one word to “None of Digital’s terminals define any meaning for <ins>received</ins> Privacy Message
    963 or Application Program Command strings” because the VT420 and VT500 Series
    964 can send information on key presses to the host as APC strings.</p></li>
    965 <li><p>Removed the overlap between <em>ground</em> state's internal actions and those that cause a transition from
    966 anywhere to <em>ground</em>.</p></li>
    967 	</ul></dd>
    968 	<dt class="date">2005-09-07</dt>
    969 	<dd class="desc"><ul>
    970 <li><p>Noted that going to <em>ground</em> state causes intermediate characters and numeric parameters to be forgotten.</p></li>
    971 <li><p><em>dispatch</em> needs to know whether the current sequence is an escape sequence or a control sequence, because
    972 <code>ESC <var>Final</var></code> is different from <code>CSI <var>Final</var></code>. Josh suggested separate
    973 <em>esc_dispatch</em> and <em>csi_dispatch</em> actions. This document retains a single <em>dispatch</em> action for both
    974 types of sequence by saying that the current sequence type is remembered on entry to the <em>escape</em> or <em>csi entry</em> states.</p></li>
    975 <li><p>The diagram showed 9C (ST) prompting the <em>execute</em> action in one place, but having no action other than a
    976 transition to <em>ground</em> in all other places. The action has been removed, because there is never any work to do for 9C,
    977 for reasons explained in the description of the <em>escape</em> state.</p></li>
    978 <li><p>Removed the short section which covered some implementation trivia on <span class="tt">xterm</span> and <span class="tt">PuTTY</span> because it
    979 inadvertently gave the impression that this document had somehow influenced the parsers of these emulators. My attempted
    980 rewording to correct this impression was much more verbose than the trivia, so I’ve removed it entirely!</p></li>
    981 </ul>
    982 <p>Thanks to Joshua Haberman for the discussion which prompted the above changes. Some other minor fixes:</p><ul>
    983 <li><p>The state diagram is now maintained with <a href="http://www.inkscape.org/">Inkscape</a> rather than
    984 <a href="http://sodipodi.sourceforge.net/">Sodipodi</a>, because of the former’s support for markers (proper arrow heads!)</p></li>
    985 <li><p>Where actions and states are discussed, their names have been linked to their full descriptions.</p></li>
    986 <li><p>In the description of <em>dcs passthrough</em>, the phrase “soft character in a string” didn't make sense unless you knew
    987 I was taking about the control function DECDLD (Downline Load).</p></li>
    988 <li><p>In <em>ground</em> state, 98 (SOS) was grouped with other C1 controls that had the <em>execute</em> action, when in fact
    989 it causes a transition to <em>sos/pm/apc string</em> state.</p></li>
    990 </ul></dd>
    991 <dt class="date">2003-09-01</dt>
    992 <dd class="desc"><ul>
    993 <li><p>Corrected link to ECMA-48.</p></li>
    994 </ul></dd>
    995 <dt class="date">2003-05-20</dt>
    996 <dd class="desc"><ul>
    997 <li><p>Corrected dcs_intermediate state in diagram, which showed intermediate characters (20-2F) being ignored, when
    998 they should have been collected. Thanks to Jamie Lokier for spotting this.</p></li>
    999 </ul></dd>
   1000 <dt class="date">2002-09-27</dt>
   1001 <dd class="desc"><ul>
   1002 <li><p>Added a new version of the statechart diagram, in SVG format.</p></li>
   1003 <li><p>Corrected description of the chart to mention <em>event</em>, not <em>on</em> actions.</p></li>
   1004 </ul></dd>
   1005 <dt class="date">2002-03-26</dt>
   1006 <dd class="desc"><ul>
   1007 <li>Changed spelling of ‘despatch’ to more common ‘dispatch’.</li>
   1008 <li><p>In the description of the state <em>csi entry</em>, amended</p>
   1009 <blockquote>
   1010 <p>As far as I am aware, only characters 3C (&lt;), 3E (&gt;) and 3F (?) were
   1011 used by Digital; 3D (=) was used by other terminal manufacturers.</p>
   1012 </blockquote>
   1013 <p>to</p>
   1014 <blockquote>
   1015 <p>As far as I am aware, only characters 3D (=), 3E (&gt;) and 3F (?) were
   1016 used by Digital.</p>
   1017 </blockquote>
   1018 <p>3C (&lt;) may have been used by other manufacturers, but I can’t be bothered to find
   1019 examples.</p></li>
   1020 </ul></dd>
   1021 <dt class="date">2002-03-11</dt>
   1022 <dd class="desc">First published.</dd>
   1023 </dl>-->
   1024 </footer>
   1025 </body>
   1026 </html>

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.