als-replace-between
Advanced tools
Comparing version 3.3.0 to 3.3.1
{ | ||
"name": "als-replace-between", | ||
"version": "3.3.0", | ||
"version": "3.3.1", | ||
"main": "index.js", | ||
@@ -5,0 +5,0 @@ "scripts": { |
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('')} 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 } } } | ||
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; this.before = ''; this.after = ''} 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.walkNodes(modifiers,child) this.runModifiers(modifiers,child,true) }); } 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 if(isNode) this.walk(modifiers,child) this.runModifiers(modifiers,child,isNode) }); } 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 } | ||
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 } | ||
class ReplaceBetween extends BaseNode { constructor(content, startR, endR) { super() if (typeof content !== 'string') throw `Expected 'content' to be a string, but got '${typeof content}'` if (startR instanceof RegExp == false) throw '"startR" should be an instance of RegExp.' if (endR instanceof RegExp == false) throw '"endR" should be an instance of RegExp.' this.content = content this.startR = startR this.endR = endR this.build() } build() { const { content, startR, endR } = this const starts = find(content, startR, -1) const ends = find(content, endR, 1) if(starts.length === 0 || ends.length === 0) return const children = buildTree(starts, ends) if(children.length === 0) return const start = children[0].start.n const end = children[children.length - 1].end.n this.before = start > 0 ? content.slice(0, start) : '' this.after = end < content.length ? content.slice(end, content.length) : '' children.forEach((child,i) => { this.children.push(new Node(this, child, this)) if(i === children.length-1) return const nextStart = children[i+1].start.n const curendEnd = child.end.n if(nextStart !== curendEnd) { this.children.push(new TextNode(content.slice(curendEnd,nextStart),this)) } }); } } | ||
class Node extends BaseNode { constructor(root, obj, parent = null) { super() this.parent = parent if(parent) this.index = parent.children.length this.root = root this.addChildren(obj) } addChildren(obj) { const { start, end, children } = obj const root = this.root let curStart = start.n + start.length, curEnd = end.n - end.length this.open = root.content.slice(start.n, curStart) children.forEach((child,i) => { if(child.start.n > curStart) this.children.push(new TextNode(root.content.slice(curStart, child.start.n),this)) this.children.push(new Node(root, child, this)) curStart = child.end.n }); if(curEnd > curStart) this.children.push(new TextNode(root.content.slice(curStart,curEnd),this)) this.close = root.content.slice(curEnd, end.n) return this } get outer() {return this.open + this.inner + this.close} get prev() {return this.parent ? this.parent.children[this.index - 1] : null} get next() {return this.parent ? this.parent.children[this.index + 1] : null} } | ||
class Node extends BaseNode { constructor(root, obj, parent = null) { super() this.parent = parent if(parent) this.index = parent.children.length this.root = root this.addChildren(obj) } addChildren(obj) { const { start, end, children } = obj const root = this.root let curStart = start.n + start.length, curEnd = end.n - end.length this.open = root.content.slice(start.n, curStart) children.forEach((child,i) => { if(child.start.n > curStart) this.children.push(new TextNode(root.content.slice(curStart, child.start.n),this)) this.children.push(new Node(root, child, this)) curStart = child.end.n }); if(curEnd > curStart) this.children.push(new TextNode(root.content.slice(curStart,curEnd),this)) this.close = root.content.slice(curEnd, end.n) return this } 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} get next() {return this.parent ? this.parent.children[this.index + 1] : null} } | ||
class TextNode { constructor(content,parent) { this.outer = content this.parent = parent if(parent) this.index = parent.children.length this.open = '' this.close = '' } get prev() {return this.parent.children[this.index - 1] || null} get next() {return this.parent.children[this.index + 1] || null} } | ||
return ReplaceBetween | ||
})() |
46584
632