Scripting: Difference between revisions

From FreeMind
Jump to navigationJump to search
(→‎Limitations: +no way to store scripts in a script file)
 
(60 intermediate revisions by 4 users not shown)
Line 1: Line 1:
[[Release 0.9.0|FreeMind 0.9.0]] has a scripting facility using Groovy.
Since [[Release 0.9.0]], FreeMind has a scripting facility using Groovy programming language, an imperative language syntactically resembling Java but with some syntactic sugar added such as optional declaration of types. The best way to get started is perhaps by reading [[Scripting/Mind map documentation]], the wiki version of the mind map documentation originally written by Christian Foltin. What follows here is less informative and consolidated than the mind map documentation. Another source is the dedicated page [[User-contributed example scripts]] for scripts supplied by FreeMind users.
 
==Menu==
* Tools > Evaluate: run all the scripts in a mind map
* Tools > Script Editor
 
==Keyboard==
* Alt + F8: run all the scripts in a mind map


==Using==
==Using==
Each script is stored in a named attribute of a node, named for example as "script1" or "script2". One node can have several scripts attached. There is no way to store scripts in a script file for the whole application; scripts can only be stored in mind maps[verify].
Each script is stored in a named attribute of a node, named for example as "script1" or "script2". One node can have several scripts attached. There is no way to store scripts in a script file for the whole application; scripts can only be stored in mind maps[verify].


New scripts can be created using the script editor, available from the menu Tools > Script Editor. Alternatively, you can plainly create an attribute whose name starts with "script" such as "script2"; such an attribute is understood by FreeMind to be a script.
To add a new script to a node:
* Use the script editor, available from the menu Tools > Script Editor. A window pops up. There, choose menu Action > New script. A new script name appears in the top left pane, starting with "script", followed by "1" or higher if there already are scripts attached to the node blocking that name. Enter the script source code into the top right pane. Then you can choose menu Actions > Save and Exit to save the script, or you can immediately run it via menu Actions > Run.
* Alternatively, you can create an attribute whose name starts with "script" such as "script1" or "scriptA"; such an attribute is understood by FreeMind to be a script. This you can do via menu Edit > Edit Attributes (Alt + F9). However, this is rather inconvenient as the field for the attribute value is small.
 
To run a single script:
* Use the script editor (Tools > Script Editor), and its menu item Actions > Run.
* The Run function of the script editor shows the results of the execution in the pane at the bottom, and it shows error messages there, if any.


To run all the scripts in a mind map, use the menu Tools > Evaluate or press Alt + F8.
To run all the scripts in a mind map:
* Use the menu Tools > Evaluate or press Alt + F8. By default, the function asks for confirmation, for security reasons.


To run a single script, use the script editor (Tools > Script Editor), and its menu item Actions > Run. The Run function of the script editor shows the results of the execution in the pane at the bottom, and it shows error messages there, if any.
To delete a script:
* There is no menu in the script editor to do that. You can delete the corresponding attribute, by placing the cursor over the attribute, and in the context menu choosing Delete.


For more detail, see the FreeMind documentation available from the menu Help > Documentation, the section "New features in version 0.9.0" and the subsection "Scripting support".
For more detail, see the FreeMind documentation available from the menu Help > Documentation, the section "New features in version 0.9.0" and the subsection "Scripting support".
==Access points==
Access points to scripting functionality, for reference:
* Menu: Tools > Script Editor
* In Script Editor
** Menu: Actions > New Script
** Menu: Actions > Run
** Menu: Actions > Sign Script...
** Menu: Dismiss Changes and Exit
** Menu: Save and Exit
* Menu: Tools > Evaluate: run all the scripts in a mind map; keyboard shortcut: Alt + F8
* Menu: Tools > Preferences > pane Scripting
** Checkbox: Permit File Operations
** Checkbox: Permit Network Operations
** Checkbox: Permit To Execute Other Applicatios
** Checkbox: Trust Signed Scripts
** Input field: Optional User Key Alias for Signing
* Menu: Edit > Edit Attributes; keyboard shortcut Alt + F9


==Examples==
==Examples==
Some example scripts:
Some example scripts follow. They take advantage of 1) = for assignment of the result of a calculation, 2) c for controller, and 3) node for the script node.


* Setting a new text of a node: <code>=12 * 14</code> (A little trick: scripts starting with "=" replace the text of a node with their results.)
One-liner examples:
* Setting a new text of a node: <code>=12 * 14</code>. Scripts starting with "=" replace the text of a node with their results. A shorthand.
* Setting a new attribute value: <code>myattribute=5 * 6</code>. Another shorthand.
* Changing the text of a node: <code>c.setNodeText(node, node.getText() + " - appended text")</code>
* Changing the text of a node: <code>c.setNodeText(node, node.getText() + " - appended text")</code>
* Setting the text color of a node: <code>c.setNodeColor(node, java.awt.Color.RED)</code>
* Setting the text color of a node: <code>c.setNodeColor(node, java.awt.Color.RED)</code>
* Setting the background color of a node: <code>c.setNodeBackgroundColor(node, java.awt.Color.YELLOW)</code>
* Setting the background color of a node: <code>c.setNodeBackgroundColor(node, java.awt.Color.YELLOW)</code>
* Setting the value of an attribute: <code>c.editAttribute(node, "myresult", "new value")</code>
* Setting the value of an attribute: <code>c.editAttribute(node, "myresult", (String)(12*14))</code>. Uses "(String)" to convert/cast the numerical result into a string. The bracket around 12*14 is mandatory.
* Make bold: <code>c.setBold(node, true);</code>
* Make italic: <code>c.setItalic(node, true);</code>
* Set cloud: <code>c.setCloud(node, true);</code>
* Set cloud color: <code>c.setCloudColor(node, new java.awt.Color(0xEE, 0xEE, 0x99));</code>. If there is no cloud, sets it; thus, c.setCloud() does not need to be called beforehand.
* Add icon as the rightmost icon: <code>c.addIcon(node, freemind.modes.MindIcon.factory("pencil"));</code> The icon list is in [[Icons]] page.
* Remove all icons: <code>c.removeAllIcons(node);</code>
* Remove last icon: <code>c.removeLastIcon(node);</code>
* Make node bold if folded: <code>c.setBold(node, node.isFolded())</code> If not folded, make it non-bold.
* Set hyperlink: <code>c.setLink(node, "http://www.google.com/");</code>
* Make the currently selected node bold (not the script node): <code>c.setBold(c.getSelected(), true);</code>
Short multiline examples:
Turn currently selected nodes bold:
<pre>
selectedNodesIt = c.getSelecteds().iterator();
while (selectedNodesIt.hasNext()) {
  selNode = selectedNodesIt.next();
  c.setBold(selNode, true); 
}
</pre>
Count descendants, exluding the node itself:
<pre>
nodeCount = 0;
def stack = new java.util.Stack();
stack.push(node);
while (stack.size() > 0) {
    def currNode = stack.pop();
    if (node != currNode) 
        nodeCount += 1;
    stack.addAll(currNode.getChildren());
}
c.editAttribute(node, "mynodecount", (String)nodeCount);
</pre>
Sum the values of cost attribute of descendants, storing the result to costTotal attribute:
<pre>
costTotal = 0;
def stack = new java.util.Stack();
stack.push(node);
while (stack.size() > 0) { 
    def currNode = stack.pop();
    if (node != currNode) {
      costTotal += Integer.parseInt(currNode.getAttribute("cost"));
    }
    stack.addAll(currNode.getChildren());
}
c.editAttribute(node, "costTotal", (String)costTotal);
</pre>


See also [[Example scripts]].
See also [[Example scripts]].


For another set of examples, see the FreeMind documentation available from the menu Help > Documentation, the section "New features in version 0.9.0" and the subsection "Scripting support".
For another set of examples, see the FreeMind documentation available from the menu Help > Documentation, the section "New features in version 0.9.0" and the subsection "Scripting support"; this is also available here: [[Scripting/Mind map documentation]].
 
==Script editor==
 
FreeMind has a very simplistic script editor, available from menu Tools > Script Editor. The editor has no color highlighting of code, and no specific support for writing Groovy scripts: it is basically a plain text editor like Notepad.
 
The editor has three panes: left one, right one, and bottom one. The left pane shows a list of scripts attached to a node. The right pane shows the script selected in the left pane. The bottom pane shows the results of the execution of a script.
 
The actions available in the menu Action of the script editor are New Script, Run, Sign Script, Dismiss Changes and Exit, and Save and Exit.
 
The action Action > New Script adds a new script to the left pane, named as "script1", "script2", etc. The newly created script can be edited in the right pane once the name of the script is selected in the left pane.
 
The action Action > Run runs the script selected in the left pane, and shows the result of running the script in the bottom pane, including any error messages.
 
The action Action > Sign Script makes it possible to sign a script. [To be documented].


==API==
==API==
The scripts can access FreeMind's scripting API--application programming interface. Above all, the scripts would typically make use of the methods of [http://freemind.cvs.sourceforge.net/viewvc/freemind/freemind/freemind/modes/mindmapmode/MindMapController.java?view=log MindMapController]. The mind map controller is available to scripts as 'c'.
The scripts can access FreeMind's scripting API--application programming interface. Above all, the scripts would typically make use of the methods of [http://freemind.cvs.sourceforge.net/viewvc/freemind/freemind/freemind/modes/mindmapmode/MindMapController.java?view=log MindMapController]. The mind map controller is available to scripts as 'c'.
The variables made available to scripts, with their types:
* <code>MindMapController c</code>: the controller
* <code>MindMapNode node</code>: the node the script is stored in, not the currently selected one
* <code>HashMap cookies sScriptCookies</code>: A hashmap of key-value pairs (TBD:WHAT IS THIS ANYWAY?)
We suggest you use the FreeMind source code and an Integrate Development Environment (IDE) to explore the types and methods available.
Java sources exposing the API:
* [https://sourceforge.net/p/freemind/code/ci/master/tree/freemind/freemind/modes/mindmapmode/MindMapController.java MindMapController.java] in Git, sourceforge.net
* [https://sourceforge.net/p/freemind/code/ci/master/tree/freemind/freemind/modes/MindMapNode.java MindMapNode.java] in Git, sourceforge.net
* [https://sourceforge.net/p/freemind/code/ci/master/tree/freemind/freemind/modes/NodeAdapter.java NodeAdapter.java] in Git, sourceforge.net
* [https://sourceforge.net/p/freemind/code/ci/master/tree/freemind/freemind/modes/mindmapmode/MindMapNodeModel.java MindMapNodeModel.java] in Git, sourceforge.net


==Security==
==Security==
Line 51: Line 152:


==Implementation==
==Implementation==
Scripts are stored in an attribute whose name reads "script" followed with a numeral, meaning in the attribute of the attribute function, not in the attribute of XML.
Scripts are stored in attributes whose names starts with "script", meaning in the attribute of the attribute function, not in the attribute of XML. Thus, the script attribute can be called "script1", "script_A", or "script_sum_calculation". Attributes created via Actions > New Script menu in the script editor are of the form "script''N''", where N is a positive integer (1, 2, ...).


The script attributes are probably distinguished from non-script attributes by their starting with "script".
The script attributes are probably distinguished from non-script attributes by their starting with "script".
Line 61: Line 162:
</node>
</node>
</pre>
</pre>
Scripting is implemented as an external [[plugin]].
Package: [http://freemind.cvs.sourceforge.net/viewvc/freemind/freemind/plugins/script/?pathrev=fm_060405_integration freemind/plugins/script/]


==Limitations==
==Limitations==
* Failure unless file operations permitted: Almost all scripts fail unless file operations are permitted for scripting; repeated execution of scripts succeeds, though[http://sourceforge.net/tracker/index.php?func=detail&aid=2789907&group_id=7118&atid=107118]
* No way to store scripts in a script file for the whole FreeMind application; scripts can only be stored in mind maps.
* There is no way to store scripts in a script file for the whole application; scripts can only be stored in mind maps[verify].
* Having the scripts associated with a particular node rather than the whole mind map is not necessarily ideal. It is uncustomary from the perspective of an office application.
* Storing scripts in user-defined attributes is arguably not so nice; this is not what attributes are for.
* No way to run a ''single'' script outside of the script editor. It is only within the script editor that one can run a single selected script. Outside of the script editor, there is the function to run ''all'' scripts stored in the nodes of the mind map. As a result, if there are multiple scripts in the mind map, there is not way to run a ''single'' script on the ''currently selected node'', given that the currently selected node is in general distinct from the node in which the script is stored.
* No way to rename a script in the script editor.
* No way to delete a script in the script editor.
* No way to run a script upon mind map opening or mind map closing ("hooks"). However, from a security standpoint, this is a bonus.
* The built-in script editor is very simple/spartan: for instance, there is no syntax highlighting and no API exploration, let alone debugging like in Microsoft Office.
 
==Freeplane==
You can find inspiration in the scripts published for Freeplane, FreeMind's fork; however, they are not guaranteed to work with FreeMind.
 
Links:
* [https://docs.freeplane.org/scripting/Scripting.html Scripting], docs.freeplane.org
* [https://docs.freeplane.org/scripting/Scripts_collection.html Scripts collection], docs.freeplane.org


==See also==
==See also==
* [[Scripting/Mind map documentation]]
* [[User-contributed example scripts]]
* [[FreeMind 0.9.0: The New Features]]
* [[FreeMind 0.9.0: The New Features]]
* [[Example scripts]]


[[Category:Development]]
[[Category:Development]]

Latest revision as of 11:13, 9 June 2023

Since Release 0.9.0, FreeMind has a scripting facility using Groovy programming language, an imperative language syntactically resembling Java but with some syntactic sugar added such as optional declaration of types. The best way to get started is perhaps by reading Scripting/Mind map documentation, the wiki version of the mind map documentation originally written by Christian Foltin. What follows here is less informative and consolidated than the mind map documentation. Another source is the dedicated page User-contributed example scripts for scripts supplied by FreeMind users.

Using

Each script is stored in a named attribute of a node, named for example as "script1" or "script2". One node can have several scripts attached. There is no way to store scripts in a script file for the whole application; scripts can only be stored in mind maps[verify].

To add a new script to a node:

  • Use the script editor, available from the menu Tools > Script Editor. A window pops up. There, choose menu Action > New script. A new script name appears in the top left pane, starting with "script", followed by "1" or higher if there already are scripts attached to the node blocking that name. Enter the script source code into the top right pane. Then you can choose menu Actions > Save and Exit to save the script, or you can immediately run it via menu Actions > Run.
  • Alternatively, you can create an attribute whose name starts with "script" such as "script1" or "scriptA"; such an attribute is understood by FreeMind to be a script. This you can do via menu Edit > Edit Attributes (Alt + F9). However, this is rather inconvenient as the field for the attribute value is small.

To run a single script:

  • Use the script editor (Tools > Script Editor), and its menu item Actions > Run.
  • The Run function of the script editor shows the results of the execution in the pane at the bottom, and it shows error messages there, if any.

To run all the scripts in a mind map:

  • Use the menu Tools > Evaluate or press Alt + F8. By default, the function asks for confirmation, for security reasons.

To delete a script:

  • There is no menu in the script editor to do that. You can delete the corresponding attribute, by placing the cursor over the attribute, and in the context menu choosing Delete.

For more detail, see the FreeMind documentation available from the menu Help > Documentation, the section "New features in version 0.9.0" and the subsection "Scripting support".

Access points

Access points to scripting functionality, for reference:

  • Menu: Tools > Script Editor
  • In Script Editor
    • Menu: Actions > New Script
    • Menu: Actions > Run
    • Menu: Actions > Sign Script...
    • Menu: Dismiss Changes and Exit
    • Menu: Save and Exit
  • Menu: Tools > Evaluate: run all the scripts in a mind map; keyboard shortcut: Alt + F8
  • Menu: Tools > Preferences > pane Scripting
    • Checkbox: Permit File Operations
    • Checkbox: Permit Network Operations
    • Checkbox: Permit To Execute Other Applicatios
    • Checkbox: Trust Signed Scripts
    • Input field: Optional User Key Alias for Signing
  • Menu: Edit > Edit Attributes; keyboard shortcut Alt + F9

Examples

Some example scripts follow. They take advantage of 1) = for assignment of the result of a calculation, 2) c for controller, and 3) node for the script node.

One-liner examples:

  • Setting a new text of a node: =12 * 14. Scripts starting with "=" replace the text of a node with their results. A shorthand.
  • Setting a new attribute value: myattribute=5 * 6. Another shorthand.
  • Changing the text of a node: c.setNodeText(node, node.getText() + " - appended text")
  • Setting the text color of a node: c.setNodeColor(node, java.awt.Color.RED)
  • Setting the background color of a node: c.setNodeBackgroundColor(node, java.awt.Color.YELLOW)
  • Setting the value of an attribute: c.editAttribute(node, "myresult", "new value")
  • Setting the value of an attribute: c.editAttribute(node, "myresult", (String)(12*14)). Uses "(String)" to convert/cast the numerical result into a string. The bracket around 12*14 is mandatory.
  • Make bold: c.setBold(node, true);
  • Make italic: c.setItalic(node, true);
  • Set cloud: c.setCloud(node, true);
  • Set cloud color: c.setCloudColor(node, new java.awt.Color(0xEE, 0xEE, 0x99));. If there is no cloud, sets it; thus, c.setCloud() does not need to be called beforehand.
  • Add icon as the rightmost icon: c.addIcon(node, freemind.modes.MindIcon.factory("pencil")); The icon list is in Icons page.
  • Remove all icons: c.removeAllIcons(node);
  • Remove last icon: c.removeLastIcon(node);
  • Make node bold if folded: c.setBold(node, node.isFolded()) If not folded, make it non-bold.
  • Set hyperlink: c.setLink(node, "http://www.google.com/");
  • Make the currently selected node bold (not the script node): c.setBold(c.getSelected(), true);

Short multiline examples:

Turn currently selected nodes bold:

selectedNodesIt = c.getSelecteds().iterator();
while (selectedNodesIt.hasNext()) {
   selNode = selectedNodesIt.next(); 
   c.setBold(selNode, true);   
}

Count descendants, exluding the node itself:

nodeCount = 0;
def stack = new java.util.Stack();
stack.push(node);
while (stack.size() > 0) {
    def currNode = stack.pop();
    if (node != currNode)   
        nodeCount += 1;
    stack.addAll(currNode.getChildren());
}
c.editAttribute(node, "mynodecount", (String)nodeCount);

Sum the values of cost attribute of descendants, storing the result to costTotal attribute:

costTotal = 0;
def stack = new java.util.Stack();
stack.push(node);
while (stack.size() > 0) {   
    def currNode = stack.pop();
    if (node != currNode) {
       costTotal += Integer.parseInt(currNode.getAttribute("cost"));
    }
    stack.addAll(currNode.getChildren());
}
c.editAttribute(node, "costTotal", (String)costTotal);

See also Example scripts.

For another set of examples, see the FreeMind documentation available from the menu Help > Documentation, the section "New features in version 0.9.0" and the subsection "Scripting support"; this is also available here: Scripting/Mind map documentation.

Script editor

FreeMind has a very simplistic script editor, available from menu Tools > Script Editor. The editor has no color highlighting of code, and no specific support for writing Groovy scripts: it is basically a plain text editor like Notepad.

The editor has three panes: left one, right one, and bottom one. The left pane shows a list of scripts attached to a node. The right pane shows the script selected in the left pane. The bottom pane shows the results of the execution of a script.

The actions available in the menu Action of the script editor are New Script, Run, Sign Script, Dismiss Changes and Exit, and Save and Exit.

The action Action > New Script adds a new script to the left pane, named as "script1", "script2", etc. The newly created script can be edited in the right pane once the name of the script is selected in the left pane.

The action Action > Run runs the script selected in the left pane, and shows the result of running the script in the bottom pane, including any error messages.

The action Action > Sign Script makes it possible to sign a script. [To be documented].

API

The scripts can access FreeMind's scripting API--application programming interface. Above all, the scripts would typically make use of the methods of MindMapController. The mind map controller is available to scripts as 'c'.

The variables made available to scripts, with their types:

  • MindMapController c: the controller
  • MindMapNode node: the node the script is stored in, not the currently selected one
  • HashMap cookies sScriptCookies: A hashmap of key-value pairs (TBD:WHAT IS THIS ANYWAY?)

We suggest you use the FreeMind source code and an Integrate Development Environment (IDE) to explore the types and methods available.

Java sources exposing the API:

Security

By default, FreeMind scripts are restricted in what they can do on the local computer. The restrictions include those of file operations, network operations and execution of applications. These restrictions can be lifted in user preferences, from the menu Tools > Preferences..., and the section "Scripting".

The available security options for scripting, in the section "Scripting" and subsection "Permissions":

  • Permit File Operations
  • Permit Network Operations
  • Permit to Execute Other Applications
  • Trust Signed Scripts
  • Optional User Key Alias for Signing

Groovy

The scripting engine and language of FreeMind is Groovy. To find out about Groovy, you can check the following web resources:

Implementation

Scripts are stored in attributes whose names starts with "script", meaning in the attribute of the attribute function, not in the attribute of XML. Thus, the script attribute can be called "script1", "script_A", or "script_sum_calculation". Attributes created via Actions > New Script menu in the script editor are of the form "scriptN", where N is a positive integer (1, 2, ...).

The script attributes are probably distinguished from non-script attributes by their starting with "script".

An example of storage in XML:

<node TEXT="hello">
<attribute NAME="script1" VALUE="=node.getNodeLevel() + &quot; &quot; + node.getText()"/>
</node>

Scripting is implemented as an external plugin.

Package: freemind/plugins/script/

Limitations

  • No way to store scripts in a script file for the whole FreeMind application; scripts can only be stored in mind maps.
  • Having the scripts associated with a particular node rather than the whole mind map is not necessarily ideal. It is uncustomary from the perspective of an office application.
  • Storing scripts in user-defined attributes is arguably not so nice; this is not what attributes are for.
  • No way to run a single script outside of the script editor. It is only within the script editor that one can run a single selected script. Outside of the script editor, there is the function to run all scripts stored in the nodes of the mind map. As a result, if there are multiple scripts in the mind map, there is not way to run a single script on the currently selected node, given that the currently selected node is in general distinct from the node in which the script is stored.
  • No way to rename a script in the script editor.
  • No way to delete a script in the script editor.
  • No way to run a script upon mind map opening or mind map closing ("hooks"). However, from a security standpoint, this is a bonus.
  • The built-in script editor is very simple/spartan: for instance, there is no syntax highlighting and no API exploration, let alone debugging like in Microsoft Office.

Freeplane

You can find inspiration in the scripts published for Freeplane, FreeMind's fork; however, they are not guaranteed to work with FreeMind.

Links:

See also