I complicated the code, now 2 search options work, by tags and by files.
Code: Select all
; AZJIO 02.09.2023
EnableExplicit
#Window = 0
#WinSet = 1
#Menu = 0
#Menu2 = 1
#Menu3 = 2
;- Перечисление
Enumeration
#WebG
#StrG
#btnClear
#StrSearchAll
#btnAll
#btnDown
#btnDown1
#ch1
#ch2
#ch3
#ch4
#Op1
#Op2
#Op3
#btnOK
#btnCancel
#btnMenu
EndEnumeration
Structure LFiles
File.s
title.s
EndStructure
;- Global
Global ww, hh
Global g_is_Found, g_CountF
Global SearchText$, SearchAll$, g_re, g_flgMenu
Global Dim aStr$(0)
Global Dim aStrF$(0)
Global NewList LFiles.LFiles()
Global my_re
Global g_Case
Global g_flgSearch = 2
Global g_Title = 1
Global g_Header = 1
Global g_Highlight = 1
Global g_rehght
Global g_re_h1
ExamineDesktops()
ww = DesktopWidth(0)
hh = DesktopHeight(0)
If ww < 60 Or hh < 60
End
EndIf
Procedure btnMenu()
g_flgMenu = 3
DisplayPopupMenu(#Menu3, WindowID(#Window), 0, 31)
EndProcedure
Procedure btnClear()
SetGadgetText(#StrG, "")
EndProcedure
Procedure EventsMenu()
Protected eMenu, tmp$
eMenu = EventMenu()
If g_flgMenu = 1
If IsMenu(#Menu)
If eMenu <= ArraySize(aStr$())
tmp$ = StringField(aStr$(eMenu), 3, "|")
If Asc(tmp$)
SetGadgetText(#WebG, "./data/" + tmp$ + ".htm")
EndIf
EndIf
EndIf
ElseIf g_flgMenu = 2
If IsMenu(#Menu2)
If eMenu <= ListSize(LFiles())
SelectElement(LFiles(), eMenu)
If Asc(LFiles()\File)
SetGadgetText(#WebG, LFiles()\File)
EndIf
EndIf
EndIf
ElseIf g_flgMenu = 3
Select eMenu
Case 0
SetGadgetText(#WebG, "./data/index.htm")
Case 1
HideWindow(#WinSet, #False)
SetActiveWindow(#WinSet)
StickyWindow(#WinSet, #True)
Case 2
SetGadgetText(#WebG, "./data/p/use.htm")
Case 3
MessageRequester("Автор AZJIO" + #LF$ + "v 1.0.1.0" + #LF$ + "02.09.2023")
EndSelect
EndIf
EndProcedure
Procedure StrG()
Protected String$, CountFound, i
If EventType() = #PB_EventType_Change
String$ = GetGadgetText(#StrG)
If Len(String$) > 1 And g_is_Found
If CreateRegularExpression(0, "^[^|]*?" + String$ + ".+?\r?$", #PB_RegularExpression_AnyNewLine | #PB_RegularExpression_NoCase | #PB_RegularExpression_MultiLine)
CountFound = ExtractRegularExpression(0, SearchText$ + #CRLF$, aStr$())
FreeRegularExpression(0)
EndIf
If CountFound
If IsMenu(#Menu)
FreeMenu(#Menu)
EndIf
CreatePopupMenu(#Menu)
For i = 0 To CountFound - 1
MenuItem(i, StringField(aStr$(i), 2, "|"))
Next
g_flgMenu = 1
DisplayPopupMenu(#Menu, WindowID(#Window), 0, 31)
EndIf
EndIf
EndIf
EndProcedure
Procedure ReadCallbackAllText(Status, Filename$, File, Size)
Protected Format, SearchText3$, CountFound, pos, name$, Found
Protected Dim aTitle$(0)
If Status = #PB_Status_Loaded
Format = #PB_UTF8
SearchText3$ = ReadString(File, Format | #PB_File_IgnoreEOL)
CloseFile(File)
If Asc(SearchText3$)
!v_found = v_my_re.test(v_searchtext3$)
If Found
If g_re
If ExtractRegularExpression(g_re, SearchText3$, aTitle$())
If AddElement(LFiles())
LFiles()\File = Filename$
LFiles()\title = aTitle$(0)
If g_Highlight
MenuItem(ListSize(LFiles()) - 1, ReplaceString(LFiles()\title, SearchAll$, "<font color=#89F>" + SearchAll$ + "</font>", #PB_String_NoCase))
Else
MenuItem(ListSize(LFiles()) - 1, LFiles()\title)
EndIf
EndIf
Else
If AddElement(LFiles())
LFiles()\File = Filename$
name$ = Filename$
Repeat
pos = FindString(name$, "/")
If pos
name$ = Mid(name$, pos + 1)
EndIf
Until Not pos
pos = FindString(name$, ".htm")
If pos
name$ = Mid(name$, 1, pos - 1)
EndIf
LFiles()\title = name$
If g_Highlight
MenuItem(ListSize(LFiles()) - 1, ReplaceString(LFiles()\title, SearchAll$, "<font color=#89F>" + SearchAll$ + "</font>", #PB_String_NoCase))
Else
MenuItem(ListSize(LFiles()) - 1, LFiles()\title)
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
ElseIf Status = #PB_Status_Error
; Debug Filename$
EndIf
EndProcedure
Procedure ReadCallbackTitle(Status, Filename$, File, Size)
Protected Format, SearchText3$, name$, Found, name2$, i, CountH1
Protected Dim aTitle$(0)
If Status = #PB_Status_Loaded
Format = #PB_UTF8
SearchText3$ = ReadString(File, Format | #PB_File_IgnoreEOL)
CloseFile(File)
If Asc(SearchText3$)
; If Len(SearchText3$)
If g_re
If g_Title
FreeArray(aTitle$())
If ExtractRegularExpression(g_re, SearchText3$, aTitle$()) ; !title$ = searchtext3$SearchText3$.match(g_re)
name$ = " " + aTitle$(0) + " " ; пробелы чтобы поиск мог искать от начала строки, там запрашивается символ не слова
; !a_name$.array[0]="dsfg";
; !v_found = v_my_re.test(a_atitle$.array[0])
; Found, name$
!v_found = v_my_re.test(v_name$)
If Found
; Debug name$
If AddElement(LFiles())
LFiles()\File = Filename$
LFiles()\title = aTitle$(0)
If g_Highlight
; MenuItem(ListSize(LFiles()) - 1, ReplaceString(LFiles()\title, SearchAll$, "<font color=#89F>" + SearchAll$ + "</font>", #PB_String_NoCase))
LFiles()\title = ReplaceRegularExpression(g_rehght, LFiles()\title, "<font color=#00F7FF>$1</font>")
EndIf
MenuItem(ListSize(LFiles()) - 1, "<font color=#FFFF00>" + Chr($25CF) + "</font> " + LFiles()\title)
EndIf
EndIf
EndIf
EndIf
; H1- H4
If g_Header
FreeArray(aTitle$())
CountH1 = ExtractRegularExpression(g_re_h1, SearchText3$, aTitle$()) ; !title$ = searchtext3$SearchText3$.match(g_re_h1)
If CountH1
For i = 0 To CountH1 - 1
; If aTitle$(i) = aTitle$(i-1)
; Continue
; EndIf
name$ = " " + aTitle$(i) + " " ; пробелы чтобы поиск мог искать от начала строки, там запрашивается символ не слова
!v_found = v_my_re.test(v_name$)
If Found
If AddElement(LFiles())
LFiles()\File = Filename$
LFiles()\title = aTitle$(i)
If g_Highlight
; MenuItem(ListSize(LFiles()) - 1, ReplaceString(LFiles()\title, SearchAll$, "<font color=#89F>" + SearchAll$ + "</font>", #PB_String_NoCase))
LFiles()\title = ReplaceRegularExpression(g_rehght, LFiles()\title, "<font color=#00F7FF>$1</font>")
EndIf
MenuItem(ListSize(LFiles()) - 1, #TAB$ + "<font color=#00FF00>" + Chr($25CB) + "</font> " + LFiles()\title)
EndIf
EndIf
Next
EndIf
EndIf
EndIf
EndIf
ElseIf Status = #PB_Status_Error
; Debug Filename$
EndIf
EndProcedure
Procedure btnAll()
Protected i, flgSearch$
SearchAll$ = GetGadgetText(#StrSearchAll)
If Len(SearchAll$) > 1 And g_CountF
If Not g_re
g_re = CreateRegularExpression(#PB_Any, "(?<=<title>)([^<>]+?)(?=</title>)", #PB_RegularExpression_AnyNewLine | #PB_RegularExpression_NoCase)
EndIf
If Not g_re_h1
g_re_h1 = CreateRegularExpression(#PB_Any, "(?<=<h(\d)>)([^<>]+?)(?=</h\1>)", #PB_RegularExpression_AnyNewLine | #PB_RegularExpression_NoCase)
EndIf
If g_Highlight
; g_rehght = CreateRegularExpression(#PB_Any, "(.*?)(" + SearchAll$ + ")(.*?)", #PB_RegularExpression_AnyNewLine | #PB_RegularExpression_NoCase)
; g_rehght = CreateRegularExpression(#PB_Any, "(" + SearchAll$ + ")", #PB_RegularExpression_AnyNewLine | #PB_RegularExpression_NoCase)
Select g_flgSearch
Case 1 ; целое слово
g_rehght = CreateRegularExpression(#PB_Any, "(?<![а-яё])(" + SearchAll$ + ")(?![а-яё])", #PB_RegularExpression_AnyNewLine | #PB_RegularExpression_NoCase)
Case 2 ; от начала
g_rehght = CreateRegularExpression(#PB_Any, "(?<![а-яё])(" + SearchAll$ + ")", #PB_RegularExpression_AnyNewLine | #PB_RegularExpression_NoCase)
Case 4 ; учёт регистра
g_rehght = CreateRegularExpression(#PB_Any, "(" + SearchAll$ + ")", #PB_RegularExpression_AnyNewLine | #PB_RegularExpression_NoCase)
EndSelect
EndIf
If IsMenu(#Menu2)
FreeMenu(#Menu2)
EndIf
FreeList(LFiles())
CreatePopupMenu(#Menu2)
If g_Case ; убрал "g" в обоих случаях, так как он не нужен и был замечен глюк с чередованием найденных через одного.
flgSearch$ = ""
Else
flgSearch$ = "i"
EndIf
Select g_flgSearch
Case 1 ; целое слово
!v_my_re = new RegExp('[^а-яё]' + v_searchall$ + '[^а-яё]', v_flgsearch$);
Case 2 ; от начала
!v_my_re = new RegExp('[^а-яё]' + v_searchall$, v_flgsearch$);
Case 4 ; учёт регистра
!v_my_re = new RegExp(v_searchall$, v_flgsearch$);
EndSelect
For i = 0 To g_CountF - 1
If g_Title Or g_Header
ReadFile(#PB_Any, "./data/" + aStrF$(i) + ".htm", @ReadCallbackTitle())
Else
ReadFile(#PB_Any, "./data/" + aStrF$(i) + ".htm", @ReadCallbackAllText())
EndIf
Next
g_flgMenu = 2
; If ListSize(LFiles()) = 0
; If AddElement(LFiles())
; LFiles()\File = ""
; LFiles()\title = "Ничего не найдено"
; MenuItem(ListSize(LFiles()) - 1, LFiles()\title)
; EndIf
; EndIf
DisplayPopupMenu(#Menu2, WindowID(#Window), 0, 31)
EndIf
EndProcedure
Procedure btnDown1()
If IsMenu(#Menu)
g_flgMenu = 1
DisplayPopupMenu(#Menu, WindowID(#Window), 0, 31)
EndIf
EndProcedure
Procedure btnDown()
If IsMenu(#Menu2)
g_flgMenu = 2
DisplayPopupMenu(#Menu2, WindowID(#Window), 0, 31)
Else
btnAll()
EndIf
EndProcedure
Procedure SizeWindowHandler()
ExamineDesktops()
ww = DesktopWidth(0)
hh = DesktopHeight(0)
ResizeWindow(#Window, #PB_Ignore, #PB_Ignore, ww, hh)
ResizeGadget(#WebG, #PB_Ignore, #PB_Ignore, ww, hh)
EndProcedure
Procedure ReadCallbackS(Status, Filename$, File, Size)
Protected Format
If Status = #PB_Status_Loaded
; Debug "|" + Filename$ + "|"
; Debug Size
; Debug "File: " + Filename$ + " - Size: " + Size + " bytes"
Format = ReadStringFormat(File)
SearchText$ = ReadString(File, Format | #PB_File_IgnoreEOL)
CloseFile(File)
If Asc(SearchText$)
g_is_Found = 1
Else
g_is_Found = 0
HideGadget(#StrG, #True)
EndIf
ElseIf Status = #PB_Status_Error
g_is_Found = 0
HideGadget(#StrG, #True)
EndIf
EndProcedure
; открывает файл f.txt, содержащий список файлов
Procedure ReadCallbackF(Status, Filename$, File, Size)
Protected Format, SearchTextF$, CountFound
If Status = #PB_Status_Loaded
; Debug "|" + Filename$ + "|"
; Debug Size
; Debug "File: " + Filename$ + " - Size: " + Size + " bytes"
Format = ReadStringFormat(File)
SearchTextF$ = ReadString(File, Format | #PB_File_IgnoreEOL)
CloseFile(File)
g_CountF = 0
If Asc(SearchTextF$)
If CreateRegularExpression(0, "^.+?\r?$", #PB_RegularExpression_AnyNewLine | #PB_RegularExpression_NoCase | #PB_RegularExpression_MultiLine)
CountFound = ExtractRegularExpression(0, SearchTextF$ + #CRLF$, aStrF$())
FreeRegularExpression(0)
If CountFound
g_CountF = CountFound
EndIf
EndIf
Else
g_CountF = 0
HideGadget(#StrSearchAll, #True)
EndIf
ElseIf Status = #PB_Status_Error
g_CountF = 0
HideGadget(#StrSearchAll, #True)
EndIf
EndProcedure
;- GUI
If OpenWindow(#Window, 0, 0, ww, hh, "", #PB_Window_Background)
WebGadget(#WebG, 0, 35, ww, hh - 35, "./data/index.htm")
ButtonGadget(#btnMenu, 0, 0, 30, 30, Chr($2630)))
StringGadget(#StrG, 35, 0, 80, 30, "Поиск тег", #PB_String_PlaceHolder)
ButtonGadget(#btnDown1, 110, 0, 30, 30, Chr($25BC))
ButtonGadget(#btnClear, 140, 0, 30, 30, "x")
StringGadget(#StrSearchAll, 180, 0, 120, 30, "Поиск, файлы", #PB_String_PlaceHolder)
ButtonGadget(#btnDown, 300, 0, 30, 30, Chr($25BC))
ButtonGadget(#btnAll, 330, 0, 60, 30, "Найти")
BindGadgetEvent(#StrG, @StrG())
BindGadgetEvent(#btnClear, @btnClear())
BindGadgetEvent(#btnMenu, @btnMenu())
BindGadgetEvent(#btnAll, @btnAll())
BindGadgetEvent(#btnDown, @btnDown())
BindGadgetEvent(#btnDown1, @btnDown1())
BindEvent(#PB_Event_SizeDesktop, @SizeWindowHandler())
BindEvent(#PB_Event_Menu, @EventsMenu())
ReadFile(#PB_Any, "./data/p/s.txt", @ReadCallbackS())
ReadFile(#PB_Any, "./data/p/f.txt", @ReadCallbackF())
If CreatePopupMenu(#Menu3)
MenuItem(0, "Домой")
MenuItem(1, "Настройки поиска файлов")
MenuItem(2, "Как пользоваться поиском")
MenuItem(3, "О программе")
EndIf
EndIf
Procedure Events()
Select Event()
Case #PB_Event_Gadget
Select EventGadget()
Case #btnOK
If GetGadgetState(#ch1) = #PB_Checkbox_Checked
g_Case = 1
Else
g_Case = 0
EndIf
If GetGadgetState(#ch2) = #PB_Checkbox_Checked
g_Title = 1
Else
g_Title = 0
EndIf
If GetGadgetState(#ch3) = #PB_Checkbox_Checked
g_Highlight = 1
Else
g_Highlight = 0
EndIf
If GetGadgetState(#ch4) = #PB_Checkbox_Checked
g_Header = 1
Else
g_Header = 0
EndIf
If GetGadgetState(#Op1) = 1
g_flgSearch = 1
ElseIf GetGadgetState(#Op2) = 1
g_flgSearch = 2
ElseIf GetGadgetState(#Op3) = 1
g_flgSearch = 4
EndIf
HideWindow(#WinSet, #True)
; Case #ch2
; If GetGadgetState(#ch2) = #PB_Checkbox_Unchecked
; SetGadgetState(#ch4, 0)
; EndIf
; Case #ch4
; If GetGadgetState(#ch4) = #PB_Checkbox_Checked
; SetGadgetState(#ch2, 1)
; EndIf
Case #btnCancel
HideWindow(#WinSet, #True)
EndSelect
EndSelect
EndProcedure
;- GUI2
If OpenWindow(#WinSet, 50, 50, 280, 290, "Настройки поиска по файлам", #PB_Window_Invisible)
SetGadgetFont(#PB_Default, #PB_Default)
CheckBoxGadget(#ch3, 10, 10, 270, 25, "Подсвечивать результат")
CheckBoxGadget(#ch1, 10, 40, 270, 25, "Учитывать регистр")
CheckBoxGadget(#ch2, 10, 70, 270, 25, "Искать в заголовках")
CheckBoxGadget(#ch4, 10, 100, 270, 25, "Искать в названиях разделов")
SetGadgetState(#ch2, 1)
SetGadgetState(#ch3, 1)
SetGadgetState(#ch4, 1)
OptionGadget(#Op1, 10, 140, 270, 25, "Целое слово, не часть")
OptionGadget(#Op2, 10, 170, 270, 25, "Часть слова от начала")
OptionGadget(#Op3, 10, 200, 270, 25, "Часть слова в любом месте")
SetGadgetState(#Op2, 1)
ButtonGadget(#btnOK, 20, 240, 50, 30, "OK")
ButtonGadget(#btnCancel, 80, 240, 90, 30, "Отмена")
BindGadgetEvent(#btnOK, @Events(), #PB_EventType_LeftClick)
BindGadgetEvent(#btnCancel, @Events(), #PB_EventType_LeftClick)
; Отменяем поведение обязательности выбора g_Header с g_Title
; BindGadgetEvent(#ch2, @Events(), #PB_EventType_LeftClick)
; BindGadgetEvent(#ch4, @Events(), #PB_EventType_LeftClick)
EndIf
To search through files, you need the f.txt file containing a list of files without the "htm" extension. List of files that are in the "data" folder. The code will take files using this list. If there are <title>...</title> tags, then the item will be taken using the title.