Menu

Multiple keywords filter/searcher

2017-06-30
2017-06-30
  • Ferdinand Mravenec

     
  • Ferdinand Mravenec

    Hello everybody once again!

    This discusssion system makes me trouble, so maybe this post occur in forum twice - sorry :)

    I add another script to my previous script collection for project managing in Freeplane (Calendar script https://sourceforge.net/p/freeplane/discussion/758437/thread/d55a3447/ and Node comparation script https://sourceforge.net/p/freeplane/discussion/758437/thread/56528603/). This script provide multiple keywords search in easy way.

    Lets assume, you are managing projects in Freeplane. You "tag" yours information in node text for better orientation, but there are lot of (key)words in accidentally order, therefore you didnt remember their order. In this situation you can not use built-in simple Freeplane search, but you must to use named filter search and combine them. This is not very handy, because for each search you need to create at least three named filters (first condition, second condition and their combination). This script changes the situation - you can easily put in the input dialog all searched keywords, separated by semicolon, and script search and select nodes, which contains ALL of searched keywords, independently of their order in node text. After that you can easily filter them with standard Freeplane capabilities for further processing. Second big feature is, that this script searches only child nodes of selected node, not in the whole map.

    You can not use REGEXPs (because of Groovy way how it handle string as regexp), but you can use wildcards (*?.). Note also, that "space" in input dialog is also considered as a part of searched keyword!

    Detailed description, installation, limitations of script are contained in script comment.

    Enjoy! :)

    // Keyword filter (Version: 170629)
    // ==============
    // 
    // Filtering nodes with ALL occurences of searched keywords in node text.
    //
    // Unlike built-in Freeplane searching, this script search and find nodes, which contains
    // all searched keywords. Standard Freeplane search is able to search only one
    // keyword/regexp per node. This Keyword filder matches only nodes, where ALL of searched
    // words are present. And unlike built-in Freeplane search, this Keyword filter works only
    // on child nodes of selected node. Of course this script can be replaced by combination
    // of Freeplane built-in filtering. That is powerfull, unfortunately not very fast and
    // simple.
    //
    // This script can be usefull for project managing/file changes tracking, to search custom
    // keywords in easy way. Lets say, you "tag" your notes by known tags (e.g. in
    // constructing names of constructed objects), so you know, what tags (keywords) you
    // should expect, but you dont remember their order. This is not solvable in easy
    // searching, provided by Freeplane, but with this script it is only game :)
    //
    // Usage: Select node, containing subnodes, where you will to perform search. Run this
    // script (Tools -> Scripts), input searched keywords, separated by semicolon (";") and
    // press Enter. Keyword filter select all subnodes, which contains all searched keywords.
    // Then you can filter them using standard Freeplane functions/buttons.
    //
    // Note!
    // - If you enter space between two keywords, that keywords included space are taken like
    // one exact word to search.
    // - Space is also taken like searched phrase!
    // - You can use for searching wildcards (*?.), but unfortunatelly no REGEXPs.
    //
    // Known issues:
    // - Sometimes occur also selection of one node, which contains only one (first) of
    // searched keywords (with no obvious reason). 
    //
    // Installation: Download script code to new file, eg. KeywordFilter.groovy and copy this
    // file to folder "scripts" in Freeplane program path. Then restart Freeplane, script
    // appears in menu Tools --> Scripts.
    // 
    // Possible improvement:
    // - Include option to search REGEXPs
    // - Include option, in which node information it should searches (now it is only node
    // text)
    //
    // Freeplane version: 1.6.2 beta
    //
    // Created by: (c) Ferdinand Mravenec, 2017
    // 
    
    // Create user input dialog.
    input = ui.showInputDialog(node.delegate, "Input searched words (separator semicolon)", "")
    input = input.split(";").toList() // Use semicolon to split input into list
    
    // Get list of child nodes and explicitly type it to ArrayList (because of use "remove"
    // below)
    def selnode = new java.util.ArrayList(c.getSelected().findAllDepthFirst()) 
    
    // Some magic to prevent wrong results, which happens, when inputted keyword was only one
    if (input.size() == 1) input.add(input[0])
    
    // Main loop - for each inputted keyword search, if it is present in node text
    for (i = 0; i < input.size(); i++){
        for (j = 0; j < selnode.size(); j++){
            if (selnode[j].text.find(input[i]) == null){ // If keyword is not in list of nodes ...
                selnode.remove(j) // ... remove that node ...
                j = 0  // ... and start from beginning (to prevent buffer overflow)
            }
    
            // Some magic to prevent wrong results, which happens, when resulted node list
            // contains only one unmatching node (see known issues upstairs)
            if (selnode.size() == 1 && selnode[0].text.find(input[i]) == null){
                selnode = []
            }
        }
    }
    
    // Select results in map
    c.select(selnode)
    
     
  • Luigi Kang

    Luigi Kang - 2017-07-01

    I didn't know about getting user input using buil-in dialog; this could save me one line of import, hehe. Thank you for sharing your script.