import { RegExpUtility } from "../RegExpUtility"; import { TextSelectionRange } from "./TextSelectionRange"; import { ColorConsole } from "../../node/ColorConsole"; export abstract class TextSelector { abstract select( source:string ):TextSelectionRange[] } export class RegexStartEndSelector extends TextSelector { startRegex:RegExp; endRegex:RegExp; inner:boolean = false; multiple:boolean = true; maxRanges:number = 100; toString() { let start = ColorConsole.fg( this.startRegex.source, ColorConsole.red ); let end = ColorConsole.fg( this.endRegex.source, ColorConsole.red ); let info = `RegexSelector{${start} ${end} ${this.multiple?"multiple":""} ${this.inner?"inner":""}}`; return info; } select( source:string ) { this.startRegex = RegExpUtility.makeGlobal( this.startRegex ); this.endRegex = RegExpUtility.makeGlobal( this.endRegex ); if ( this.multiple ) { return this.selectMultiple( source ); } let range = TextSelectionRange.fromString( source ); this.startRegex.lastIndex = 0; this.endRegex.lastIndex = 0; let startResult = this.startRegex.exec( source ); if ( startResult ) { range.start = this.inner ? ( startResult.index + startResult[ 0 ].length ) : startResult.index; } else { console.log( "Start not found: ", this.startRegex, source.substring( 0, Math.min( source.length,100 ) ) ); } let endResult = this.endRegex.exec( source ); if ( endResult ) { range.end = this.inner ? endResult.index : ( endResult.index + endResult[ 0 ].length ); } else { console.log( "End not found: ", this.endRegex, source.substring( 0, Math.min( source.length,100 ) ) ); } return [ range ]; } selectMultiple( source:string ):TextSelectionRange[] { let ranges:TextSelectionRange[] = []; let currentIndex = -1; let searching = true; let currentElements = 0; while ( searching && currentElements < this.maxRanges ) { let starterIndex = Math.max( 0, currentIndex ); this.startRegex.lastIndex = starterIndex; let startResult = this.startRegex.exec( source ); if ( ! startResult || startResult.index <= currentIndex ) { if ( startResult ) { console.log( "Start Index invalid:", currentIndex, startResult.index ); } searching = false; break; } this.endRegex.lastIndex = startResult.index + startResult[ 0 ].length; let endResult = this.endRegex.exec( source ); if ( ! endResult || endResult.index <= currentIndex ) { if ( endResult ) { console.log( "End Index invalid:", currentIndex, endResult.index ); } searching = false; break; } let range = new TextSelectionRange(); range.start = this.inner ? ( startResult.index + startResult[ 0 ].length ) : startResult.index; range.end = this.inner ? endResult.index : ( endResult.index + endResult[ 0 ].length ); ranges.push( range ); currentIndex = endResult.index + endResult[ 0 ].length; searching = currentIndex < source.length; currentElements ++; } if ( ranges.length === 0 ) { console.log( "No ranges found!" ); ranges.push( TextSelectionRange.fromString( source ) ); } return ranges; } }