Revert "permet l'ajout des frameworks et des routes"

This reverts commit 361112699c
This commit is contained in:
Dario Duchateau-weinberger
2023-09-25 09:44:12 +02:00
parent 361112699c
commit 20cb812095
2787 changed files with 0 additions and 864804 deletions

View File

@@ -1,990 +0,0 @@
/**
* @name CeL function for console
*
* @fileoverview 本檔案包含了 console 操作用的 functions。<br />
* a.k.a. 一般論壇 (BBS) ANSI color 轉換程式。
*
* @since 2015/3/1 13:16:6
*/
'use strict';
// More examples: see /_test suite/test.js
// ------------------------------------------------------------------------------------------------
typeof CeL === 'function' && CeL.run({
name : 'interact.console',
// includes() @ data.code.compatibility.
require : 'data.code.compatibility.|data.native.to_RegExp_pattern',
// 為了方便格式化程式碼,因此將 module 函式主體另外抽出。
code : module_code
});
function module_code(library_namespace) {
// requiring
var to_RegExp_pattern = this.r('to_RegExp_pattern');
/**
* null module constructor
*
* @class console 處理的 functions
*/
var _// JSDT:_module_
= function() {
// null module constructor
};
/**
* for JSDT: 有 prototype 才會將之當作 Class
*/
_// JSDT:_module_
.prototype = {};
// -------------------------------------------------------------
/**
* 本 module 所有 library_namespace.debug() 可能使用到之相關函數,所須使用之最低 debug level。
*
* @type {ℕ⁰:Natural+0}
*
* @see function new_SGR(messages) @ base.js
*/
var min_debug = 3;
// -------------------------------------------------------------
//
/**
* parse style name
*
* @param {String|Object}style_name
* style name to parse
*
* @returns {String}style name
*
* @see <span title="Select Graphic Rendition">SGR</span> parameters
*/
function SGR_style_name(style_name) {
library_namespace.debug({
// gettext_config:{"id":"search-style-name-$1-in-`sgr_code.style_name_alias`"}
T : [ 'Search style name [%1] in `SGR_code.style_name_alias`...',
style_name ]
}, min_debug, 'SGR_style_name');
if (typeof style_name !== 'object'
&& (style_name in SGR_code.style_name_alias))
style_name = SGR_code.style_name_alias[style_name];
if (library_namespace.is_debug() && (typeof style_name === 'object'
//
|| !(style_name in SGR_code.style_data))) {
library_namespace.warn([ 'SGR_style_name: ', {
// gettext_config:{"id":"unknown-style-name-$1"}
T : [ 'Unknown style name: [%1].', style_name ]
} ]);
}
return style_name;
}
/**
* parse style value
*
* @param style_value
* style value to parse
* @param {String}[style_name]
* style name to referrer
*
* @returns {String} style value
*/
function SGR_style_value(style_value, style_name) {
// TODO: using "brightred", "boldred"
// http://git-scm.com/docs/git-config#Documentation/git-config.txt-color
if (typeof style_value !== 'object'
&& (style_value in SGR_code.color_index)) {
if (typeof style_name !== 'string' || !(style_name in color_shift)) {
// Expects value in color_shift.
library_namespace.warn([ 'SGR_style_value: ', {
// gettext_config:{"id":"invalid-name-of-color-$1"}
T : [ 'Invalid name of color: [%1].', style_name ]
} ]);
return;
}
// color_shift[style_name] +
return SGR_code.color_index[style_value];
}
if (style_value in SGR_style_value.alias)
style_value = SGR_style_value.alias[style_value];
if (typeof style_value === 'boolean') {
if ((style_name in SGR_code.style_data)
&& SGR_code.style_data[style_name][style_value ? 0 : 1] === undefined) {
library_namespace.warn([ {
// gettext_config:{"id":"invalid-value-$1-of-style-$2"}
T : [ 'Invalid value [%1] of style: [%2]:',
//
style_value, style_name ]
}, {
// gettext_config:{"id":"unable-to-convert-the-value-to-a-style"}
T : '無法將真偽值轉為樣式。'
} ]);
return;
}
return style_value;
}
if (isNaN(style_value) || (style_value |= 0) < 0) {
library_namespace.warn([ {
// gettext_config:{"id":"invalid-value-$1-of-style-$2"}
T : [ 'Invalid value [%1] of style: [%2]:',
//
style_value, style_name ]
}, {
// gettext_config:{"id":"the-style-value-is-not-a-number"}
T : '欲設定的樣式值並非數字。'
} ]);
return;
}
// do more check.
if ((style_name in SGR_code.style_data)
&& !SGR_code.style_data[style_name].includes(style_value))
if (style_name in color_shift) {
if (style_value >= color_shift[style_name])
style_value -= color_shift[style_name];
} else {
library_namespace.warn([ {
// gettext_config:{"id":"invalid-value-$1-of-style-$2"}
T : [ 'Invalid value [%1] of style: [%2]:',
//
style_value, style_name ]
}, {
// gettext_config:{"id":"the-style-value-is-not-in-the-style-sheet-$1-that-can-be-set"}
T : [ '樣式值不在可設定的樣式資料[%1]中。',
//
SGR_code.style_data[style_name] ]
} ]);
return;
}
return style_value;
}
SGR_style_value.alias = {
'true' : true,
'false' : false
};
/**
* check if the style value is "reset" or not.
*
* @param style_value
* style value to check
*
* @returns {Boolean} the style value is "reset".
*/
function is_reset_style(style_value) {
return style_value === 0 || style_value === '0';
}
/**
* parse and add style to {SGR_style}(this).<br />
* 注意: 一般論壇 (BBS) 使用 VT100遇到 \x20 (space) 即會終止解析而跳出。 但本函式依然會跳過空白而解析之。
*
* @param style
* style to add
*
* @returns {SGR_style}(this)
*/
function SGR_style_add(style) {
if (!style && !is_reset_style(style))
// skip.
return this;
library_namespace.debug({
// gettext_config:{"id":"searching-style-{$2}-$1-in-sgr_code.style_value_alias"}
T : [ 'Searching style {%2} [%1] in SGR_code.style_value_alias...',
typeof JSON === 'object' ? JSON.stringify(style) : style,
typeof style ]
}, min_debug, 'SGR_style_add');
if (typeof style !== 'object')
while (style in SGR_code.style_value_alias) {
library_namespace.debug({
// gettext_config:{"id":"find-style-$1-normalized-to-→-$2"}
T : [ 'Find style [%1] normalized to → [%2]', style,
SGR_code.style_value_alias[style] ]
}, min_debug, 'SGR_style_add');
style = SGR_code.style_value_alias[style];
}
library_namespace.debug({
// gettext_config:{"id":"parse-{$2}-$1-if-it-is-a-primitive-value"}
T : [ 'Parse {%2} [%1] if it is a primitive value.',
typeof JSON === 'object' ? JSON.stringify(style) : style,
typeof style ]
}, min_debug, 'SGR_style_add');
if (typeof style === 'string') {
if (style.includes(SGR_code.separator)) {
style = style.split(SGR_code.separator);
} else if (isNaN(style)) {
library_namespace.debug({
// gettext_config:{"id":"test-if-$1-is-+-style-name"}
T : [ 'Test if [%1] is "[+-] style name".', style ]
}, min_debug, 'SGR_style_add');
// "+bright"
var matched = style.match(/^([+\-])([^=]*?)$/);
if (matched && (matched[2] = SGR_style_name(matched[2].trim()))) {
matched[1] = matched[1] !== '-';
if (undefined === SGR_style_value(matched[1], matched[2]))
library_namespace.warn([ 'SGR_style_add: ', {
// gettext_config:{"id":"invalid-configuration-of-style-$1"}
T : [ 'Invalid configuration of style: [%1].',
// Expects integer.
matched[2] ]
} ]);
else {
library_namespace.debug({
// gettext_config:{"id":"set-style-$1-=-$2"}
T : [ 'Set style "%1" = %2.', matched[2],
matched[1] ]
}, min_debug, 'SGR_style_add');
this[matched[2]] = matched[1];
}
return this;
}
library_namespace.debug({
T : [
// gettext_config:{"id":"test-if-$1-is-style-name-=-style-value-(0-1-false-true-...)"}
'Test if [%1] is "style name = style value (0, 1, false, true, ...)".'
//
, style ]
}, min_debug, 'SGR_style_add');
matched = style.match(/^([^=]+)=(.+)$/);
if (matched && (matched[1] = SGR_style_name(matched[1].trim()))) {
if (undefined !== (matched[2] = SGR_style_value(matched[2]
.trim(), matched[1])))
this[matched[1]] = matched[2];
return this;
}
// 死馬當活馬醫。
style = SGR_style_name(style);
} else {
style |= 0;
}
} else if (typeof style === 'number') {
style |= 0;
}
if (library_namespace.is_Object(style) || style instanceof SGR_style) {
library_namespace.debug({
T : [
// gettext_config:{"id":"parse-{$2}-$1-if-it-is-a-object"}
'Parse {%2} [%1] if it is a object.',
typeof JSON === 'object' ? JSON.stringify(style)
: style, typeof style ]
}, min_debug, 'SGR_style_add');
Object.keys(style).some(
function(style_name) {
var style_value = style[style_name];
if (!(style_name = SGR_style_name(style_name))) {
// 已於 SGR_style_name() 警告過。
return;
}
style_value = SGR_style_value(style_value, style_name);
if (style_value !== undefined) {
library_namespace.debug({
T : [ 'Set style "%1" = [%2].', style_name,
style_value ]
}, min_debug + 1, 'SGR_style_add');
this[style_name] = style_value;
} else if (is_reset_style(style_value)) {
library_namespace.debug({
// gettext_config:{"id":"reset-style-{$2}-$1"}
T : [ 'Reset style {%2} [%1].', style,
typeof style ]
}, min_debug + 1, 'SGR_style_add');
this.to_reset();
return true;
}
}, this);
} else if (Array.isArray(style)) {
style.forEach(function(value) {
this.add(value);
}, this);
} else if (30 <= style && style <= 37) {
this.foreground = style;
} else if (40 <= style && style <= 47) {
this.background = style;
} else if (is_reset_style(style)) {
library_namespace.debug({
// gettext_config:{"id":"reset-style-{$2}-$1"}
T : [ 'Reset style {%2} [%1].', style, typeof style ]
}, min_debug, 'SGR_style_add');
this.to_reset();
} else if (library_namespace.is_debug()) {
library_namespace.warn([ 'SGR_style_add: ', {
// gettext_config:{"id":"unknown-style-$1"}
T : [ 'Unknown style: [%1].', style ]
} ]);
}
return this;
}
/**
* SGR style Class
*
* @param [style]
* style to set
*
* @returns {SGR_style}(this)
*/
function SGR_style(style, options) {
if (false)
if (library_namespace.is_Object(options))
this.options = options;
// 對於 Object.create(null),這邊會出錯。
library_namespace.debug('Set style ['
+ (typeof JSON === 'object' ? JSON.stringify(style) : style)
+ ']', min_debug, 'SGR_style');
this.add(style);
library_namespace.debug('Set style ['
+ (typeof JSON === 'object' ? JSON.stringify(style) : style)
+ '] finished.', min_debug + 1, 'SGR_style');
}
/**
* indicate the color styles.<br />
* 實際上應該列出所有設定值超過一種的樣式/格式名。
*
* @type {Object}
*/
var color_shift = {
foreground : 30,
background : 40
};
Object.assign(SGR_style.prototype, {
add : SGR_style_add,
forEach : function(callback, thisArg) {
// 下面當前不使用。
if (false) {
var style_names = Object.keys(this);
if (this.options)
// remove 'options'.
style_names.splice(style_names.indexOf('options'), 2);
style_names.forEach(callback, thisArg || this);
}
Object.keys(this).forEach(callback, thisArg || this);
},
to_reset : function() {
library_namespace.debug('Reset style.', min_debug,
'SGR_style.prototype.to_reset');
this.forEach(function(style_name) {
delete this[style_name];
});
this.reset = true;
return this;
},
clone : function(options) {
library_namespace.debug('Clone style [' + this + '].', min_debug,
'SGR_style.prototype.clone');
var result = new SGR_style();
this.forEach(function(style_name) {
result[style_name] = this[style_name];
});
if (false)
if (options = options || this.options)
result.options = options;
return result;
},
to_Array : function() {
var array = [];
if (library_namespace.is_debug(min_debug))
library_namespace.debug('style [' + Object.keys(this) + ']', 1,
'SGR_style.prototype.to_Array');
if (false)
for ( var name in this)
library_namespace.debug('[' + name + ']', min_debug + 1);
this.forEach(function(style_name) {
var value = this[style_name];
library_namespace.debug('style "' + style_name + '" ['
+ SGR_code.style_data[style_name] + '] = ('
+ (typeof value) + ') [' + value + ']', min_debug + 1,
'SGR_style.prototype.to_Array');
if (style_name in color_shift) {
if (typeof value === 'boolean')
value = SGR_code.style_data[style_name]
// 0: on, 1: off.
[value ? 0 : 1];
else if (value < color_shift[style_name])
// 正常情況。
value += color_shift[style_name];
else if (isNaN(value))
library_namespace.warn('Invalid ' + style_name
+ ' color [' + value + ']');
} else if (typeof value !== 'number')
// 正常情況。
value = SGR_code.style_data[style_name]
// 0: on, 1: off.
[value ? 0 : 1];
if (typeof value === 'number')
array.push(value);
// else: e.g., reset.
});
library_namespace.debug('style array [' + array + ']',
min_debug + 1, 'SGR_style.prototype.to_Array');
array.sort();
library_namespace.debug('sorted style array [' + array + ']',
min_debug, 'SGR_style.prototype.to_Array');
return array;
},
// (): use default CSI
// (false): No CSI
toString : function(CSI, end_code) {
var code = this.to_Array().join(SGR_code.separator);
library_namespace.debug('code [' + code + ']', min_debug,
'SGR_style.prototype.toString');
// 假如有設定 .reset那應該會有 '0'。
// 否則代表是空的 style此時不回傳以避免被當作 reset。
if (code && (CSI || CSI === undefined))
code = (CSI || SGR_code.CSI) + code
+ (end_code || SGR_code.end_code);
return code;
}
});
// -------------------------------------------------------------
/**
* cf. String.prototype.split ( separator, limit )
*
* @returns [ {SGR_code} ]
*/
function SGR_split(separator, limit) {
// TODO
throw new Error('SGR_split: Not Yet Implemented!');
}
/**
* cf. String.prototype.slice ( start, end )
*
* @returns {SGR_code}
*/
function SGR_slice() {
var result = new SGR_code(this.text.split(start, end));
result.style = this.style.split(start, end);
result.style.forEach(function(style, index) {
result[index] = result[index].clone();
});
return result;
}
/**
* 會改變 (this)!<br />
* cf. Array.prototype.concat ( ...arguments )
*
* @param {String|SGR_code}value
*
* @returns {SGR_code} (this)
*/
function SGR_concat(value) {
var index = 0, length = argument.length,
//
text_list = [ this.text ], value;
for (; index < length; index++)
if (is_SGR_code(value = argument[index])) {
// treat as {SGR_code}
text_list = text_list.join('');
this.style.forEach(function(style, index) {
this.style[text_list.length + index] = style;
}, this);
text_list = [ text_list, value.text ];
} else if (value)
// treat as {String}
text_list.push(value);
this.text = text_list.join('');
return this;
}
/**
* parse styled text.
*
* @param {String}styled_text
* text with style
* @param {Object}[options]
* options : { CSI : '' }
*
* @returns {Array} [ text, style ]
*/
function SGR_parse(styled_text, options) {
// console.log('to_RegExp_pattern: ' + typeof to_RegExp_pattern);
// console.log('to_RegExp_pattern: ' + to_RegExp_pattern);
var text_now = '', style = [], matched, lastIndex = 0,
//
pattern = new RegExp(to_RegExp_pattern(options.CSI || SGR_code.CSI)
+ '([\\d{1,3}\\s\\' + (options.separator || SGR_code.separator)
+ ']*)'
+ to_RegExp_pattern(options.end_code || SGR_code.end_code), 'g');
while (matched = pattern.exec(styled_text)) {
library_namespace.debug(matched.join(), min_debug, 'SGR_parse');
text_now += styled_text.slice(lastIndex, matched.index);
style[text_now.length] = new SGR_style(matched[1] || 0);
lastIndex = pattern.lastIndex;
}
return [ text_now + styled_text.slice(lastIndex), style ];
}
/**
* parse text token with style.
*
* @param {Array}text_Array
* text token and style.<br /> [ {String}text, {Object}style,
* {String}text, .. ]<br />
* 預設 [0] 為 text之後 style, text, style, ... 交替
* @param {Object}[options]
* options : { CSI : '' }
*
* @returns {Array} [ text, style ]
*/
function SGR_parse_list(text_Array, options) {
var text_now = '', style = [],
//
index = 0, length = text_Array.length, text_length;
for (; index < length; index++) {
if (typeof text_Array[index] !== 'object')
text_now += text_Array[index++];
if (index < length)
if (style[text_length = text_now.length])
style[text_length].add(text_Array[index]);
else
style[text_length] = new SGR_style(text_Array[index]);
}
return [ text_now, style ];
}
/**
* get / set SGR style.
*
* @param {integer}index
* index of text
* @param {Object|String|Boolean}[style]
* the style to set.<br />
* undefined: 從頭遍歷,取得某一 index 的 style。比起 `true` 取得的更準確。<br />
* 0: reset style (e.g., normal color)<br />
* null: remove style<br />
* true: 單純取得某一 index 的 style不從頭遍歷。如此取得的可能是錯誤的 style。<br />
* others: 設定 style。
* @param {integer}[to_index]
*
* @returns {SGR_style}
*/
function SGR_style_at(index, style, to_index) {
index |= 0;
if (style === null) {
// e.g., .style_at(index, null)
delete this.style[index];
return;
}
if (style === true) {
// e.g., .style_at(index, true)
return this.style[index];
}
var style_now;
// 從頭遍歷。
library_namespace.debug('Start traversing to ' + index, min_debug,
'SGR_style_at');
this.style.some(function(this_style, this_index) {
if (this_index > index)
return true;
library_namespace.debug('Traversing to index ' + this_index,
min_debug + 1, 'SGR_style_at');
if (style_now) {
// TODO: reduce. 決定最短顯示法。
style_now.add(this_style);
} else
style_now = this_style.clone();
});
if (!style_now)
style_now = new SGR_style();
if (style) {
// 設定
library_namespace.debug('Set style of "' + this.text + '"[' + index
+ '] = [' + style + ']', min_debug, 'SGR_style_at');
if (!this.style[index])
this.style[index] = style_now;
style_now.add(style = new SGR_style(style));
library_namespace
.debug('Set `to_index`', min_debug, 'SGR_style_at');
if (index < to_index) {
// TODO: 更有效率點。
while (index < to_index)
if (this.style[index]) {
var inter_style = this.style[index];
delete inter_style.reset;
style.forEach(function(style_name) {
// 覆寫設定。
delete inter_style[style_name];
})
}
}
} else if (is_reset_style(style)) {
this.style[index] = style_now.add(0);
} else {
// e.g., .style_at(index)
}
return style_now;
}
/**
* get full stylied String.
*
* @param {Boolean}[get_Array]
* get Array, else String.
*
* @returns {String}
*/
function SGR_style_toString(get_Array) {
var sequence = this.text.split('');
this.style.forEach(function(style, index) {
sequence[index] = style.toString()
// 在最後一個 item 時可能只剩 style。
+ (sequence[index] || '');
}, this);
return get_Array ? sequence : sequence.join('');
}
/**
* 測試 value 是否為 SGR_code instance。
*
* @param value
* 測試值。
*
* @returns {Boolean} 測試值為 SGR_code instance
*/
function is_SGR_code(value) {
return value instanceof SGR_code;
}
// -------------------------------------------------------------
/**
* ANSI escape code (or escape sequences) Class
*
* @param {String|Array}text
* text / text token
* @param {Object}[options]
* options : { CSI : '' }
*
* @see <a href="https://en.wikipedia.org/wiki/ANSI_escape_code#graphics"
* accessdate="2015/3/1 8:1" title="ANSI escape code (or escape
* sequences)"><span title="Select Graphic Rendition">SGR</span>
* parameters</a><br />
* <a href="http://vt100.net/docs/vt510-rm/SGR" accessdate="2015/3/1
* 8:1">SGR—Select Graphic Rendition</a>
*/
function SGR_code(text, options) {
if (false)
if (typeof options === 'string')
options = {
CSI : options
};
if (false) {
console.trace([ text, library_namespace.is_Object(text), options,
library_namespace.is_Object(options) ]);
}
if (library_namespace.is_Object(text) && !options) {
// 把 text 當作 options。
options = text;
text = null;
}
if (library_namespace.is_Object(options))
this.options = options;
options = Array.isArray(text) ? SGR_parse_list(text, options
|| Object.create(null))
// String(): 標準化 / normalization
: SGR_parse(String(text), options || Object.create(null));
this.text = options[0];
// {inner}private properties
// this.style[ index ] = new SGR_style();
this.style = options[1];
}
Object.assign(SGR_code.prototype, {
// SGR_style_to_HTML(style_mapping)
// to_HTML : SGR_style_to_HTML,
// style : SGR_style,
slice : SGR_slice,
// split : SGR_split,
concat : SGR_concat,
// TODO:
// splice : SGR_splice,
// chunk : SGR_chunk,
style_at : SGR_style_at,
// toJSON : SGR_style_toString,
toString : SGR_style_toString
});
/**
* ECMA-48 8.3.117 SGR - SELECT GRAPHIC RENDITION<br />
* 為允許使用者參照,因此放在 public。<br />
* 注意: 一般論壇 (BBS) 使用 VT100僅支援如 reset, bold, blink, reverse, foreground,
* background。
*
* @type {Object}
*/
SGR_code.style_data = {
// name : [ on, off ]
// reset / normal
reset : [ 0, ],
// bold or increased intensity (bright / highlight / 高亮)
bold : [ 1, 22 ],
// faint, decreased intensity or second colour
faint : [ 2, 22 ],
// singly underlined (mono only)
underline : [ 4, 24 ],
// blink / 閃爍
// 5: slowly blinking less then 150 per minute,
// 6: rapidly blinking
blink : [ 5, 25 ],
// negative / positive image (反白, reverse type)
reverse : [ 7, 27 ],
// concealed characters (invisible image) 隱瞞,隱匿,隱蔽,隱藏來源
conceal : [ 8, 28 ],
// display (text color, foreground color, 文字部份前景色):
// 3037
foreground : [ , library_namespace.platform.Windows
// Windows console 不支援 39。(e.g. node.js 下)
&& library_namespace.platform.nodejs ? 37 : 39 ],
// background color (背景色 / 底色): 4047
background : [ , 49 ],
// Overlined / Not overlined
overline : [ 53, 55 ]
};
/**
* style name alias<br />
* 為允許使用者添增,因此放在 public。
*/
SGR_code.style_name_alias = {
normal : 'reset',
bright : 'bold',
highlight : 'bold',
hidden : 'conceal',
text : 'foreground',
color : 'foreground',
fg : 'foreground',
bg : 'background'
};
/**
* 添增 color name alias。
*
* @example <code>
// 使設定格式時,可使用中文顏色名稱。
CeL.interact.console.SGR.add_color_alias('黑紅綠黃藍紫青白'.split(''));
* </code>
*
* @param {Array}color_list
* color name list
*/
function add_color_alias(color_list) {
if (Array.isArray(color_list)) {
color_list.forEach(function(color, index) {
SGR_code.color_index[color] = index;
});
}
}
/**
* style value alias: style_value_alias[alias] = normalized<br />
* 為允許使用者添增,因此放在 public。
*/
SGR_code.style_value_alias = Object.create(null);
// SGR_code.color_index.black = 0
SGR_code.color_index = Object.create(null);
SGR_code.color = 'black,red,green,yellow,blue,magenta,cyan,white'
.split(',');
// 鎖定物件。
Object.seal(SGR_code.color);
add_color_alias(SGR_code.color);
// 一些初始設定。
// alias of number
(function() {
for ( var property in SGR_code.style_data) {
var value = SGR_code.style_data[property];
if (typeof value[0] === 'number')
SGR_code.style_value_alias[value[0]] = '+' + property;
if (typeof value[1] === 'number')
SGR_code.style_value_alias[value[1]] = '-' + property;
}
})();
// 鎖定物件。
Object.seal(SGR_code.style_data);
Object.assign(SGR_code, {
min_debug_level : min_debug,
add_color_alias : add_color_alias,
/**
* {String} Control Sequence Introducer, or Control Sequence Initiator.<br />
* "\x1b" : [Esc]<br />
* some 論壇 (BBS): 按 Esc 兩次, '\x1b\x1b['。
*
* @see https://en.wikipedia.org/wiki/ANSI_escape_code#Sequence_elements
*/
CSI : '\x1b[',
// do not modify this value!
default_CSI : '\x1b[',
separator : ';',
end_code : 'm',
is_SGR : is_SGR_code
});
// export
_.SGR = SGR_code;
_.SGR_style = SGR_style;
if (false) {
var SGR_style = CeL.interact.console.SGR_style;
console.log('Showing ' + (new SGR_style('fg=blue')).toString() + 'blue'
+ (new SGR_style({
reset : true
})).toString() + ' text');
// for SGR: @see test.js
}
// ----------------------------------------------------------------------------------------------------------------
function console_status() {
return {
// size. 注意: 這兩個值可能會被覆寫。
width : process.stdout.columns || 80,
height : process.stdout.rows || 25
};
}
_.console_status = console_status;
// ----------------------------------------------------------------------------------------------------------------
// CLI progress bar
// https://github.com/visionmedia/node-progress
// https://github.com/bubkoo/ascii-progress
// https://github.com/AndiDittrich/Node.CLI-Progress
function Progress_bar(max_value, options) {
if (max_value > 0)
this.max_value = max_value;
this.start_time = Date.now();
if (options) {
Object.assign(this, options);
if (this.rtl && !options.start_quote && !options.end_quote) {
var quote = this.end_quote;
this.end_quote = this.start_quote;
this.start_quote = quote;
}
}
}
_.Progress_bar = Progress_bar;
Progress_bar.prototype = {
progress_value : 0,
max_value : 1,
// 方向 direction
rtl : false,
start_quote : ' [',
end_quote : '] ',
use_quote : true,
// single character
filled : '=',
blank : ' ',
show : show_progress,
tick : tick_progress,
// schema. TODO
format : '\r%{pre_text}%{start_quote}%{bar}%{end_quote}%{post_text}'
}
function show_progress(progress_value, post_text, pre_text) {
var max_dots = this.bar_width;
if (!max_dots) {
// - 1: 預防顯示到最後一個字元,會自動跳行。
max_dots = console_status().width - 1;
}
max_dots |= 0;
if (this.pre_text)
max_dots -= this.pre_text.length;
if (this.post_text)
max_dots -= this.post_text.length;
if (this.use_quote) {
max_dots -= this.left_quote.length + this.right_quote.length;
}
// current progress value
this.progress_value = +progress_value || 0;
this.percentage = Math
.round(100 * this.progress_value / this.max_value)
+ '%';
// TODO: .eta
this.completed = this.progress_value >= this.max_value;
var progress_dots = Math.round(max_dots * this.progress_value
/ this.max_value);
var bar_text = [ this.pre_text || '',
this.use_quote && this.start_quote || '',
this.filled.repeat(progress_dots),
this.blank.repeat(max_dots - progress_dots),
this.use_quote && this.end_quote || '',
// suffix
this.post_text || '' ];
if (this.rtl) {
bar_text.reverse();
}
library_namespace.log_temporary(bar_text.join('\n'));
}
function tick_progress(delta, post_text, pre_text) {
this.show(this.progress_value + delta, post_text, pre_text);
}
return (_// JSDT:_module_
);
}