Menu

Using a variable for file links

swuser
2021-04-18
2021-04-24
  • swuser

    swuser - 2021-04-18

    Is there a way to specify file links using an environment variable so a link won't be broken when the top level directory changes?

    For example, a file link will be c:\Documents1\myFile.pdf on one computer but c:\Documents2\myFile.pdf on another. Can I specify these paths using <env>\myFile.pdf and define <env> on each computer appropriately?</env></env>

    Thanks

     
  • Edo Frohlich

    Edo Frohlich - 2021-04-18

    I don't know how to use environment variables in the nodes links, but maybe you can solve your problem by using relative links.

    in Preferences / Environment / Hyperlink types / links

    change from Absolute to Relative and when inserting a file as node it will have a relative link. This way if the folders structure is similar in both computers it should work.

     
    • forumer

      forumer - 2021-04-18

      Thanks for the idea and it works but seems somewhat cumbersome. If I
      understand correctly, the relative position of the map the link is in and
      file referred to has to stay the same. I wish there was a way to define a
      variable for the directory or directory tree the referencing map was in and
      use that in a link path. Any changes in relativeness could be absorbed in
      the value of the variable.

      Thank you

      On Sun, Apr 18, 2021 at 10:00 AM Edo Frohlich edo_f@users.sourceforge.net
      wrote:

      I don't know how to use environment variables in the nodes links, but
      maybe you can solve your problem by using relative links.

      in Preferences / Environment / Hyperlink types / links

      change from Absolute to Relative and when inserting a file as node it will
      have a relative link. This way if the folders structure is similar in both
      computers it should work.


      Using a variable for file links
      https://sourceforge.net/p/freeplane/discussion/758437/thread/e5dbee493c/?limit=25#74d2


      Sent from sourceforge.net because you indicated interest in
      https://sourceforge.net/p/freeplane/discussion/758437/

      To unsubscribe from further messages, please visit
      https://sourceforge.net/auth/subscriptions/

       
      • Edo Frohlich

        Edo Frohlich - 2021-04-18

        Another way is to make a script that updates all the links in your nodes at
        once. You will have to run it every time you change from computer.
        It is doable and not difficult.
        I’m not at the computer right now but I could make a first version of the
        script for you to try if you think it’s worth the effort.

         
  • Edo Frohlich

    Edo Frohlich - 2021-04-19

    Dear Forumer,
    as comented here I have to work part of my time in a different computer (starting this week), so I realized I needed this script for myself too.

    Here is the version I did for the map I have to work in both computers. I have other scripts that I use frequently that need absolute links to the files to be used, so the relative links solution wasn't an option for me too.

    Here is the code:

    def lastLocAttr = 'currentFileLocation' //name of the attribute that contains last location
    
    //finding node that has this attribute
    def nodo = node.attributes.containsKey(lastLocAttr)?node:c.find{it.attributes.containsKey(lastLocAttr)}[0]
    
    //looks for the folder of the current map
    def currLoc = map.file.parent
    
    //if the map has no nodo yet, then it gives you the possibility to add the attribute to the selected node and ends the script
    if (!nodo) {
        if(ui.showConfirmDialog(node.delegate,"No '$lastLocAttr' attribute in this map.\n\n Do you want to add '$lastLocAttr' attribute to the selected node?".toString(),'Location node',0)==0){
            node[lastLocAttr] = currLoc
            return 'new loc node. interrupted'
        }else{
            return 'interrupted'
        }
    }
    
    //looks which was the last folder where the map was when runing this script (check in in other computer)
    def lastLoc = nodo[lastLocAttr].toString()
    
    //if they are the same then do nothing, there was no travel
    if(lastLoc==currLoc){
         ui.showMessage("current directory is already set to:\n\n $currLoc".toString(),2)
        return 'interrupted'
    }
    
    // list of all nodes that have a link to a file
    def nodos = nodo.map.root.find{n -> n.link.file!=null}
    
    //change the link for each one of them replacing the last location with the new one
    nodos.each{n ->
        n.link.file = new File(n.link.file.canonicalFile.toString().replace(lastLoc,currLoc))
    }
    
    // update the last location information, for the next Check In
    nodo[lastLocAttr] = currLoc
    
    //success
    ui.informationMessage( "directory changed to:\n\n $currLoc".toString())
    return 'done'
    

    It adds the Attribute "currentFileLocation" to one of your nodes to remember the last time it changed all the links.

    For this script to work you need to place your map in the root folder of your project. That's the way its working now, but you can modify it if you need.

    I attached a map to this post. It has a node with the script. You can copy it to your map and execute the script in it (by clicking in its icon) every time you change from computer.

    hope it helps,
    edo

     

    Last edit: Edo Frohlich 2021-04-20
  • Edo Frohlich

    Edo Frohlich - 2021-04-20

    You can also use System.getenv to get the environment variable (path) you need, doing something like:

    def currLoc = System.getenv('myEnvironmentVariable')
    

    or if you can't (or don't want) to create new environment variables, you can get the computer's name (using System.getenv('COMPUTERNAME') )and define the path depending on this in the script's logic

    BR
    edo

     
    • forumer

      forumer - 2021-04-20

      Edo,

      I really appreciate your help. I'll put this script to use in a few days.
      I'll be sure to update you on how it goes.

      Thank you!

      On Tue, Apr 20, 2021 at 6:38 AM Edo Frohlich edo_f@users.sourceforge.net
      wrote:

      You can also use System.getenv to get the environment variable (path) you
      need, doing something like:

      def currLoc = System.getenv('myEnvironmentVariable')

      or if you can't (or don't want) to create new environment variables, you
      can get the computer's name (using System.getenv('COMPUTERNAME') )and
      define the path depending on this in the script's logic

      BR
      edo


      Using a variable for file links
      https://sourceforge.net/p/freeplane/discussion/758437/thread/e5dbee493c/?limit=25#e5ae


      Sent from sourceforge.net because you indicated interest in
      https://sourceforge.net/p/freeplane/discussion/758437/

      To unsubscribe from further messages, please visit
      https://sourceforge.net/auth/subscriptions/

       
  • Jochen Kall

    Jochen Kall - 2021-04-22

    Hi Edo,

    nice work, bookmarked for later use ;)
    When looking at your code, I thought, wouldn't it be easier to store the last known path in the map data instead of a node attribute?
    No need for searching, and dialogs and almost no risk for accidentally messing with the path either that way.

    node.map.storage["lastLocAttr"]
    

    Jochen

     
  • Edo Frohlich

    Edo Frohlich - 2021-04-24

    Hi Jochen,
    You are right. I corrected my script to use a map storage variable instead of node attributes.

    This is the new version:

    def lastLocSto = 'currentFileLocation' //name of the Map Storage Variable that contains last location
    def m = node.map //getting the active map
    
    //looks which was the last folder where the map was when running this script (check in in other computer)
    def lastLoc = m.storage[lastLocSto]?.string
    
    //looks for the folder of the current map
    def currLoc = m.file.parent
    
    //if the map has no map variable yet, then it gives you the possibility to add it and ends the script
    if (!lastLoc) {
        if(ui.showConfirmDialog(node.delegate,"No '$lastLocSto' storage variable in this map.\n\n Do you want to add it to the current map?".toString(),'Location Map Storage Variable',0)==0){
            m.storage[lastLocSto] = currLoc
            return 'new lastLocSto. ended'
        }else{
            return 'interrupted'
        }
    }
    
    //if they are the same then do nothing, there was no travel --> do nothing
    if(lastLoc==currLoc){
         ui.showMessage("current directory is already set to:\n\n $currLoc".toString(),2)
        return 'interrupted'
    }
    
    // list of all nodes that have a link to a file
    def nodos = nodo.map.root.find{n -> n.link.file!=null}
    
    //change the link for each one of them replacing the last location with the new one
    nodos.each{n ->
        n.link.file = new File(n.link.file.canonicalFile.toString().replace(lastLoc,currLoc))
    }
    
    // update the last location information, for the next Check In
    m.storage[lastLocSto] = currLoc
    
    //success
    ui.informationMessage( "directory changed to:\n\n $currLoc".toString())
    return 'done'
    

    I attached a map containing bothe versions.