Menu

One Map, two languages

michaelhe
2017-06-30
2019-05-21
1 2 > >> (Page 1 of 2)
  • michaelhe

    michaelhe - 2017-06-30

    I'm working on a map, developed in German language. I'm thinking about the best way, to introduce English as second language for all nodes text; translation can be done manually.

    Here I've found a proposal, which sounds practical to me. As I'm already using a lot of styles and these will often change during the project (like: open, work in progress, done), I'd prefer to use the node text for first language and node details for the second language.

    As proposed, "A script could be used to switch back and forth." Would anybody please advice me, how to build such script. I experienced meanwhile, how to run (calendar) script (from underneath) but have no idea about switching ...

    Thank you

     

    Last edit: michaelhe 2017-07-01
  • Luigi Kang

    Luigi Kang - 2017-07-01

    Here's a simple script that can switch the texts of node ande node details. There's one caveat though, this script uses the node note as buffer, so I hope your note is already empty. :p

    c.selecteds.each {
    it.noteText = it.text
    it.text = it.details.text
    it.detailsText = it.note.text
    it.noteText = ''
    }
    
     
    • Felix Natter

      Felix Natter - 2017-07-01

      hello Luigi,

      since it.text and it.detailsText are just Strings, you can just use a temporary string variable:

      def tmp = it.text
      it.text = it.details.text
      it.detailsText = tmp
      

      Cheers and Best Regards,
      Felix

       
    • Luigi Kang

      Luigi Kang - 2017-07-02

      Thanks Felix for pointing using a temporary variable for string.

      michaelhe, here's the version without tempering node notes with Felix's help.

      c.selecteds.each {
      def tmp = it.text
      it.text = it.details.text
      it.detailsText = tmp
      }
      
       
  • michaelhe

    michaelhe - 2017-07-02

    Thank you Luigi and Felix for your time and support. I saved "SwitchTextDetails.groovy" locally, added few comments like // comment.

    Attached a simple map showing the questions I still have:

    • Running the script, having only one node marked, only this one is changed properly.
    • Selecting all nodes (CTRL-A), nothing happens, when script is started.
      How can I change all nodes with one command?
    • View > Node-Details (ALT-F") switches the English text visible / unvisible. The little triangle remains. Is there any chance to hide also the triangel?
    • If not, would it be possible to use the Note (DE: Notiz) for the second language. I added such notes to both nodes and can switch that icon vice-versa.

    Best regards
    Michael

     

    Last edit: michaelhe 2017-07-02
    • zipizap

      zipizap - 2017-07-02

      Try selecting a few notes and then running the script with those few nodes
      selected ,to see what happens

       
  • michaelhe

    michaelhe - 2017-07-02

    Thank you, zipizap
    but I'm not sure, I understand you right.
    First I had a poor attachement, for whatever reason, the NodeDetails text disappeared, sorry for that. Now attached a correct one, having 1+2 nodes.

    Now please try with the new attachement Test DE-EN3.mm downloaded :

    • Do not save this again, unless mentioned in the following text!
    • Press CTRL-A to mark all three nodes, run the script, all three nodes switch from German to English.
    • Run the script again, back to German. Thats great!
    • Now drop node B, press CTRL-A, run the script: Nothing happens. Mark only one node, text changes. This is what I had earlier, therefore I was asking. Why this behaviour with only two nodes?
    • Close the actual, open the downloaded one again.
    • Press CTRL-A and run the script twice. Language changes to English and back to German, as expected. Now safe that file, quit and open it again: All node details are gone completely. This is the reason I was looking fo in my second sentence in this post.

    What's wrong here? Thank you.

     

    Last edit: michaelhe 2017-07-02
  • Luigi Kang

    Luigi Kang - 2017-07-02

    I just followed bullet points and tested them out, and reproduced the two problems, on map attached (Test DE-EN3) and my own test map:
    1. The script works on one or all, but not on two or more selected.
    2. After runnning the script twice then save and reopen, all details are gone.
    3. I went further, tried running the script once, then save and reopen, the root node's detail is gone.

    Perhaps these are due to bugs? If so one can open a ticket and report them.

     
  • michaelhe

    michaelhe - 2017-07-02

    Thanks, Luigi for testing and confirmation.
    I've found, that after running the script, the node's details are gone for all that node, that have been seleted for scripting process.

     
  • michaelhe

    michaelhe - 2017-07-02

    Now I extended the script for using the note instead of detail, ref. above for reason for this.

    // Switch DE-EN.groove
    // Quelle: https://sourceforge.net/p/freeplane/discussion/758437/thread/5729a4cc/
    // Script to switch back and forth
    
    // Detail
    // c.selecteds.each {
    // def tmp = it.text
    // it.text = it.details.text
    // it.detailsText = tmp
    // }
    
    // Note / Notiz
    c.selecteds.each {
    def tmp = it.text
    it.text = it.note.text
    it.noteText = tmp
    }
    

    Please comment / uncomment the appropriate section. for testing. New Test DE-EN4.mm attached, having notes for each node.

    Actually the script changes the notes properly first, but after saving the note-text is gone for all nodes, that have been involved to changes. Same behaviour like for notes.

    Is the difference for variables on lines 3 and 4 on purpose:
    it.details.text =! it.detailsText?

     

    Last edit: michaelhe 2017-07-02
  • Dimitry Polivaev

    I do not use scripting myself, but I stil want to share some hints.

    http://www.freeplane.org/wiki/index.php/Scripting gives introduction into Scripting with Freeplane.
    In partucular it recommends to use method c.findAll() to work with all nodes in the map independently from current selection. I think you can use it like

    c.findAll().each {
    ...
    }
    

    Instead of using notes or details you could also keep your language specific content in attributes.
    You can find examples at http://freeplane.sourceforge.net/doc/api/org/freeplane/plugin/script/proxy/Proxy.Attributes.html

    Actually I am thinking about implementing some hidden attributes which are not shown on the map but could be used by scripts, but it still just a thought.

    Dimitry

     
  • Luigi Kang

    Luigi Kang - 2017-07-02

    I tested with the latest map and script but still encounter the same problems, unfortunately. However, michaelhe, if you would still like to proceed with developing your mind map, perhaps you can use the script for sole purpose of presenting, and not saving. For example, make a copy of the map for it to be use with script to show it with an alternate language to a friend or colleague, but make and save changes only to the original map that has not run the script.

    As for the details used in the script, and scripting in general, please refer to Dimitry's first wiki link, and the reference links below:
    http://freeplane.sourceforge.net/doc/api.old/org/freeplane/plugin/script/proxy/Proxy.Node.html
    http://freeplane.sourceforge.net/doc/api.old/org/freeplane/plugin/script/proxy/Proxy.NodeRO.html

     
  • michaelhe

    michaelhe - 2017-07-02

    Thank you, Dimitry.

    c.findAll().each {
    

    works fine for the notes actually, but after running the script and saving the map, the notes are gone in the re-opened file.
    I did not spend too much time in the attributes, as the notes would work perfectly for me: It is possible to have nothing visible about different language f.e. for printing. For editing, I can have all notes fully visible or the icons only, to find missing notes.

    I'd really appreciate if someone could help me to find the reason, why scrips destroys either notes or comments.

     
  • Dimitry Polivaev

    Probably notes and details expect valid HTML and your content is plain text and the assignment is not valid. In this case and you need some conversion. It is just a guess.

     
  • Luigi Kang

    Luigi Kang - 2017-07-02

    Thank you Dimitry--you're right, cause the following code works even after saving and opening.

    c.selecteds.each {
    def tmp = it.htmlText
    it.text = it.details.string
    it.detailsText = tmp
    }
    

    michaelhe, if you're sure you want the script to switch all the nodes all the time, replace the first line with

    c.findAll().each {
    
     
  • michaelhe

    michaelhe - 2017-07-02

    Thank you, Luigi and Dimitry.

    Seems it works, I modified the code to use the notes instead of details:

    // Note / Notiz
    // c.selecteds.each {
    c.findAll().each {
    // def tmp = it.text
       def tmp = it.htmlText
       it.text = it.note.text
       it.noteText = tmp
    }
    

    One more questions: If there is one of the selected nodes without Note (or without detail), an error message is shown and there is no switching. Would it be possible to extend the script to overrun such nodes and to show "" instead of that?

    Now I'm starting with the original map ...

     

    Last edit: michaelhe 2017-07-02
  • Luigi Kang

    Luigi Kang - 2017-07-02

    So here we give a condition for the switching code to run, when the note exists and the node text (what you see) is not empty.

    c.find{
    it.note && !it.displayedText.empty
    }
    .each {
    def tmp = it.htmlText
    it.text = it.note.html
    it.noteText = tmp
    }
    
     
  • michaelhe

    michaelhe - 2017-07-03

    Thank you Luigi, that works perfectly now.
    I could finalize my map with both languages yesterday and spread the two versions to all participants. Sorry for late reply, but after that had some other issues first ...
    Thanks and best regards
    Michael

     
  • Volker Börchers

    When developing scripts please make sure that you understand the Execution modes. If you execute the the c.find script with ON_SELECTED_NODE then the whole script is run multiple times (as often as the number of selected nodes). Make sure to include a line

    ~~~
    // @ExecutionModes({ON_SINGLE_NODE})
    ~~~

    in scripts that iterate over the whole map.

    Using Proxy.Node.htmlText (which unfortunately up to now had a very unappropriate documentation) is a very good idea when interchanging between a HTML-only container (details and note) and a either HTML or text container (node core).

    Volker

     
  • michaelhe

    michaelhe - 2017-07-25

    As described above, my maps are dual language (GErman/ ENglish), both versions are stored as Text and Note; a script switches for presentation:

    // @ExecutionModes({ON_SINGLE_NODE})
    c.find{
    it.note && !it.displayedText.empty
    }
    .each {
       def tmp = it.htmlText
       it.text = it.note.html
       it.noteText = tmp
    }
    

    This works fine, but sometimes while editing, I forget to add the note. Is there any way to find (filter?) such nodes without Note.
    Thank you.

     
  • Luigi Kang

    Luigi Kang - 2017-07-25
    map.filter { !it.note }
    
     
  • Luigi Kang

    Luigi Kang - 2017-07-25

    I just tried with the above code, and got a null exception.

     
  • michaelhe

    michaelhe - 2017-07-26

    Thank you Luigi, your code

    map.filter { !it.note }
    

    (again) works perfekt. Seeing, that filtering is possible, I was thinking to solve it without programming; otherwise again (ref. here) I'd need something like if .. else and code to decide about existence: IF there is any noDe without noTe, filter ON, ELSE switch languages / Text <> Note for all noDes.

    So I tried the manual filtering with the attached .mm-file, having three noDes without noTe (left ###, right status::, bottom also without text. With your code, only these three plus "NeueMap" are shown --> OK.
    Now I tried the manual filtering (CTRL-F) and entered into the Dropdown / Text fields "Text" "is equal" and kept the Text-field empty, so the filtering is shown as

    Text is equal ""
    

    As expected, only the bottom node is shown after that --> OK. For whatever reason it moves to the top.

    Now the same for noTe to have the filtering shown as

    Note is equal "".
    

    Only the main node is shown ...

    Any ideas?

     

    Last edit: michaelhe 2017-07-26
  • Luigi Kang

    Luigi Kang - 2017-07-26

    When applying filtering condition that leads to empty or 0 result (I'll explain later why in your case), only the root node, aka main node, will be shown.

    When a node is created, its associated note and details do not exist by default, whereas node core (text) isn't empty, even if you don't type any text in it, it exists, like your filtering condition that test for empty string to an existing node text, which happens to be empty, the result is what you would expect, exists -> as empty.

    However, a test for empty string would not work for something that does not exist, like note and details associated with a brand new node, so the result is nothing, leading to only showing root node when the filter is applied.

    By manual filter, I am guessing you mean the Filter toolbar or Filter composer in the English translation of Freeplane. If you play with it a little bit down, such as icon, select it, the first dropdown menu on the right shows "contains" and "exists", which is what you want to check if something exists, unfortunately, the condition "exists" is not available for details or note.

     
  • michaelhe

    michaelhe - 2017-07-26

    Thanks for explanation, Luigi.

    You're right, manual Filter I mean the dropdown fields etc. showing up after pressing CTRL-F. I changed Freemind's language to English now and found
    Contains icon: That shows all noDes with noTe, unfortunately there is no Contains NOT ...
    ScriptFilter, where I added your code "map.filter { !it.note }". This brings the right result for the testStatus&Node.mm, I sent earlier today but also an error message.

    So obviously it's difficult / impossible to filter manually noDes without noTe.

    Different approach: Here I have some code, counting the total number of nodes "NodeCountTotal". If somebody knew, how to count the number of noDes with noTe, an if-Statement could be added running your code plus something like

    if (NodeCountTotal > NodeCountnoTe)
       c.statusInfo = "Found noDes without noTe (=EN-text). Add this to the filtered nodes first ..."
       map.filter { !it.note }
    else
      // the old code
      c.find{
    it.note && !it.displayedText.empty
    }
    .each {
       def tmp = it.htmlText
       it.text = it.note.html
       it.noteText = tmp
    }
    // end of old code
    

    Thank you.

     
1 2 > >> (Page 1 of 2)