extract @vt entries from docs

This commit is contained in:
Jörg Breitbart
2019-08-18 17:36:06 +02:00
parent 5a9e6fe94b
commit 2de22f9356
4 changed files with 203 additions and 1 deletions
+181
View File
@@ -0,0 +1,181 @@
/**
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
* @license MIT
*
* Script to extract vt features documented in docstrings.
*/
const fs = require('fs');
const Mustache = require('mustache');
/**
* regexp to fetch all comments
* Fetches all multiline comments and single lines containing '// @vt:'.
*/
const REX_COMMENTS = /^\s*?[/][*][*]([\s\S]*?)[*][/]|^\s*?\/\/ ([@]vt[:].*?)$/mug;
// expected - "@vt: type name "sequence" "short description"
/**
* regexp to parse the @vt line
* expected data - "@vt: <status> <kind> <mnemonic> <"name"> "<sequence>" "<short description>"
*/
const REX_VT_LINE = /^[@]vt\:\s*(\w+)\s*(\w+)\s*(\w+)\s*"(.*?)"\s*"(.*?)"\s*"(.*?)".*$/;
// known vt command types
const TYPES = [
'C0',
'C1',
'ESC',
'CSI',
'DCS',
'OSC',
'APC',
'PM',
'SOS'
];
const MARKDOWN_TMPL = `
# Supported VT features by xterm.js
Version: {{version}}
### C0
| Mnemonic | Name | Sequence | Short Description | Status |
| -------- | ---- | -------- | ----------------- | ------ |
{{#C0}}
| {{mnemonic}} | {{name}} | \`{{sequence}}\` | {{shortDescription}} | {{status}} |
{{/C0}}
### C1
| Mnemonic | Name | Sequence | Short Description | Status |
| -------- | ---- | -------- | ----------------- | ------ |
{{#C1}}
| {{mnemonic}} | {{name}} | \`{{sequence}}\` | {{shortDescription}} | {{status}} |
{{/C1}}
### CSI
| Mnemonic | Name | Sequence | Short Description | Status |
| -------- | ---- | -------- | ----------------- | ------ |
{{#CSI}}
| {{mnemonic}} | {{name}} | \`{{sequence}}\` | {{shortDescription}} | {{status}} |
{{/CSI}}
### DCS
| Mnemonic | Name | Sequence | Short Description | Status |
| -------- | ---- | -------- | ----------------- | ------ |
{{#DCS}}
| {{mnemonic}} | {{name}} | \`{{sequence}}\` | {{shortDescription}} | {{status}} |
{{/DCS}}
### ESC
| Mnemonic | Name | Sequence | Short Description | Status |
| -------- | ---- | -------- | ----------------- | ------ |
{{#ESC}}
| {{mnemonic}} | {{name}} | \`{{sequence}}\` | {{shortDescription}} | {{status}} |
{{/ESC}}
### OSC
| Mnemonic | Name | Sequence | Short Description | Status |
| -------- | ---- | -------- | ----------------- | ------ |
{{#OSC}}
| {{mnemonic}} | {{name}} | \`{{sequence}}\` | {{shortDescription}} | {{status}} |
{{/OSC}}
`
function parseMultiLine(filename, s) {
if (!~s.indexOf('@vt:')) {
return;
}
const lines = s.split('\n').map(el => el.trim().replace(/[*]/, '').replace(/\s/, ''));
let grabLine = false;
const longDescription = [];
let feature;
for (const line of lines) {
if (grabLine) {
if (!line) {
break;
}
longDescription.push(line);
}
if (~line.indexOf('@vt:')) {
feature = parseSingleLine(filename, line);
grabLine = true;
}
}
if (feature) {
feature.longDescription = longDescription;
return feature;
}
}
function parseSingleLine(filename, s) {
const line = s.trim();
const match = line.match(REX_VT_LINE);
if (match !== null) {
if (!~TYPES.indexOf(match[2])) {
throw new Error(`unkown vt-command type "${match[2]}" specified in "${filename}"`);
}
return {
status: match[1],
type: match[2],
mnemonic: match[3],
name: match[4],
sequence: match[5],
shortDescription: match[6],
longDescription: [],
source: filename
};
}
}
function postProcessData(features) {
const featureTable = {};
for (const feature of features) {
if (featureTable[feature.type] === undefined) {
featureTable[feature.type] = [];
}
featureTable[feature.type].push(feature);
}
for (const entry in featureTable) {
featureTable[entry].sort((a, b) => a.sequence.slice(-1) > b.sequence.slice(-1));
}
// console.error(featureTable);
featureTable.version = require('../package.json').version;
console.log(Mustache.render(MARKDOWN_TMPL, featureTable));
}
function main(filenames) {
// console.error(filenames);
let leftToProcess = filenames.length;
const features = [];
for (const filename of filenames) {
fs.readFile(filename, 'utf-8', (err, data) => {
let match;
while ((match = REX_COMMENTS.exec(data)) !== null) {
if (match.index === REX_COMMENTS.lastIndex) {
REX_COMMENTS.lastIndex++;
}
const feature = match[1]
? parseMultiLine(filename, match[1])
: parseSingleLine(filename, match[2]);
if (feature) {
features.push(feature);
}
}
leftToProcess--;
if (!leftToProcess) {
postProcessData(features);
}
});
}
}
main(process.argv.slice(2))
+3 -1
View File
@@ -23,7 +23,8 @@
"benchmark": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json",
"benchmark-baseline": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json --baseline out-test/benchmark/test/benchmark/*benchmark.js",
"benchmark-eval": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json --eval out-test/benchmark/test/benchmark/*benchmark.js",
"clean": "rm -rf lib out addons/*/lib addons/*/out"
"clean": "rm -rf lib out addons/*/lib addons/*/out",
"vtfeatures": "node bin/extract_vt.js src/**/*.ts src/*.ts"
},
"devDependencies": {
"@types/chai": "^3.4.34",
@@ -41,6 +42,7 @@
"glob": "^7.0.5",
"jsdom": "^11.11.0",
"mocha": "^6.1.4",
"mustache": "^3.0.1",
"node-pty": "0.7.6",
"puppeteer": "^1.15.0",
"source-map-loader": "^0.2.4",
+14
View File
@@ -177,13 +177,18 @@ export class InputHandler extends Disposable implements IInputHandler {
* CSI handler
*/
this._parser.setCsiHandler({final: '@'}, params => this.insertChars(params));
// @vt: supported CSI CUU "Cursor Up" "CSI Ps A" "Move the cursor position `Ps` times to the top (default=1)."
this._parser.setCsiHandler({final: 'A'}, params => this.cursorUp(params));
// @vt: supported CSI CUD "Cursor Down" "CSI Ps B" "Move the cursor position `Ps` times to the bottom (default=1)."
this._parser.setCsiHandler({final: 'B'}, params => this.cursorDown(params));
// @vt: supported CSI CUF "Cursor Forward" "CSI Ps C" "Move the cursor position `Ps` times to the right (default=1)."
this._parser.setCsiHandler({final: 'C'}, params => this.cursorForward(params));
// @vt: supported CSI CUB "Cursor Backward" "CSI Ps D" "Move the cursor position `Ps` times to the left (default=1)."
this._parser.setCsiHandler({final: 'D'}, params => this.cursorBackward(params));
this._parser.setCsiHandler({final: 'E'}, params => this.cursorNextLine(params));
this._parser.setCsiHandler({final: 'F'}, params => this.cursorPrecedingLine(params));
this._parser.setCsiHandler({final: 'G'}, params => this.cursorCharAbsolute(params));
// @vt: supported CSI CUP "Cursor Position" "CSI Ps ; Ps H" "Set the cursor to position [`Ps`, `Ps`]."
this._parser.setCsiHandler({final: 'H'}, params => this.cursorPosition(params));
this._parser.setCsiHandler({final: 'I'}, params => this.cursorForwardTab(params));
this._parser.setCsiHandler({final: 'J'}, params => this.eraseInDisplay(params));
@@ -210,6 +215,7 @@ export class InputHandler extends Disposable implements IInputHandler {
this._parser.setCsiHandler({prefix: '?', final: 'h'}, params => this.setModePrivate(params));
this._parser.setCsiHandler({final: 'l'}, params => this.resetMode(params));
this._parser.setCsiHandler({prefix: '?', final: 'l'}, params => this.resetModePrivate(params));
// @vt: partly CSI SGR "Select Graphic Rendition" "CSI Pm m" "Set various text attributes."
this._parser.setCsiHandler({final: 'm'}, params => this.charAttributes(params));
this._parser.setCsiHandler({final: 'n'}, params => this.deviceStatus(params));
this._parser.setCsiHandler({prefix: '?', final: 'n'}, params => this.deviceStatusPrivate(params));
@@ -222,11 +228,15 @@ export class InputHandler extends Disposable implements IInputHandler {
/**
* execute handler
*/
// @vt: supported C0 BEL "Bell" "\x07" "Rings the bell."
this._parser.setExecuteHandler(C0.BEL, () => this.bell());
// @vt: supported C0 LF "Line Feed" "\n" "Moves the cursor one row down, scrolling if needed."
this._parser.setExecuteHandler(C0.LF, () => this.lineFeed());
this._parser.setExecuteHandler(C0.VT, () => this.lineFeed());
this._parser.setExecuteHandler(C0.FF, () => this.lineFeed());
// @vt: supported C0 CR "Carriage Return" "\r" "Moves the cursor to the beginning of the row."
this._parser.setExecuteHandler(C0.CR, () => this.carriageReturn());
// @vt: supported C0 BS "Backspace" "\x08" "Moves the cursor one position to the left."
this._parser.setExecuteHandler(C0.BS, () => this.backspace());
this._parser.setExecuteHandler(C0.HT, () => this.tab());
this._parser.setExecuteHandler(C0.SO, () => this.shiftOut());
@@ -241,9 +251,12 @@ export class InputHandler extends Disposable implements IInputHandler {
* OSC handler
*/
// 0 - icon name + title
// @vt: partly OSC OSC0 "" "OSC 0 ; Pt BEL" "Set window title and icon name."
this._parser.setOscHandler(0, new OscHandler((data: string) => this.setTitle(data)));
// 1 - icon name
// @vt: unsupported OSC OSC1 "" "OSC 1 ; Pt BEL" "Set icon name."
// 2 - title
// @vt: supported OSC OSC2 "" "OSC 2 ; Pt BEL" "Set window title."
this._parser.setOscHandler(2, new OscHandler((data: string) => this.setTitle(data)));
// 3 - set property X in the form "prop=value"
// 4 - Change Color Number
@@ -306,6 +319,7 @@ export class InputHandler extends Disposable implements IInputHandler {
this._parser.setEscHandler({intermediates: '.', final: flag}, () => this.selectCharset('.' + flag));
this._parser.setEscHandler({intermediates: '/', final: flag}, () => this.selectCharset('/' + flag)); // TODO: supported?
}
// @vt: supported ESC DECALN "Screen Alignment Pattern" "ESC # 8" "Fill viewport with a test pattern (E)."
this._parser.setEscHandler({intermediates: '#', final: '8'}, () => this.screenAlignmentPattern());
/**
+5
View File
@@ -3133,6 +3133,11 @@ ms@2.1.1, ms@^2.1.1:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
mustache@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/mustache/-/mustache-3.0.1.tgz#873855f23aa8a95b150fb96d9836edbc5a1d248a"
integrity sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==
mute-stream@0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"