Improved dispatchers with richer results and added predicate and regular expression based dispatchers
This commit is contained in:
@@ -1,19 +1,36 @@
|
||||
import { string_has_contents, indented_line_iterator } from '@efforting.tech/data/string-utilities';
|
||||
import * as CF from '@efforting.tech/data/field-configuration-factories';
|
||||
import { Text_Settings } from '@efforting.tech/data/string-utilities';
|
||||
|
||||
export class Text_Node {
|
||||
constructor(text_settings, line=undefined, indent=0, line_no=undefined, index=undefined, raw=undefined, parent=undefined) {
|
||||
Object.assign(this, { text_settings, line, indent, line_no, index, raw, parent, children: [] });
|
||||
export const Text_Tree_Settings = new CF.Schema({
|
||||
//BUG - there is currently no way (I think) to put defaults into a sub schema - this should be fixed
|
||||
text: Text_Settings,
|
||||
trim_head: CF.boolean(false, 'Trim the empty lines from the head of a node'),
|
||||
trim_tail: CF.boolean(false, 'Trim the empty lines from the tail of a node'),
|
||||
trim_lines: CF.boolean(false, 'Trim lines'),
|
||||
}, 'Text tree settings');
|
||||
|
||||
|
||||
export class Text_Tree_Node {
|
||||
constructor(text_tree_settings, line=undefined, indent=0, line_no=undefined, index=undefined, raw=undefined, parent=undefined) {
|
||||
Object.assign(this, { text_tree_settings, line, indent, line_no, index, raw, parent, children: [] });
|
||||
}
|
||||
|
||||
static from_string(text_settings, str) {
|
||||
get has_line() {
|
||||
return string_has_contents(this.line);
|
||||
}
|
||||
|
||||
const root = new this(text_settings);
|
||||
|
||||
static from_string(text_tree_settings, str) {
|
||||
|
||||
const root = new this(text_tree_settings);
|
||||
const { trim_head, trim_tail, trim_lines } = text_tree_settings;
|
||||
|
||||
// NOTE: This first Text_Node is not added to the tree, it serves as an initial cursor only.
|
||||
let current = new this(root.text_settings, undefined, 0, undefined, undefined, undefined, root);
|
||||
let current = new this(root.text_tree_settings, undefined, 0, undefined, undefined, undefined, root);
|
||||
|
||||
|
||||
for (const line_info of indented_line_iterator(text_settings, str)) {
|
||||
for (const line_info of indented_line_iterator(text_tree_settings.text, str)) {
|
||||
|
||||
// TODO: Implement other variants than inherit-from-previous
|
||||
const indent = string_has_contents(line_info.line) ? line_info.indent : current.indent;
|
||||
@@ -21,14 +38,14 @@ export class Text_Node {
|
||||
const delta_indent = indent - current.indent;
|
||||
|
||||
if (delta_indent == 0) {
|
||||
const pending = new Text_Node(current.text_settings, undefined, current.indent, undefined, undefined, undefined, current.parent); // Partial insertion - same level
|
||||
const pending = new this(current.text_tree_settings, undefined, current.indent, undefined, undefined, undefined, current.parent); // Partial insertion - same level
|
||||
if (current.parent) {
|
||||
current.parent.children.push(pending);
|
||||
}
|
||||
current = pending;
|
||||
} else if (delta_indent > 0) {
|
||||
for (let i=0; i<delta_indent; i++) {
|
||||
const pending = new Text_Node(current.text_settings, undefined, current.indent + 1, undefined, undefined, undefined, current); // Partial insertion
|
||||
const pending = new this(current.text_tree_settings, undefined, current.indent + 1, undefined, undefined, undefined, current); // Partial insertion
|
||||
current.children.push(pending);
|
||||
current = pending;
|
||||
}
|
||||
@@ -37,7 +54,7 @@ export class Text_Node {
|
||||
current = current.parent;
|
||||
}
|
||||
|
||||
const pending = new Text_Node(current.text_settings, undefined, current.indent, undefined, undefined, undefined, current.parent); // Partial insertion - same level
|
||||
const pending = new this(current.text_tree_settings, undefined, current.indent, undefined, undefined, undefined, current.parent); // Partial insertion - same level
|
||||
if (current.parent) {
|
||||
current.parent.children.push(pending);
|
||||
}
|
||||
@@ -46,7 +63,7 @@ export class Text_Node {
|
||||
|
||||
// Fill in partial insertion
|
||||
Object.assign(current, {
|
||||
line: line_info.line,
|
||||
line: trim_lines ? line_info.line.trim() : line_info.line,
|
||||
line_no: line_info.line_no,
|
||||
index: line_info.index,
|
||||
raw: line_info.raw,
|
||||
@@ -54,6 +71,12 @@ export class Text_Node {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (trim_head || trim_tail) { //TODO: Implement
|
||||
throw new Error('Trimming is not implemented'); //TODO: Proper non implemented error
|
||||
}
|
||||
|
||||
return root;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user