Auto help
parent
73ef52b939
commit
4e1f900326
|
|
@ -136,6 +136,8 @@
|
||||||
whiteSpace: 'nowrap'
|
whiteSpace: 'nowrap'
|
||||||
});
|
});
|
||||||
var row = $('<div/>').appendTo(container);
|
var row = $('<div/>').appendTo(container);
|
||||||
|
var row2 = $('<div/>').appendTo(container);
|
||||||
|
var row3 = $('<div/>').appendTo(container);
|
||||||
var selectField = $('<select/>', { style: "width:120px; margin-left: 5px; text-align: center;" }).appendTo(row);
|
var selectField = $('<select/>', { style: "width:120px; margin-left: 5px; text-align: center;" }).appendTo(row);
|
||||||
var group0 = $('<optgroup/>', { label: "value rules" }).appendTo(selectField);
|
var group0 = $('<optgroup/>', { label: "value rules" }).appendTo(selectField);
|
||||||
for (var d in operators) {
|
for (var d in operators) {
|
||||||
|
|
@ -166,9 +168,23 @@
|
||||||
var typeValueField = null;
|
var typeValueField = null;
|
||||||
|
|
||||||
var finalspan = $('<span/>', { style: "float: right;margin-top: 6px;" }).appendTo(row);
|
var finalspan = $('<span/>', { style: "float: right;margin-top: 6px;" }).appendTo(row);
|
||||||
|
var desc_label = $('<span/>', {style:"width:100px;display:inline-block;"}).text("Help:").appendTo(row2);
|
||||||
|
var desc = $('<input/>', { class: "node-input-rule-help", type: "text", style: "margin-left: 5px; width:250px", placeholder:"Help description" }).appendTo(row2);
|
||||||
|
desc.val(rule.help || "");
|
||||||
|
var desc_label = $('<span/>', {style:"width:100px;display:inline-block;"}).text("Variable:").appendTo(row3);
|
||||||
|
var match_name = $('<input/>', { class: "node-input-rule-match_name", type: "text", style: "margin-left: 5px; width: 250px;", placeholder:"Matched variable name" }).appendTo(row3);
|
||||||
|
match_name.val(rule.match_name || "");
|
||||||
|
if (rule.type !== "regex") {
|
||||||
|
row3.hide();
|
||||||
|
}
|
||||||
finalspan.append(' → <span class="node-input-rule-index">' + (i + 1) + '</span> ');
|
finalspan.append(' → <span class="node-input-rule-index">' + (i + 1) + '</span> ');
|
||||||
selectField.on("change", function () {
|
selectField.on("change", function () {
|
||||||
var type = selectField.val();
|
var type = selectField.val();
|
||||||
|
if (type == "regex") {
|
||||||
|
row3.show();
|
||||||
|
} else {
|
||||||
|
row3.hide();
|
||||||
|
}
|
||||||
valueField.typedInput('hide');
|
valueField.typedInput('hide');
|
||||||
if (!valueField) {
|
if (!valueField) {
|
||||||
valueField = createValueField();
|
valueField = createValueField();
|
||||||
|
|
@ -234,6 +250,10 @@
|
||||||
var r = { t: type };
|
var r = { t: type };
|
||||||
r.v = rule.find(".node-input-rule-value").typedInput('value');
|
r.v = rule.find(".node-input-rule-value").typedInput('value');
|
||||||
r.vt = rule.find(".node-input-rule-value").typedInput('type');
|
r.vt = rule.find(".node-input-rule-value").typedInput('type');
|
||||||
|
r.help = rule.find(".node-input-rule-help").val();
|
||||||
|
if(r.t == 'regex') {
|
||||||
|
r.match_name = rule.find(".node-input-rule-match_name").val();
|
||||||
|
}
|
||||||
node.rules.push(r);
|
node.rules.push(r);
|
||||||
});
|
});
|
||||||
this.propertyType = $("#node-input-property").typedInput('type');
|
this.propertyType = $("#node-input-property").typedInput('type');
|
||||||
|
|
@ -264,6 +284,10 @@
|
||||||
<label for="node-input-property"><i class="fa fa-ellipsis-h"></i> Property:</label>
|
<label for="node-input-property"><i class="fa fa-ellipsis-h"></i> Property:</label>
|
||||||
<input type="text" id="node-input-property" style="width: 70%"/>
|
<input type="text" id="node-input-property" style="width: 70%"/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-help_keyword"><i class="fa fa-ellipsis-h"></i> Help keyword:</label>
|
||||||
|
<input type="text" id="node-input-help_keyword" style="width: 70%"/>
|
||||||
|
</div>
|
||||||
<div class="form-row node-text-editor-row">
|
<div class="form-row node-text-editor-row">
|
||||||
<input type="hidden" id="node-input-help_text" autofocus="autofocus">
|
<input type="hidden" id="node-input-help_text" autofocus="autofocus">
|
||||||
<div style="height: 250px; min-height:150px;" class="node-text-editor" id="node-input-help_text-editor"></div>
|
<div style="height: 250px; min-height:150px;" class="node-text-editor" id="node-input-help_text-editor"></div>
|
||||||
|
|
@ -279,7 +303,8 @@
|
||||||
defaults: {
|
defaults: {
|
||||||
property: { value: "payload", required: true, validate: RED.validators.typedInput("propertyType") },
|
property: { value: "payload", required: true, validate: RED.validators.typedInput("propertyType") },
|
||||||
name: { value: "" },
|
name: { value: "" },
|
||||||
help_text: {value: ""}
|
help_text: {value: ""},
|
||||||
|
help_keyword: {value: "help"},
|
||||||
},
|
},
|
||||||
inputs: 1,
|
inputs: 1,
|
||||||
outputs: 2,
|
outputs: 2,
|
||||||
|
|
|
||||||
115
command-parse.js
115
command-parse.js
|
|
@ -2,10 +2,95 @@
|
||||||
module.exports = function (RED) {
|
module.exports = function (RED) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
function format_usage(usage, prefix) {
|
||||||
|
if (!prefix) {
|
||||||
|
prefix = [];
|
||||||
|
}
|
||||||
|
let out = "";
|
||||||
|
for (let k in usage) {
|
||||||
|
if (!usage.hasOwnProperty(k))
|
||||||
|
continue;
|
||||||
|
if(typeof usage[k] == "object"){
|
||||||
|
out += format_usage(usage[k], prefix.concat([k]));
|
||||||
|
} else {
|
||||||
|
let ext = k != "" ? [k] : [];
|
||||||
|
out += prefix.concat(ext).join(" ") + ": " + usage[k] + "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
function depth_first(n, path) {
|
||||||
|
if (!path) {
|
||||||
|
path = [n.id];
|
||||||
|
}
|
||||||
|
if (!n) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
let usage = {};
|
||||||
|
if (n.type == 'parser-consume') {
|
||||||
|
for (let r_idx in n.rules) {
|
||||||
|
let r = n.rules[r_idx];
|
||||||
|
let key;
|
||||||
|
if (r.t == "regex") {
|
||||||
|
if (r.match_name){
|
||||||
|
key = `[${r.match_name}]`;
|
||||||
|
} else {
|
||||||
|
key = `[espressione]`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
key = r.v;
|
||||||
|
}
|
||||||
|
if (r.help) {
|
||||||
|
usage[key] = r.help;
|
||||||
|
} else {
|
||||||
|
let sub_usage = {};
|
||||||
|
for (let wire of n.wires[r_idx]) {
|
||||||
|
if (path.indexOf(wire) === -1) {
|
||||||
|
let sub_n = RED.nodes.getNode(wire);
|
||||||
|
let tmp_sub_usage = depth_first(sub_n, path + [wire]);
|
||||||
|
if (tmp_sub_usage !== null) {
|
||||||
|
Object.assign(sub_usage, tmp_sub_usage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
usage[key] = sub_usage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return usage;
|
||||||
|
}
|
||||||
|
|
||||||
function ParserEntryPoint(n) {
|
function ParserEntryPoint(n) {
|
||||||
RED.nodes.createNode(this, n);
|
RED.nodes.createNode(this, n);
|
||||||
this.property = n.property;
|
this.property = n.property;
|
||||||
this.help_text = n.help_text;
|
this.help_text = n.help_text;
|
||||||
|
this.help_keyword = n.help_keyword;
|
||||||
|
this.genera_errore = function(msg) {
|
||||||
|
let out = "";
|
||||||
|
if (msg && msg.token_parser && msg.token_parser.consumed_tokens.length > 0) {
|
||||||
|
let offending_token = msg.token_parser.consumed_tokens[msg.token_parser.consumed_tokens.length - 1];
|
||||||
|
if (offending_token == "") {
|
||||||
|
offending_token = "(vuoto)";
|
||||||
|
}
|
||||||
|
out += msg.token_parser.consumed_tokens.slice(0, -1).join(" ") +`: comando non riconosciuto: ${offending_token}.\n`;
|
||||||
|
if (this.help_keyword) {
|
||||||
|
let help_command = msg.token_parser.consumed_tokens.slice(0, -1).concat([this.help_keyword]).join(" ");
|
||||||
|
out += `Usa '${help_command}' per la guida.\n`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
this.genera_help = function (root, msg) {
|
||||||
|
let usages = {};
|
||||||
|
if (!root) {
|
||||||
|
for (let wire of root.wires[0]) {
|
||||||
|
Object.assign(usages, depth_first(RED.nodes.getNode(wire)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
usages = depth_first(root);
|
||||||
|
}
|
||||||
|
return format_usage(usages, msg.token_parser.consumed_tokens.slice(0,-1));
|
||||||
|
};
|
||||||
this.on("input", msg => {
|
this.on("input", msg => {
|
||||||
RED.util.evaluateNodeProperty(this.property, "msg", this, msg,
|
RED.util.evaluateNodeProperty(this.property, "msg", this, msg,
|
||||||
(err, value) => {
|
(err, value) => {
|
||||||
|
|
@ -13,12 +98,17 @@ module.exports = function (RED) {
|
||||||
this.error(`Can't evaluate msg.${this.property}`);
|
this.error(`Can't evaluate msg.${this.property}`);
|
||||||
} else {
|
} else {
|
||||||
let tokens = value.trim().toLowerCase().split(" ");
|
let tokens = value.trim().toLowerCase().split(" ");
|
||||||
|
msg.regex_matches = {};
|
||||||
msg.token_parser = {
|
msg.token_parser = {
|
||||||
new_tokens: tokens,
|
new_tokens: tokens,
|
||||||
consumed_tokens: [],
|
consumed_tokens: [],
|
||||||
help_message: this.help_text,
|
help_keyword: this.help_keyword,
|
||||||
on_error: (maybe_error) => {
|
on_error: (msg, maybe_error) => {
|
||||||
let err = maybe_error ? maybe_error : this.help_text;
|
let err = maybe_error ? maybe_error : this.genera_errore(msg);
|
||||||
|
this.send([undefined, err]);
|
||||||
|
},
|
||||||
|
on_help: (help_node, msg) => {
|
||||||
|
let err = this.genera_help(help_node, msg);
|
||||||
this.send([undefined, err]);
|
this.send([undefined, err]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -33,10 +123,10 @@ module.exports = function (RED) {
|
||||||
function ConsumaToken(n) {
|
function ConsumaToken(n) {
|
||||||
RED.nodes.createNode(this, n);
|
RED.nodes.createNode(this, n);
|
||||||
this.rules = n.rules;
|
this.rules = n.rules;
|
||||||
this.behavior= n.behavior;
|
this.behavior = n.behavior;
|
||||||
this.checkall= n.checkall;
|
this.checkall = n.checkall;
|
||||||
function check_rule(r, token) {
|
function check_rule(r, token) {
|
||||||
switch(r.t){
|
switch (r.t) {
|
||||||
case "eq":
|
case "eq":
|
||||||
return token == r.v.toLowerCase();
|
return token == r.v.toLowerCase();
|
||||||
case "regex":
|
case "regex":
|
||||||
|
|
@ -47,10 +137,18 @@ module.exports = function (RED) {
|
||||||
this.on("input", msg => {
|
this.on("input", msg => {
|
||||||
let token = msg.token_parser.new_tokens.shift() || "";
|
let token = msg.token_parser.new_tokens.shift() || "";
|
||||||
msg.token_parser.consumed_tokens.push(token);
|
msg.token_parser.consumed_tokens.push(token);
|
||||||
|
if(token == msg.token_parser.help_keyword) {
|
||||||
|
msg.token_parser.on_help(this, msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
let out = [];
|
let out = [];
|
||||||
let n_matches = 0;
|
let n_matches = 0;
|
||||||
for (let r of this.rules) {
|
for (let r of this.rules) {
|
||||||
if(check_rule(r, token)){
|
let matches = check_rule(r, token);
|
||||||
|
if (matches === true || matches.length > 0) {
|
||||||
|
if (matches.length > 0) {
|
||||||
|
msg.regex_matches[r.match_name] = matches;
|
||||||
|
}
|
||||||
out.push(msg);
|
out.push(msg);
|
||||||
n_matches += 1;
|
n_matches += 1;
|
||||||
if (!this.checkall) {
|
if (!this.checkall) {
|
||||||
|
|
@ -61,7 +159,8 @@ module.exports = function (RED) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (n_matches == 0) {
|
if (n_matches == 0) {
|
||||||
msg.token_parser.on_error();
|
msg.token_parser.on_error(msg);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
this.send(out);
|
this.send(out);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue