als-replace-between
Advanced tools
Comparing version 3.1.0 to 3.2.0
@@ -0,1 +1,3 @@ | ||
const TextNode = require('./text-node') | ||
class BaseNode { | ||
@@ -5,2 +7,4 @@ constructor() {this.children = []} | ||
get inner() {return this.children.map(child => child.outer).join('')} | ||
set outer(value) {this.inner = value; this.before = ''; this.after = ''} | ||
set inner(value) {this.children = []; this.children.push(new TextNode(value,this))} | ||
@@ -7,0 +11,0 @@ walkNodes(modifiers=[],parent = this) { |
@@ -29,2 +29,3 @@ const TextNode = require('./text-node') | ||
get outer() {return this.open + this.inner + this.close} | ||
set outer(value) {this.inner = value; this.open = ''; this.close = ''} | ||
get prev() {return this.parent ? this.parent.children[this.index - 1] : null} | ||
@@ -31,0 +32,0 @@ get next() {return this.parent ? this.parent.children[this.index + 1] : null} |
{ | ||
"name": "als-replace-between", | ||
"version": "3.1.0", | ||
"version": "3.2.0", | ||
"main": "index.js", | ||
@@ -5,0 +5,0 @@ "scripts": { |
@@ -176,2 +176,4 @@ # als-replace-between | ||
- `get inner()`: A getter that returns the full content without `before` and `after`. | ||
- `set inner(value)`: replace all children with single TextNode including value | ||
- `set inner(value)`: sets inner and assigns empty string to before and after | ||
- `walk([functions])`: A method that applies one or more modifier functions to every node and text node within the structure. | ||
@@ -181,6 +183,8 @@ - `walkNodes([functions])`: Same as `walk`, but only for nodes. | ||
1. **Node**: Represents a segment of content with potential nested structure. Each `Node` includes: | ||
2. **Node**: Represents a segment of content with potential nested structure. Each `Node` includes: | ||
- `children`: An array of child nodes that may contain further nested `Node` or `TextNode` objects. | ||
- `outer`: Getter that returns the complete content of the node including all children. | ||
- `inner`: Getter that returns only the content inside this node, excluding any wrappers or nested structures. | ||
- `set inner(value)`: replace all children with single TextNode including value | ||
- `set inner(value)`: sets inner and assigns empty string to open and close | ||
- `prev()`: A getter for the previous sibling node. | ||
@@ -190,3 +194,3 @@ - `next()`: A getter for the next sibling node. | ||
2. **TextNode**: Represents plain text within or between nodes. It includes: | ||
3. **TextNode**: Represents plain text within or between nodes. It includes: | ||
- `outer`: The text content of this node. | ||
@@ -193,0 +197,0 @@ - `prev()`: A getter for the previous sibling node or text node. |
const ReplaceBetween = (function() { | ||
class BaseNode { constructor() {this.children = []} get outer() { return this.before + this.inner + this.after } get inner() {return this.children.map(child => child.outer).join('')} walkNodes(modifiers=[],parent = this) { parent.children.forEach(child => { if(child instanceof BaseNode === false) return this.runModifiers(modifiers,child,true) this.walkNodes(modifiers,child) }); } walkTextNodes(modifiers=[],parent = this) { parent.children.forEach(child => { if(child instanceof BaseNode) this.walkTextNodes(modifiers,child) else this.runModifiers(modifiers,child,false) }); } walk(modifiers=[],parent = this) { parent.children.forEach(child => { const isNode = child instanceof BaseNode const result = this.runModifiers(modifiers,child,isNode) if(isNode && result !== false) this.walk(modifiers,child) }); } runModifiers(modifiers,child,isNode) { for(const modifier of modifiers) { const result = modifier(child,isNode) if(result === false) return false } } } | ||
class BaseNode { constructor() {this.children = []} get outer() { return this.before + this.inner + this.after } get inner() {return this.children.map(child => child.outer).join('')} set outer(value) { this.inner = value; ['open','close','before','after'].forEach(prop => {if(this[prop]) this[prop] = ''}) } set inner(value) {this.children = []; this.children.push(new TextNode(value,this));} walkNodes(modifiers=[],parent = this) { parent.children.forEach(child => { if(child instanceof BaseNode === false) return this.runModifiers(modifiers,child,true) this.walkNodes(modifiers,child) }); } walkTextNodes(modifiers=[],parent = this) { parent.children.forEach(child => { if(child instanceof BaseNode) this.walkTextNodes(modifiers,child) else this.runModifiers(modifiers,child,false) }); } walk(modifiers=[],parent = this) { parent.children.forEach(child => { const isNode = child instanceof BaseNode const result = this.runModifiers(modifiers,child,isNode) if(isNode && result !== false) this.walk(modifiers,child) }); } runModifiers(modifiers,child,isNode) { for(const modifier of modifiers) { const result = modifier(child,isNode) if(result === false) return false } } } | ||
function buildTree(starts, ends) { if(starts[0].n > ends[0].n) ends.shift() if(starts[starts.length-1].n > ends[ends.length-1].n) starts.pop() if (starts.length !== ends.length) throw new Error(`Parsing error: unmatched tags detected. (${starts.length},${ends.length})`); let pairs = starts.map((start, i) => ({ start, end: ends[i], children: [] })); pairs.forEach((curPair, i) => { for (let k = i; k < pairs.length; k++) { if (curPair.end.n > pairs[k].start.n) { const end = pairs[k].end const curEnd = curPair.end curPair.end = end pairs[k].end = curEnd } } }) pairs.sort((a, b) => a.end.n - b.end.n); pairs.forEach((curPair, i) => { for (let k = i; k < pairs.length; k++) { if (curPair.start.n > pairs[k].start.n && curPair.end.n < pairs[k].end.n) { if (!curPair.level) curPair.level = 0 curPair.level++ pairs[k].children.push(curPair) } } }); function filterPairs(pairs, curLevel = 0) { pairs = pairs.filter(({ level }) => (!level || level <= curLevel)) pairs.forEach(pair => { if (pair.children.length === 0) return pair.children = filterPairs(pair.children, curLevel + 1) }); return pairs } pairs = filterPairs(pairs) return pairs } | ||
@@ -4,0 +4,0 @@ function find(string, r, add, offset = 0) { const arr = [] while (true) { const match = string.match(r) if (!match) break offset += match.index + 1 const n = add < 0 ? add : add * (match[0].length - 1) arr.push({n:offset + n,length:match[0].length}) string = string.slice(match.index + 1) } return arr } |
@@ -158,2 +158,25 @@ const { describe, it, beforeEach } = require('node:test') | ||
}) | ||
describe('inner and outer setters', () => { | ||
it('root inner', () => { | ||
const content = "<body><div><span>span 1</span></div><div><span>span 2</span></div></body>"; | ||
const result = new ReplaceBetween(content, /<\w*>/, /<\/\w*>/); | ||
result.inner = 'test' | ||
assert(result.outer === 'test') | ||
}); | ||
it('node inner', () => { | ||
const content = "<body><div><span>span 1</span></div><div><span>span 2</span></div></body>"; | ||
const result = new ReplaceBetween(content, /<\w*>/, /<\/\w*>/); | ||
result.children[0].inner = 'test' | ||
assert(result.outer === '<body>test</body>') | ||
}); | ||
it('node outer', () => { | ||
const content = "<body><div><span>span 1</span></div><div><span>span 2</span></div></body>"; | ||
const result = new ReplaceBetween(content, /<\w*>/, /<\/\w*>/); | ||
result.children[0].outer = 'test' | ||
assert(result.outer === 'test') | ||
}); | ||
}) |
47851
643
359