Text search of User Manual or Programmer's Guide

New to FreeBASIC? Post your questions here.
Flyzone
Posts: 109
Joined: Nov 17, 2017 17:39

Text search of User Manual or Programmer's Guide

Post by Flyzone »

Is there a way to do a text search of the User Manual? For example if I want to look up something I can't find in the index (like "&H") can I use a search term to find it in the manual?
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Text search of User Manual or Programmer's Guide

Post by jj2007 »

See Free search in a CHM file - let me know if it works.

Image
Flyzone
Posts: 109
Joined: Nov 17, 2017 17:39

Re: Text search of User Manual or Programmer's Guide

Post by Flyzone »

Ummm ... I think this is a "bit" out of my skill set -- if I'm even understanding what it is - an inline ASM subroutine for searching? I'd have a chance it if were 360 Assembler :)

I think in lieu of a search might be an index of all terms in the doc(s) (removing some English terms but AND, OR, THEN, etc. would be a problem unless maybe if it was case sensitive).

So, I guess this is just not available ... I'll survive ... though there have been several instances where it would have been handy.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Text search of User Manual or Programmer's Guide

Post by jj2007 »

It's a standalone program, not meant for embedding in FB, Flyzone. Just follow exactly the instructions.
Flyzone
Posts: 109
Joined: Nov 17, 2017 17:39

Re: Text search of User Manual or Programmer's Guide

Post by Flyzone »

This might be painful for both of us. You need to realized my day job is retired and my previous job, tho in IT, was in management.

So, first figure out what a CHM file is ... ok, got it ... an MS Help file format.
OK, go someplace to find it for FB
Oh, it's in SourceForge? Go there.
Under SF FB documentation there are exactly 0 files.
Now, even if I could find it I think I need to download some kind of reader (but it may be already here it I just double click - that is, assuming I have it)
I think I may be able to find that - maybe. After all, I'm about 20% there.
Then you get naked ... that could be very bad but I just need to find the instructions ... ok, jj says just follow them. But they're Greek ... we'll see.
When I find the file, find the reader perhaps I'll do that ...
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Text search of User Manual or Programmer's Guide

Post by MrSwiss »

FB-Manual in chm format for a specific FBC release:
See: in section "New" (in the forum, below Windows version(s))

Most recent (includes also certain features of "version next"):
Get it from: https://users.freebasic-portal.de/stw/builds/ german FB website.
Named: freebasic_manual.chm (date = last time compiled)
which is typically done, after a change in the "online-wiki" (aka: source) is detected.

CHM-readers typically have "index" as well as "search" features (for non WIN OS's only needed).

Btw: just ignore posts from opportunistic advertisers like jj...
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Text search of User Manual or Programmer's Guide

Post by jj2007 »

Flyzone wrote:I need to download some kind of reader
No chm reader needed. You need 7-zip (or similar) to extract the HTML files from the chm files, afterwards my proggie extracts the text from these files.

Note the format is not the most pleasant, but it's incredibly fast, and you can search for two strings at the same time, as shown in the naked sub example above.
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Text search of User Manual or Programmer's Guide

Post by badidea »

The default chm-reader of Windows also has search possibilities:
Image
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Text search of User Manual or Programmer's Guide

Post by jj2007 »

badidea wrote:The default chm-reader of Windows also has search possibilities
Yes, but it is slow, you have to click a lot to get a response, and there is no "favourites" or bookmark function. My proggie has favourites because I was used to them with the old *.hlp format. Which IMHO is a lot better than the chm crap. When I select a word in my sources, e.g. the Windows keyword WM_GETTEXT, hitting F1 displays immediately the page in a very, very old *.hlp file. With an equivalent *.chm file, it means a very slow load plus several mouseclicks. Disgusting!

JNotes is ultrafast, has favourites, and with Alt left arrow / Alt right arrow you can scroll through your search history. I put version 2 online, the headers are now a bit more user-friendly - see below. Try to search for opt arr in the chm reader...

When searching, <tab> brings you into the upper listbox. Use arrow down to scroll through the results.

Image
marcov
Posts: 3455
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: Text search of User Manual or Programmer's Guide

Post by marcov »

jj2007 wrote:
badidea wrote:The default chm-reader of Windows also has search possibilities
Yes, but it is slow, you have to click a lot to get a response, and there is no "favourites" or bookmark function
CHM has a built in dictionary for full-text-search (in the .hhp). Speed may very depending on if that is enabled or not.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Text search of User Manual or Programmer's Guide

Post by dodicat »

Windows.
Here is a little searcher.
The output is written to the console, for easiness.
The .chm file expands into it's component files, I use 7zip, but perhaps .zip would do.
But this code searches for text in any folder.
I might fix it for a whole drive, but at the moment, folders only.
I think it is self explanatory on the gui.
Tested 32/64 bits, but I didn't use any gcc optimisations.

Code: Select all



#include "windows.bi"
#include "win\shlobj.bi"
#include "file.bi"
#include "crt.bi"

Declare Function stats Cdecl Alias "_stat"(As zstring Ptr,As Any Ptr) As long
Function Set_Font (Font As String,Size As long,Bold As long,Italic As long,Underline As long,StrikeThru As long) As HFONT
    Dim As HDC hDC=GetDC(HWND_DESKTOP)
    Dim As long CyPixels=GetDeviceCaps(hDC,LOGPIXELSY)
    ReleaseDC(HWND_DESKTOP,hDC)
    Return CreateFont(0-(Size*CyPixels)/72,0,0,0,Bold,Italic,Underline,StrikeThru,ANSI_CHARSET _
    ,OUT_TT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FF_DONTCARE,Font)
End Function

Function String_Split(s_in As String,chars As String,result() As String) As Long
    Dim As Long ctr,ctr2,k,n,LC=Len(chars)
    Dim As boolean tally(Len(s_in))
    #macro check_instring()
    n=0
    While n<Lc
        If chars[n]=s_in[k] Then 
            tally(k)=true
            If (ctr2-1) Then ctr+=1
            ctr2=0
            Exit While
        End If
        n+=1
    Wend
    #endmacro
    
    #macro split()
    If tally(k) Then
        If (ctr2-1) Then ctr+=1:result(ctr)=Mid(s_in,k+2-ctr2,ctr2-1)
        ctr2=0
    End If
    #endmacro
    '==================  LOOP TWICE =======================
    For k  =0 To Len(s_in)-1
        ctr2+=1:check_instring()
    Next k
    If ctr=0 Then
        If Len(s_in) Andalso Instr(chars,Chr(s_in[0])) Then ctr=1':beep
    End If
    If ctr Then Redim result(1 To ctr): ctr=0:ctr2=0 Else  Return 0
    For k  =0 To Len(s_in)-1
        ctr2+=1:split()
    Next k
    '===================== Last one ========================
    If ctr2>0 Then
        Redim Preserve result(1 To ctr+1)
        result(ctr+1)=Mid(s_in,k+1-ctr2,ctr2)
    End If
    
    Return Ubound(result)
End Function

Function _Remove(Byval Text As String,Char As String) As String
    Var index = 0,asci=Asc(char)
    For i As long = 0 To Len(Text) - 1
        If Text[i] <> ASCi Then Text[index] = Text[i] : index =index+ 1
    Next 
    Return Left(Text,index)
End Function

Function loadfile(file As String) As String
    file= _remove(file,Chr(34))
    If file="" Then Exit Function
    If Fileexists(file)=0 Then Print file;" CAN'T READ OR EMPTY FOLDER":Exit Function
    Var  f=Freefile
    Open file For Binary Access Read As #f
    Dim As String text
    If Lof(f) > 0 Then
        text = String(Lof(f), 0)
        Get #f, , text
    End If
    Close #f
    Return text
End Function

Function isfolder(path As zstring Ptr) As Long
    #define S_ISDIR(m)   (((m) And &hF000) = &h4000)
    Dim As stat statbuf
    If (stats(path, @statbuf) <> 0) Then Return 0
    Return S_ISDIR(statbuf.st_mode)
End Function

Function isfile(fname As String) As boolean
    Return Iif(isfolder(fname),0,1)
End Function

Function pipeout(Byval s As String="") Byref As String
    Var f=Freefile
    Dim As String tmp
    Open Pipe s For Input As #f 
    s=""
    Do Until Eof(f)
        Line Input #f,tmp
        s+=tmp+Chr(10)
    Loop
    Close #f
    Return s
End Function 

Function tally (somestring As String,partstring As String) As long
    Dim As long i,j,ln,lnp,count,num
    ln=Len(somestring)
    lnp=Len(partstring)
    count=0
    i=-1
    Do
        i+=1
        If somestring[i] <> partstring[0] Then Goto skip 
        If somestring[i] = partstring[0] Then
            For j=0 To lnp-1 
                If somestring[j+i]<>partstring[j] Then Goto skip
            Next j
        End If
        count+=1
        i=i+lnp-1
        skip:
    Loop Until i>=ln-1 
    Return count
End Function
Dim Shared As Long counter
Function search(inputs As String,st As String,ext As String="") As Long
      while len(inkey):wend
    st=Lcase(st)
    Dim As Long dflag
    dim as long exitflag
    Dim As String path
    If isfile(inputs) Then 'for a single file or a drive:
        If Len(inputs)=2 And inputs[1]=Asc(":") Then dflag=1:Goto skip
        Var L=Lcase(loadfile(inputs))
        If Instr(L,st) Then Print inputs:Return 1 Else Return 0
    End If
    skip:
    Dim As String file
    If Instr(inputs," ") Then inputs=Chr(34)+inputs+Chr(34)
    Dim As String s=pipeout("dir /b " + inputs)
    Dim As String a()
    string_split(s,Chr(13,10),a())
    inputs=_remove(inputs,Chr(34))
    If dflag=0 Then 'not a drive
        Redim As String tmp()
        string_split(inputs,"\/",tmp())
        If Instr(tmp(Ubound(tmp)),st) Then Print inputs;" >> (In folder name)"
    End If
    For n As Long=Lbound(a) To Ubound(a)
         if multikey(&h01) then exitflag=1: exit for
        path=(inputs+"\"+a(n)) '''
        If isfile(path) Then
             
            Redim As String tmp()
            string_split(path,"\",tmp())
            file= tmp(Ubound(tmp))
            If Instr(file,st) Then Print path;" >> (In file name)"
            If Instr(file," ") Then file=Chr(34)+file+Chr(34)
            If Len(ext) Then If Instr(file,ext)=0 Then Goto nxt 'path
            Var L=Lcase(loadfile(path))
            if multikey(&h01) then exitflag=1: exit for
            If Len(L) Andalso Instr(L,st) Then Print path + "  ("+ Str(tally(L,st))+")":counter+=1
        Else
               if multikey(&h01) then exitflag=1: exit for
            search(path,st,ext) 'for nested folders
        End If
        nxt:
       
    Next n
    if exitflag then print "aborted search"
    Function= counter
    
End Function 

Function folderbrowser_callback (Byval hwndbrowse As HWND, Byval uMsg As UINT, _
    Byval lp As LPARAM, Byval lpData As LPARAM) As long
    Return 0
End Function

Function folderbrowser (Byref title As String = "Choose A Folder") As String
    Dim bi As BROWSEINFO
    Dim pidl As LPITEMIDLIST
    Dim ret As HRESULT
    Dim physpath As Zstring * MAX_PATH
    Dim dispname As Zstring * MAX_PATH
    Dim As LPITEMIDLIST idl,idlroot
    bi.hwndOwner = HWND_DESKTOP
    ret = SHGetSpecialFolderLocation(HWND_DESKTOP, CSIDL_DRIVES, @idlroot)
    
    bi.pszDisplayName = @dispname
    bi.lpszTitle = Strptr(title)
    bi.ulFlags = 0
    bi.lpfn = @folderbrowser_callback
    bi.lParam = 0
    bi.iImage = 0
    
    pidl = SHBrowseForFolder(@bi)
    
    If pidl <> 0 Then
        If SHGetPathFromIDList(pidl, physpath) = 0 Then
            Function = ""
        Else
            
            Function = physpath
        End If
        CoTaskMemFree pidl
        
    Else
        Function = ""
    End If
    
    CoTaskMemFree idlroot
    
End Function

Dim As String * 200 whichfolder
Dim Shared As HFONT  ThisFont:ThisFont=Set_Font("Times new roman",14,0,0,0,0)
Dim  As HWND Main_Win,OKwin,edit,cancel,start,extS,ext,go,showfolder
Main_Win=CreateWindowEx(0,"#32770","Word Finder",WS_OVERLAPPEDWINDOW Or WS_VISIBLE,200,200,800,500,0,0,0,0)
OKwin=CreateWindowEx(0,"button","GO", WS_VISIBLE Or WS_CHILD,0,0,60,30,Main_win,0,0,0)
start=CreateWindowEx(0,"static","Enter search words:", WS_VISIBLE Or WS_CHILD ,5,80+20,290,45,Main_win,0,0,0)

edit=CreateWindowEx(0,"edit","", WS_VISIBLE Or WS_CHILD Or WS_Border Or ws_hscroll Or ES_AUTOHSCROLL,5,80+40,290,45,Main_win,0,0,0)
exts=CreateWindowEx(0,"static","Enter file extension (example: .txt), or leave blank.", WS_VISIBLE Or WS_CHILD ,5,80+100,390,45,Main_win,0,0,0)
ext=CreateWindowEx(0,"edit","", WS_VISIBLE Or WS_CHILD Or WS_Border,5,80+120,90,30,Main_win,0,0,0)
go=CreateWindowEx(0,"button","browse folders", WS_VISIBLE Or WS_CHILD Or WS_Border,5,80+170,190,30,Main_win,0,0,0)
showfolder=CreateWindowEx(0,"static","", WS_VISIBLE Or WS_CHILD Or WS_Border,5,80+210,700,30,Main_win,0,0,0)
cancel=CreateWindowEx(0,"button","End", WS_VISIBLE Or WS_CHILD,0,40,60,30,Main_win,0,0,0)

SendMessage(edit,WM_SETFONT,Cast(WPARAM,ThisFont),0)
SendMessage(OKWin,WM_SETFONT,Cast(WPARAM,ThisFont),0)
SendMessage(cancel,WM_SETFONT,Cast(WPARAM,ThisFont),0)
SendMessage(go,WM_SETFONT,Cast(WPARAM,ThisFont),0)
SendMessage(ext,WM_SETFONT,Cast(WPARAM,ThisFont),0)
SendMessage(exts,WM_SETFONT,Cast(WPARAM,ThisFont),0)
SendMessage(showfolder,WM_SETFONT,Cast(WPARAM,ThisFont),0)
SendMessage(start,WM_SETFONT,Cast(WPARAM,ThisFont),0)
Dim As msg msg
While GetMessage( @msg,Main_Win,0,0)
      
    TranslateMessage(@msg)
    DispatchMessage(@msg)
    
    Select Case msg.hwnd
    Case Main_Win
        Select Case msg.message
        Case 273  
            DeleteObject(Cast(HGDIOBJ,ThisFont))
            End
        End Select
        
    Case OKwin 
        Select Case msg.message  
        Case WM_LBUTTONDOWN
            Dim As String * 100 nms
            Dim As String * 10 extension
            Dim As Long c
            GetWindowText(edit,nms,100)
            getwindowtext(ext,extension,10)
            If Len(nms) And Len(whichfolder) Then
                whichfolder=rtrim(whichfolder,"\")
                'getwindowtext(showfolder,whichfolder,200)
                Dim  As String location=whichfolder
                Dim As String wordname=nms
                Dim As String _ext=extension
                Print "search for ";wordname
                Print "You are using fb version ";__fb_version__
                Print "output format:"
                Print "path to file  (number of occurencies in the file)"
                Print "Searching  . . ."
                counter=0
                c=search(location,wordname,_ext)
                Print "Done ",c; "  locations"
                print
            End If
        End Select
        
    Case go 
        Select Case msg.message  
        Case WM_LBUTTONDOWN
            whichfolder=folderbrowser()
            setwindowtext(showfolder,whichfolder)
        End Select
        
    Case cancel 
        Select Case msg.message  
        Case WM_LBUTTONDOWN
            DeleteObject(Cast(HGDIOBJ,ThisFont))
            destroywindow(Main_Win)
            Exit While
        End Select   
        
    End Select
Wend 

Sleep

Sub finish Destructor
    DeleteObject(Cast(HGDIOBJ,ThisFont))
End Sub

 
Last edited by dodicat on Apr 29, 2021 18:50, edited 1 time in total.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Text search of User Manual or Programmer's Guide

Post by jj2007 »

After "Browse for folder", I get heap corruption at CoTaskMemFree @idlroot (Windows 7-64).
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Text search of User Manual or Programmer's Guide

Post by jj2007 »

marcov wrote:
jj2007 wrote:
badidea wrote:The default chm-reader of Windows also has search possibilities
Yes, but it is slow, you have to click a lot to get a response, and there is no "favourites" or bookmark function
CHM has a built in dictionary for full-text-search (in the .hhp). Speed may very depending on if that is enabled or not.
No .hhp after extraction, so that's probably not enabled. Does it allow partial search strings?

Speed is not the worst problem. The first time you load the .chm, it's slow, afterwards it's in the cache. But the search process is clumsy. In JNotes, you type dyl, and when you arrive at the "l", you see already 13 matches, for Compiler Option: -dylib ... DyLibFree etc. In the Windows chm viewer, you type dyl but nothing happens, and when you hit Return, it tells you that "no argument" was found. Only if you type the full word, such as DyLibSymbol, and then hit Return, it will show you something. That is pretty clumsy imho.
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Text search of User Manual or Programmer's Guide

Post by badidea »

You can stop quoting me, that is way more information about chm-files than I want to know :-)
bfuller
Posts: 362
Joined: Jun 02, 2007 12:35
Location: Sydney, Australia

Re: Text search of User Manual or Programmer's Guide

Post by bfuller »

There is a text search facility in both the Wiki and the Help file.

I don't think the "&" character appears in either. To make a search, I used &*** because the Wiki need 4 characters minimum.
Post Reply