OK, so I'm considering three options to "upgrade" TF.ahk to also process strings (vars) and not just textfiles.
a) create a string library with similar functions and possibly make TF.ahk a wrapper for the string lib
b) Currently ! is used to indicate overwrite the source file or not, I could simply introduce ? (or other char) to indicate something is a var but that would preclude vars starting with a ?
c) the solution below where I added a function that tries to determine if something is a file or a variable and act accordingly. Before upgrading the entire library I would like to have some feedback and suggestions, you can try the code below indepently of the lib as I've changed some of the (internal) function names, as a test I used the RemoveLines function.
New: TF_FileOrVar (suggestions? I could perhaps also check if TextFile has contents to determine if it is a var, if it is empty it is a file)
The code marked in red could probably be condensed a bit
Code:
; script for testing & feedback so I can upgrade TF.AHK to also work with strings
F=
(join`n
!1bla
2bla
3bla
4bla
5bla
6bla
7bla
8bla
9bla
0bla
)
FileDelete, testfile.txt
FileAppend, %f%, testfile.txt
TXT_RemoveLines("testfile.txt", "2+2") ; will process testfile.txt and create testfile_copy.txt
;TXT_RemoveLines("!testfile.txt", "2+2") ; will process testfile.txt and overwrite it
;MsgBox % TXT_RemoveLines(F, "2+2") ; will process the var F and return var, no files will be created
TXT_RemoveLines(TextFile, StartLine = 1, EndLine = 0) ; HugoV
{
OW:=TF_FileOrVar(TextFile) ; find out if it is a file, if so find out to overwrite or not, or is it a variable
If (OW = 0) or (OW = 1)
{
TextFile := (SubStr(TextFile,1,1)="!") ? (SubStr(TextFile,2)) : TextFile
FileRead, Str, %TextFile%
}
Else
{
Str:=TextFile
TextFile= ; free memory because TextFile is a var
}
TXT_MatchList:=__MakeMatchList_(Str, StartLine, EndLine) ; create MatchList
Loop, Parse, Str, `n, `r
{
If A_Index in %TXT_MatchList%
Continue
Else
OutPut .= A_LoopField "`n"
}
Return (OW = 1) ? __OverWrite_(TextFile, Output) : (OW = 0) ? __MakeCopy_(TextFile, Output) : Output
}
TF_FileOrVar(byref TextFile) ; HugoV, to determine if VAR or FILE is passed to TF
{
OW=0 ; default setting: asume it is a file and create textfile_copy
If (SubStr(TextFile,1,1)="!") ; first we check for "overwrite"
{
TextFile:=SubStr(TextFile,2)
OW=1 ; overwrite file (if it is a file)
}
IfNotExist, %TextFile% ; now we can check if the file exists
{
If (OW=1) ; the variable started with a ! so we need to put it back because it is variable not a file
TextFile:= "!" . TextFile
OW=2 ; no file, so it is var
}
Return OW
}
; YOU CAN IGNORE THE REST PURELY INCLUDED AS NOT TO CONFLICT WITH TF.AHK IN LIB
; OverWrite TextFile by Heresy / Hugov
__OverWrite_(File, String, TrimTrailing = 1, CreateNewFile = 0)
{
IfNotExist, % File ; check if file Exist, if not return otherwise it would create an empty file. Thanks for the idea Murp|e
{
If (CreateNewFile = 0) ; CreateNewFile used for TF_SplitFileBy*,
Return
}
If (TrimTrailing = 1)
StringTrimRight, String, String, 1 ; remove trailing `n
SplitPath, File,, Dir, Ext, Name
If (Dir = "") ; if Dir is empty TextFile & script are in same directory
Dir := A_ScriptDir
IfExist, % Dir "\backup" ; if there is a backup dir, copy original file there
FileCopy, % Dir "\" Name "." Ext, % Dir "\backup\" Name ".bak", 1
FileDelete, % Dir "\" Name "." Ext
FileAppend, %String%, % Dir "\" Name "." Ext
Return Errorlevel ? False : True
}
; Make textfile_copy by Heresy / Hugov
__MakeCopy_(File, String, TrimTrailing = 1)
{
IfNotExist, % File ; check if file Exist, if not return otherwise it would create an empty file. Thanks for the idea Murp|e
Return
If (TrimTrailing = 1)
StringTrimRight, String, String, 1 ; remove trailing `n
SplitPath, File,, Dir, Ext, Name
If (Dir = "") ; if Dir is empty TextFile & script are in same directory
Dir := A_ScriptDir
IfExist, % Dir "\backup" ; if there is a backup dir, copy original file there
FileCopy, % Dir "\" Name "_copy." Ext, % Dir "\backup\" Name "_copy.bak", 1
FileDelete, % Dir "\" Name "_copy." Ext
FileAppend, %String%, % Dir "\" Name "_copy." Ext
Return Errorlevel ? False : True
}
__MakeMatchList_(TextFile, Start = 1, End = 0)
{
TXT_MatchList= ; just to be sure
If (Start = 0 or Start = "")
Start = 1
; Option #1
; StartLine has + character indicating startline + incremental processing.
; EndLine will be used
; Make TXT_MatchList
IfInString, Start, +
{
If (End = 0 or End = "")
End := _TXT_CountLines(TextFile)
StringSplit, Section, Start, `, ; we need to create a new "TXT_MatchList" so we split by ,
Loop, %Section0%
{
StringSplit, SectionLines, Section%A_Index%, `+
LoopSection:=End + 1 - SectionLines1
Counter=0
TXT_MatchList .= SectionLines1 ","
Loop, %LoopSection%
{
If (A_Index >= End) ;
Break
If (Counter = (SectionLines2-1)) ; counter is smaller than the incremental value so skip
{
TXT_MatchList .= (SectionLines1 + A_Index) ","
Counter=0
}
Else
Counter++
}
}
StringTrimRight, TXT_MatchList, TXT_MatchList, 1 ; remove trailing ,
Return TXT_MatchList
}
; Option #2
; StartLine has - character indicating from-to, COULD be multiple sections.
; EndLine will be ignored
; Make TXT_MatchList
IfInString, Start, `-
{
StringSplit, Section, Start, `, ; we need to create a new "TXT_MatchList" so we split by ,
Loop, %Section0%
{
StringSplit, SectionLines, Section%A_Index%, `-
LoopSection:=SectionLines2 + 1 - SectionLines1
Loop, %LoopSection%
{
TXT_MatchList .= (SectionLines1 - 1 + A_Index) ","
}
}
StringTrimRight, TXT_MatchList, TXT_MatchList, 1 ; remove trailing ,
Return TXT_MatchList
}
; Option #3
; StartLine has comma indicating multiple lines.
; EndLine will be ignored
IfInString, Start, `,
{
TXT_MatchList:=Start
Return TXT_MatchList
}
; Option #3
; parameters passed on as StartLine, EndLine.
; Make TXT_MatchList from StartLine to EndLine
If (End = 0 or End = "") ; determine nr of lines
End:=_TXT_CountLines(TextFile)
LoopTimes:=End-Start
Loop, %LoopTimes%
{
TXT_MatchList .= (Start - 1 + A_Index) ","
}
TXT_MatchList .= End ","
StringTrimRight, TXT_MatchList, TXT_MatchList, 1 ; remove trailing ,
Return TXT_MatchList
}
_TXT_CountLines(Str) ; was TotalLines in v1
{
StringReplace, Str, Str, `n, `n, UseErrorLevel
Return ErrorLevel+1
}
Test reports and suggestions welcome