130 lines
3.5 KiB
TypeScript
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;
|
|
}
|
|
} |