library-ts/browser/text/replacing/TextSelector.ts

130 lines
3.5 KiB
TypeScript

import { TextSelectionRange } from "./TextSelectionRange";
import { RegExpUtility } from "../RegExpUtitlity";
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;*/
return this.inner;
}
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;
}
}