ScriptFu: update devel docs re version 3 changes
This commit is contained in:
parent
1384bf8c28
commit
ff1ad6d605
2 changed files with 355 additions and 259 deletions
|
|
@ -1,14 +1,62 @@
|
|||
# Guide to changes to ScriptFu v3 for script authors
|
||||
|
||||
*Draft, until GIMP 3 is final. FIXME: rearrange and rename the cited documents*
|
||||
|
||||
## About
|
||||
|
||||
The audience is authors of Scriptfu plugins.
|
||||
This discusses how to edit v2 scripts so they will run in GIMP 3.
|
||||
It also discusses enhancements to ScriptFu and its language.
|
||||
|
||||
This is only about changes to ScriptFu proper.
|
||||
The GIMP PDB, which you can call in scripts, has also changed.
|
||||
## Quickstart
|
||||
|
||||
A lucky few existing scripts may work in GIMP v3 without change.
|
||||
|
||||
### Required changes
|
||||
|
||||
Some changes are *required* in existing plugins:
|
||||
|
||||
- many PDB procedures are obsolete or renamed, or their signature changed
|
||||
- the symbol SF-VALUE is obolete
|
||||
|
||||
Once you edit a script for these changes, the script won't work in GIMP v2.
|
||||
|
||||
Most scripts will require edits due to changed PDB API.
|
||||
|
||||
### Optional changes
|
||||
|
||||
Other changes to scripts are *optional*.
|
||||
Such changes use improved features of ScriptFu.
|
||||
|
||||
In approximate order of importance:
|
||||
|
||||
- you can install scripts like plugins in other languages
|
||||
- you can use new, specific registration functions instead of the generic script-fu-register
|
||||
- scripts can use the new mult-layer selection feature of GIMP
|
||||
- scripts can use a v3 dialect having more natural binding of return values from PDB calls
|
||||
- the symbolic constants TRUE and FALSE are deprecated, except for SF-TOGGLE
|
||||
- a script can *quit* with an error code
|
||||
- a script can call *display* to print to the terminal
|
||||
|
||||
Enhancements to ScriptFu might not affect an existing plugin.
|
||||
You need only understand those enhancements when you want to use them.
|
||||
|
||||
### Why these changes now?
|
||||
|
||||
GIMP 3 is a major version change with new features.
|
||||
A major version allows breaking API,
|
||||
meaning old plugins and scripts might not work.
|
||||
|
||||
The GIMP developers understand these changes may be onerous.
|
||||
Script developers might need to maintain two different versions of their scripts.
|
||||
Some users will stick with GIMP 2 for a while and some will switch to GIMP 3.
|
||||
|
||||
A major version is necessary to move forward.
|
||||
The situation is similar to the disruption caused by the move from Python 2 to 3.
|
||||
|
||||
## Changed PDB API
|
||||
|
||||
*You must edit your scripts to conform to version 3 of the PDB API.*
|
||||
|
||||
The GIMP PDB (Programmers Data Base), that you can call in scripts, has changed in GIMP version 3.
|
||||
That also may require you to edit scripts.
|
||||
|
||||
- For changes in signatures of PDB procedures,
|
||||
|
|
@ -16,40 +64,13 @@ That also may require you to edit scripts.
|
|||
- For added, removed, and replaced PDB procedures,
|
||||
see devel-docs/GIMP3-plug-in-porting-guide/removed_functions.md
|
||||
|
||||
## Quickstart
|
||||
Some of the changes are for the multi-layer select feature of GIMP 3.
|
||||
Many PDB procedures now take a container (a Scheme vector) of drawables
|
||||
instead of a single drawable.
|
||||
|
||||
A lucky few existing scripts may work in GIMP v3.
|
||||
## SF-VALUE type of argument is obsolete
|
||||
|
||||
Some changes are most likely to break an existing plugin.:
|
||||
|
||||
- many PDB procedures are obsolete or renamed, or their signature changed
|
||||
|
||||
Once you edit a script for these changes, the script won't work in GIMP v2.
|
||||
|
||||
Other changes:
|
||||
|
||||
- you can use new, specific registration functions instead of the generic script-fu-register
|
||||
- you can install scripts like plugins in other languages
|
||||
- scripts can use the new mult-layer selection feature of GIMP
|
||||
- a script can abort with an error message
|
||||
- a script's settings are more fully saved
|
||||
|
||||
Those changes might not affect an existing plugin.
|
||||
You need only understand those changes when you want to use new features of GIMP.
|
||||
|
||||
A word of explanation: the GIMP developers understand these changes may be onerous.
|
||||
Script developers might need to maintain two different versions of their scripts.
|
||||
Some users will stick with GIMP 2 for a while and some will switch to GIMP 3.
|
||||
But GIMP 3 is a major version change with new features.
|
||||
A clean break is necessary to move forward with improvements.
|
||||
The situation is similar to the disruption caused by the move from Python 2 to 3.
|
||||
|
||||
## Deprecated ScriptFu constants
|
||||
|
||||
### SF-VALUE kind of argument is deprecated
|
||||
|
||||
The symbol SF-VALUE is deprecated.
|
||||
You can edit v2 scripts and replace that symbol.
|
||||
*You must edit v2 scripts and replace the symbol SF-VALUE.*
|
||||
|
||||
In v2, SF-VALUE declared a formal argument that is an unquoted, arbitrary string.
|
||||
Usually, SF-VALUE was used for an integer valued argument.
|
||||
|
|
@ -60,9 +81,9 @@ but the widget let you enter any text into the string.
|
|||
You usually will replace it with an SF-ADJUSTMENT kind of formal argument,
|
||||
where the "digits" field of the SF-ADJUSTMENT is 0,
|
||||
meaning no decimal places, i.e. integer valued.
|
||||
You must also add the other fields, e.g. the lower and upper limits.
|
||||
You must also provide other fields, e.g. the lower and upper limits.
|
||||
|
||||
A script that has been edited to replace SF-VALUE with SF-ADJUSTMENT
|
||||
A script that has SF-VALUE replaced with SF-ADJUSTMENT
|
||||
will remain compatible with GIMP 2.
|
||||
|
||||
Example:
|
||||
|
|
@ -83,7 +104,7 @@ used SF-VALUE to declare a formal argument that is float valued:
|
|||
Here, the 1 denotes: show 1 decimal place, for example "45.0",
|
||||
in the dialog widget.
|
||||
|
||||
#### Use SF-STRING for some use cases
|
||||
### Use SF-STRING for some use cases
|
||||
|
||||
In v2, a SF-VALUE argument let a user enter executable Scheme code,
|
||||
say "'(1 g 1)", which is a list literal,
|
||||
|
|
@ -92,7 +113,7 @@ That use is no longer possible.
|
|||
If you must do that, use SF_STRING to get a string,
|
||||
and then your plugin can eval the string.
|
||||
|
||||
#### Arbitrary precision floats
|
||||
### Arbitrary precision floats
|
||||
|
||||
In v2, a SF-VALUE argument let a user enter a float with arbitrary precision,
|
||||
e.g. "0.00000001"
|
||||
|
|
@ -114,204 +135,33 @@ If you actually need arbitrary precision, use SF_STRING to get a string,
|
|||
and then your plugin can eval the string to get a Scheme numeric
|
||||
of the maximum precision that Scheme supports.
|
||||
|
||||
#### Rationale
|
||||
### Rationale
|
||||
|
||||
Formerly, a SF-VALUE argument let a user enter garbage for an argument,
|
||||
which caused an error in the script.
|
||||
SF-ADJUSTMENT is more user-friendly.
|
||||
|
||||
### FALSE and TRUE symbols deprecated
|
||||
|
||||
FALSE and TRUE symbols are deprecated in the ScriptFu language.
|
||||
They never were in the Scheme language.
|
||||
Instead, you can use the Scheme language symbols #f and #t.
|
||||
|
||||
In ScriptFu v2, FALSE was equivalent to 0
|
||||
and TRUE was equivalent to 1.
|
||||
But FALSE was not equivalent to #f.
|
||||
|
||||
Formerly, you could use the = operator to compare to FALSE and TRUE.
|
||||
The = operator in Scheme is a numeric operator, not a logical operator.
|
||||
Now you can use the eq? or eqv? operators.
|
||||
|
||||
In Scheme, all values are truthy except for #f.
|
||||
The empty list is truthy.
|
||||
The numeric 0 is truthy.
|
||||
Only #f is not truthy.
|
||||
|
||||
A PDB procedure returning a single Boolean (a predicate)
|
||||
returns a list containing one element, for example (#f) or (#t).
|
||||
|
||||
#### Rationale
|
||||
|
||||
The ScriptFu language is simpler and smaller; TRUE and FALSE duplicated concepts already in the Scheme language.
|
||||
|
||||
#### Example changes
|
||||
|
||||
Declaring a script:
|
||||
|
||||
SF-TOGGLE "Gradient reverse" FALSE
|
||||
=>
|
||||
SF-TOGGLE "Gradient reverse" #f
|
||||
|
||||
Calling a PDB procedure taking a boolean:
|
||||
|
||||
(gimp-context-set-feather TRUE)
|
||||
=>
|
||||
(gimp-context-set-feather #t)
|
||||
|
||||
Logically examining a variable for truth:
|
||||
|
||||
(if (= shadow TRUE) ...
|
||||
=>
|
||||
(if shadow ...
|
||||
|
||||
|
||||
## v3 binding of PDB return values
|
||||
|
||||
TODO this needs rewrite. When first written, we anticipated
|
||||
a breaking change to the binding.
|
||||
Now the binding version is a choice,
|
||||
settable at runtime.
|
||||
Scripts can opt to use the new binding.
|
||||
|
||||
### In scripts, calls to PDB procedures that return boolean yield (#t) or (#f)
|
||||
|
||||
In ScriptFu v2, PDB procedures returning a boolean returned 1 or 0 to a script,
|
||||
that is, numeric values.
|
||||
Those were equal to the old TRUE and FALSE values.
|
||||
|
||||
Remember that a call to the PDB returns a list to the script.
|
||||
So in ScriptFu v3,
|
||||
a PDB procedure that returns a single boolean (a predicate function)
|
||||
returns (#t) or (#f), a list containing one boolean element.
|
||||
|
||||
#### Rationale
|
||||
|
||||
#t and #f are more precise representations of boolean values.
|
||||
0 and 1 are binary, but not strictly boolean.
|
||||
|
||||
The ScriptFu language is smaller if concepts of truth are not duplicated.
|
||||
|
||||
#### Example changes
|
||||
|
||||
Calling a PDB procedure that is a predicate function:
|
||||
|
||||
(if (= FALSE (car (gimp-selection-is-empty theImage))) ...
|
||||
=>
|
||||
(if (car (gimp-selection-is-empty theImage)) ...
|
||||
|
||||
Here, the call to the PDB returns a list of one element.
|
||||
The "car" function returns that element.
|
||||
The "if" function evaluates that element for truthy.
|
||||
|
||||
Note that to evaluate the result of a PDB call for truth,
|
||||
you should just use as above, and not use "eq?" or "eqv?".
|
||||
Such a result is always a list, and a list is truthy,
|
||||
but not equivalent to #t.
|
||||
In the ScriptFu console:
|
||||
|
||||
>(eq? #t '())
|
||||
#f
|
||||
>(eqv? #t '())
|
||||
#f
|
||||
|
||||
## Use script-fu-script-abort to throw an error
|
||||
|
||||
The function "script-fu-script-abort" is new to ScriptFu v3.
|
||||
|
||||
It causes the interpreter to stop evaluating a script
|
||||
and yield an error of type GimpPDBStatus.
|
||||
That is, it immediately returns an error to the caller.
|
||||
It is similar to the "return" statement in other languages,
|
||||
but the Scheme language has no "return" statement.
|
||||
|
||||
The function takes an error message string.
|
||||
|
||||
When the caller is the GIMP app,
|
||||
the GIMP app will show an error dialog
|
||||
having the message string.
|
||||
|
||||
When the caller is another PDB procedure (a plugin or script)
|
||||
the caller must check the result of a call to the PDB
|
||||
and propagate the error.
|
||||
ScriptFu itself always checks the result of a call to the PDB
|
||||
and propagates the error,
|
||||
concatenating error message strings.
|
||||
|
||||
The function can be used anywhere in a script,
|
||||
like you would a "return" statement in other languages.
|
||||
|
||||
Alternatively, a script can yield #f to yield a PDB error.
|
||||
See below.
|
||||
|
||||
#### Rationale
|
||||
|
||||
Formerly, scripts usually called gimp-message on errors,
|
||||
without yielding an error to the caller.
|
||||
It was easy for a user to overlook the error message.
|
||||
An abort shows an error message that a user must acknowledge
|
||||
by choosing an OK button.
|
||||
|
||||
#### Example
|
||||
|
||||
This script defines a PDB procedure that aborts:
|
||||
|
||||
(define (script-fu-abort)
|
||||
(script-fu-script-abort "Too many drawables.")
|
||||
(gimp-message "this never evaluated")
|
||||
)
|
||||
...
|
||||
|
||||
## A script can yield #f to throw an error
|
||||
|
||||
Here we use the word "yield" instead of the word "return".
|
||||
Neither "yield" nor "return" are reserved words in the Scheme language.
|
||||
|
||||
A Scheme text evaluates to, or yields, the value of its last expression.
|
||||
Any value other than #f, even the empty list or the list containing #f,
|
||||
is truthy.
|
||||
|
||||
A ScriptFu plugin
|
||||
(the PDB procedure that a script defines in its run func)
|
||||
whose last evaluated expression is #f
|
||||
will yield an error of type GimpPDBStatus.
|
||||
|
||||
If you don't want a ScriptFu plugin to yield an error,
|
||||
it must not evaluate to #f.
|
||||
Most existing plugins won't, since their last evaluated expression
|
||||
is usually a call to the PDB yielding a list, which is not equivalent to #f.
|
||||
|
||||
*Remember that ScriptFu does not yet let you declare PDB procedures
|
||||
that return values to the caller.
|
||||
That is, you can only declare a void procedure, having only side effects.
|
||||
So to yield #f does not mean to return a boolean to the caller.*
|
||||
|
||||
*Also, you can define Scheme functions internal to a script
|
||||
that yield #f but that do not signify errors.
|
||||
It is only the "run func" that defines a PDB procedure that,
|
||||
yielding #f, yields a PDB error to the caller.*
|
||||
|
||||
|
||||
#### Examples
|
||||
|
||||
(define (script-fu-always-fail)
|
||||
(begin
|
||||
; this will be evaluated and show a message in GIMP status bar
|
||||
(gimp-message "Failing")
|
||||
; since last expression, is the result, and will mean error
|
||||
#f
|
||||
)
|
||||
)
|
||||
SF-ADJUSTMENT or SF-STRING is more user-friendly.
|
||||
|
||||
## You can optionally install scripts like plugins in other languages
|
||||
|
||||
In v3 you can install ScriptFu scripts to a /plug-ins directory.
|
||||
*We recommend this for new plugins.*
|
||||
|
||||
In v3 you can install ScriptFu scripts to a /plug-ins directory,
|
||||
like plugins in other languages.
|
||||
This helps isolate plugins.
|
||||
|
||||
You must edit the script to include a shebang in the first line:
|
||||
|
||||
#!/usr/bin/env gimp-script-fu-interpreter-3.0
|
||||
;!# Close comment started on first line.
|
||||
|
||||
In v2 all ScriptFu scripts were usually installed in a /scripts directory.
|
||||
If the script has translatable strings, it should also have a second line
|
||||
as above, to accomodate parsing by gettext.
|
||||
(Note that ScriptFu doesn't actually support multi-line comments using #!,
|
||||
and this is a trick to fool gettext, which parses a script as if
|
||||
it did support multi-line comments.)
|
||||
|
||||
|
||||
In v2 all ScriptFu scripts were installed in a /scripts directory.
|
||||
In v3 you may install ScriptFu scripts with a shebang
|
||||
in a subdirectory of a /plug-ins directory.
|
||||
|
||||
|
|
@ -325,37 +175,43 @@ A script file must:
|
|||
|
||||
An example path to a script:
|
||||
|
||||
~/.config/GIMP/2.99/plug-ins/myScript/myScript.scm
|
||||
~/.config/GIMP/2.99/plug-ins/script-fu-my/script-fu-my.scm
|
||||
|
||||
Such a script will execute in its own process.
|
||||
The advantage of installing a script in the /plug-ins directory is that
|
||||
such a script will execute in its own process.
|
||||
If it crashes, it doesn't affect GIMP or other scripts.
|
||||
In v2, all scripts in the /scripts directory are executed by the long-lived
|
||||
process "extension-script-fu."
|
||||
|
||||
Conversely, in v2, all scripts in the /scripts directory
|
||||
are executed by the long-lived process "extension-script-fu."
|
||||
If one of those scripts crash, menu items implemented by ScriptFu dissappear
|
||||
from the GIMP app, and you should restart GIMP.
|
||||
|
||||
## Changes in registration functions
|
||||
It is only a convention to name scripts starting with "script-fu-".
|
||||
|
||||
ScriptFu defines "registration" functions, letting you declare a plugin PDB procedure.
|
||||
## Using new registration functions
|
||||
|
||||
ScriptFu v2 has only *script-fu-register*.
|
||||
It was a generic function used to declare procedures that are either:
|
||||
*We recommend this.*
|
||||
|
||||
* generic procedures (operating without an image.)
|
||||
* filters/renderers (operating on an image)
|
||||
New registration functions let a plugin dialog have a new look-and-feel
|
||||
and improved settings.
|
||||
ScriptFu "registration" functions let you declare a plugin PDB procedure,
|
||||
and how it's dialog will look.
|
||||
|
||||
The new registration functions are:
|
||||
ScriptFu v3 has two new registration functions:
|
||||
|
||||
* *script-fu-register-procedure*
|
||||
* *script-fu-register-filter*
|
||||
|
||||
The new registration functions let a plugin have a new look-and-feel
|
||||
and improved settings.
|
||||
|
||||
Terminology: you *declare* a plugin's attributes and signature using a registration function.
|
||||
You *define* a run func with a similar signature.
|
||||
ScriptFu *registers* the plugin in the PDB.
|
||||
|
||||
ScriptFu v2 has only *script-fu-register*.
|
||||
It is a generic function used to declare procedures that are either:
|
||||
|
||||
* generic procedures (operating without an image.)
|
||||
* filters/renderers (operating on an image)
|
||||
|
||||
### Registration function *script-fu-register* is now deprecated.
|
||||
|
||||
**You should not use script-fu-register in new ScriptFu scripts.**
|
||||
|
|
@ -604,4 +460,166 @@ That is a programming error in the calling procedure.
|
|||
|
||||
A well-written called plugin that is passed more drawables than declared
|
||||
should return an error instead of processing any of the drawables.
|
||||
Similarly for fewer than declared.
|
||||
Similarly for fewer than declared.
|
||||
|
||||
## Using the v3 dialect for PDB return values
|
||||
|
||||
*We recommend this for new scripts.*
|
||||
|
||||
ScriptFu in GIMP version 3 will optionally interpret a v3 dialect.
|
||||
The dialect is more natural to the Scheme language.
|
||||
The dialect affects the binding of return values from calls to the PDB.
|
||||
|
||||
A script opts into the v3 dialect at runtime by calling script-fu-use-v3
|
||||
at the beginning of the run func..
|
||||
|
||||
The advantage of the v3 dialect is that scripts are smaller,
|
||||
with fewer calls to car.
|
||||
Also, you can more naturally examine boolean values.
|
||||
|
||||
For more information, see the document in the GIMP source /plugins/script-fu/docs/using-v3-binding.md
|
||||
|
||||
## FALSE and TRUE symbols are deprecated
|
||||
|
||||
*We recommend not using TRUE and FALSE in new scripts, except for an SF-TOGGLE argument.*
|
||||
|
||||
FALSE and TRUE symbols are deprecated in the ScriptFu language.
|
||||
They never were in the Scheme language.
|
||||
|
||||
Instead, you should use the v3 dialect
|
||||
and use the Scheme language symbols #f and #t.
|
||||
|
||||
In ScriptFu, FALSE is 0
|
||||
and TRUE is 1.
|
||||
But FALSE is not equivalent to #f.
|
||||
|
||||
You must use the = operator to compare to FALSE and TRUE.
|
||||
FALSE and TRUE are numeric.
|
||||
The = operator in Scheme is a numeric operator, not a logical operator.
|
||||
|
||||
In Scheme, all values are truthy except for #f.
|
||||
The empty list is truthy.
|
||||
The numeric 0 is truthy.
|
||||
Only #f is not truthy.
|
||||
|
||||
In the v3 dialect, a PDB procedure returning a single Boolean (a predicate)
|
||||
returns one element, for example #f or #t.
|
||||
|
||||
In the v2 dialect, it still returns (0) or (1),
|
||||
that is, numeric 0 or 1 wrapped in a list.
|
||||
|
||||
*You still need to compare boolean SF_TOGGLE arguments to a script with TRUE and FALSE.
|
||||
They are not #t and #f*.
|
||||
|
||||
#### Rationale
|
||||
|
||||
The ScriptFu language is simpler and smaller; TRUE and FALSE duplicated concepts already in the Scheme language.
|
||||
|
||||
#### Example changes
|
||||
|
||||
Declaring a script's SF_TOGGLE arguments can still use TRUE and FALSE.
|
||||
|
||||
SF-TOGGLE "Gradient reverse" FALSE
|
||||
|
||||
Comparing a boolean argument to a script *must* remain as in v2 dialect:
|
||||
|
||||
(if (= should-invert TRUE)
|
||||
; do invert )
|
||||
|
||||
Calling a PDB procedure taking a boolean:
|
||||
|
||||
(gimp-context-set-feather TRUE)
|
||||
=>
|
||||
(gimp-context-set-feather #t)
|
||||
|
||||
Logically examining a variable for truth:
|
||||
|
||||
(if (= shadow TRUE) ...
|
||||
=>
|
||||
(if shadow ...
|
||||
|
||||
## Using the quit function to abort a script
|
||||
|
||||
*We recommend using quit to declare errors* along with gimp-message.
|
||||
|
||||
The function "quit" is in Scheme.
|
||||
It causes a script to exit i.e. return to the system.
|
||||
The function can be used anywhere in a script,
|
||||
like you would a "return" statement in other languages.
|
||||
|
||||
In ScriptFu v3 it causes the interpreter to stop interpreting a script
|
||||
and yield an error of type GimpPDBStatus.
|
||||
That is, it immediately returns an error to the GIMP app or other caller.
|
||||
The GIMP app will show an error message including the phrase
|
||||
"script quit with error code x."
|
||||
|
||||
When the caller is another PDB procedure (a plugin or script)
|
||||
the caller should check the result of a call to the script
|
||||
and propagate the error.
|
||||
ScriptFu itself always checks the result of a call to the PDB
|
||||
and propagates the error,
|
||||
concatenating error message strings.
|
||||
|
||||
In ScriptFu v2, a call such as (quit -1) did abort the script,
|
||||
but did not return an error to the caller
|
||||
(usually the GIMP app)
|
||||
and did not return the error code.
|
||||
|
||||
### A script doesn't return a value
|
||||
|
||||
In ScriptFu, a script returns void.
|
||||
It is not possible to define a plugin script that returns useful values.
|
||||
Note that script registration functions do not declare return values.
|
||||
Scripts only have side effects.
|
||||
|
||||
The last expression in a script plugin is *not* the value of the plugin,
|
||||
as it is in Scheme.
|
||||
|
||||
As a PDB procedure, a script can succeed or fail.
|
||||
But success does not depend on the value of the last evaluated expression.
|
||||
To make a script return failure, you should call the quit function.
|
||||
|
||||
#### Rationale
|
||||
|
||||
Formerly, scripts usually called gimp-message on errors,
|
||||
without yielding an error to the caller.
|
||||
It was easy for a user to overlook the error message.
|
||||
|
||||
You should still call gimp-message just before calling quit,
|
||||
with an informative error message.
|
||||
The numeric code that quit prints is not informative to users,
|
||||
only to the script author.
|
||||
|
||||
#### Example
|
||||
|
||||
This script quits early:
|
||||
|
||||
(define (script-fu-my-plugin)
|
||||
...
|
||||
(gimp-message "Too many drawables.")
|
||||
(quit -1)
|
||||
(display "this never evaluated")
|
||||
)
|
||||
...
|
||||
|
||||
## Using the display function to write to the terminal
|
||||
|
||||
*We recommend using the display function to help debug a script or to log,
|
||||
but not to prompt for user input.*
|
||||
|
||||
Display is a Scheme function, in the R5RS standard.
|
||||
It should write a string to any open terminal (e.g stdout on Linux.)
|
||||
|
||||
In ScriptFu v3, it does.
|
||||
You will see the output in any terminal in which the GIMP app was started
|
||||
(which is optional, and not usually done on a graphical desktop.)
|
||||
|
||||
In ScriptFu v2, it did not write to a terminal.
|
||||
Display wrote to a stream which was returned to the GIMP app, and usually discarded (unless an error occurred, and then the stream
|
||||
was the prefix of the error message.)
|
||||
|
||||
Example:
|
||||
|
||||
(display "The script is here") (newline)
|
||||
|
||||
Note that displayln is not in ScriptFu.
|
||||
|
|
@ -1,11 +1,13 @@
|
|||
# The version 3 dialect of the ScriptFu language
|
||||
# Version 3 of the ScriptFu language
|
||||
|
||||
## About
|
||||
|
||||
This describes a new dialect of ScriptFu,
|
||||
used when a script calls: (script-fu-use-v3).
|
||||
This describes a new dialect of the ScriptFu language.
|
||||
ScriptFu interprets the dialect after a script calls: (script-fu-use-v3).
|
||||
The new dialect is more like Scheme and makes scripts shorter.
|
||||
The dialect only affects calls to the PDB.
|
||||
ScriptFu inteprets the old version 2 by default,
|
||||
unless a script calls script-fu-use-v3.
|
||||
|
||||
The audience is script authors and other developers.
|
||||
|
||||
|
|
@ -14,13 +16,20 @@ This describes the new dialect and how to port old scripts to the new dialect.
|
|||
|
||||
## Quick Start
|
||||
|
||||
ScriptFu inteprets the old version 2 by default,
|
||||
unless a script calls script-fu-use-v3.
|
||||
After a call to script-fu-use-v3,
|
||||
ScriptFu interprets the new dialect until the script finishes,
|
||||
or until the script calls script-fu-use-v2.
|
||||
A script can switch back and forth between dialects at runtime.
|
||||
|
||||
A script that calls:
|
||||
```
|
||||
(script-fu-use-v3)
|
||||
```
|
||||
binds to certain PDB calls differently:
|
||||
|
||||
1. PDB procedures that return single values return just that single value,
|
||||
1. PDB procedures that return single values (atoms) return just that single value,
|
||||
*not wrapped in a list.*
|
||||
Formerly, every PDB call returned a list (possibly nesting more lists.)
|
||||
|
||||
|
|
@ -39,12 +48,13 @@ until you call *script-fu-use-v2.*
|
|||
|
||||
## Where to call *script-fu-use-v3* in scripts
|
||||
|
||||
Call *script-fu-use-v3* early.
|
||||
This sets the dialect version for the remaining interpretation of the script.
|
||||
Call *script-fu-use-v3* at the beginning of the run function.
|
||||
This sets the dialect version for the remaining interpretation
|
||||
of the script.
|
||||
|
||||
!!! Do not call *script-fu-use-v3* at the top level of a script.
|
||||
This has no effect, since it is only executed in the query phase.
|
||||
This has no effect, since it is only executed in the query phase
|
||||
of a plugin.
|
||||
The interpreter starts at the run function during the run phase.
|
||||
|
||||
*The interpreter always starts interpreting each script in the v2 dialect.
|
||||
|
|
@ -60,24 +70,26 @@ Example:
|
|||
(let* (
|
||||
...
|
||||
```
|
||||
### Technically speaking
|
||||
### Scope
|
||||
|
||||
The dialect version has "execution scope" versus "lexical scope."
|
||||
Setting the dialect version is effective even for
|
||||
other functions defined in the same script but lexically
|
||||
outside the function where the dialect is set.
|
||||
You only need to call script-fu-use-v3 once,
|
||||
not in every defined function.
|
||||
|
||||
|
||||
## Don't call v2 scripts from v3 scripts
|
||||
|
||||
When using the v3 dialect,
|
||||
you can't call plugin scripts or other library scripts that depend on the v2 dialect.
|
||||
you cannot call plugin Scheme scripts or other library scripts that are in the v2 dialect.
|
||||
And vice versa.
|
||||
(When a script calls a PDB procedure that is a script,
|
||||
(When a script calls a PDB procedure that is a Scheme script,
|
||||
a new interpreter process is *NOT* started.)
|
||||
|
||||
For example, a new plugin script should not call the PDB procedure
|
||||
script-fu-add-bevel because it is implemented in ScriptFu Scheme
|
||||
script-fu-add-bevel because it is a Scheme script in v2 dialect
|
||||
and for example has:
|
||||
|
||||
```
|
||||
|
|
@ -121,6 +133,30 @@ In the ScriptFu Console:
|
|||
|
||||
TRUE and FALSE symbols may become obsolete in the future.
|
||||
|
||||
## An argument of type SF-TOGGLE is FALSE or TRUE, not #f or #t
|
||||
|
||||
The v3 dialect does not affect the binding of arguments to a script.
|
||||
So the value of an argument of type SF-TOGGLE is zero or one,
|
||||
not #f or #t.
|
||||
|
||||
You must continue to check boolean arguments to a script like this:
|
||||
|
||||
```
|
||||
(define script-fu-my-plugin (should-invert)
|
||||
(if (= should-invert TRUE)
|
||||
(
|
||||
; do invert
|
||||
)))
|
||||
|
||||
(script-fu-register-procedure "script-fu-my-plugin"
|
||||
"My plugin..."
|
||||
...
|
||||
SF-TOGGLE "Invert?" FALSE
|
||||
)
|
||||
```
|
||||
This may change when in the future we obsolete v2 dialect
|
||||
and the symbols TRUE and FALSE.
|
||||
|
||||
## Plans for the future
|
||||
|
||||
This dialect is shorter and more natural for Scheme programmers.
|
||||
|
|
@ -133,9 +169,51 @@ You should write any new scripts in the v3 dialect,
|
|||
and call *script-fu-use-v3*.
|
||||
|
||||
You should plan on porting existing scripts to the v3 dialect,
|
||||
since eventually ScriptFu might not support v2 dialect.
|
||||
since eventually ScriptFu may obolete the v2 dialect.
|
||||
|
||||
## Example conversions from v2 to v3 dialects
|
||||
|
||||
### An example script using v3 dialect
|
||||
|
||||
```
|
||||
; !!! Usually not call (script-fu-use-v3) here in global scope
|
||||
|
||||
(define script-fu-my-plugin (should-invert)
|
||||
; the body switches to the v3 dialect
|
||||
(script-fu-use-v3)
|
||||
|
||||
(let* (
|
||||
; don't need a car, unlike v2
|
||||
(angle gimp-context-get-brush-angle)))
|
||||
|
||||
; call PDB returning boolean
|
||||
; don't need (= (car (gimp-context-get-feather)) TRUE)
|
||||
(if (gimp-context-get-feather)
|
||||
; do feather
|
||||
)
|
||||
|
||||
; boolean arg to script is still C notion of truth
|
||||
(if (= should-invert TRUE)
|
||||
(
|
||||
; do invert
|
||||
))
|
||||
|
||||
; calling a v2 plugin, temporarily switch to v2 dialect
|
||||
(script-fu-use-v2)
|
||||
(script-fu-add-bevel ...)
|
||||
|
||||
; rest of script in v3 dialect
|
||||
(script-fu-use-v3)
|
||||
...
|
||||
)
|
||||
|
||||
(script-fu-register-procedure "script-fu-my-plugin"
|
||||
"My plugin..."
|
||||
...
|
||||
SF-TOGGLE "Invert?" FALSE
|
||||
)
|
||||
```
|
||||
|
||||
## Example conversions from v2 to v3
|
||||
|
||||
### A call to a PDB procedure returning a single value
|
||||
|
||||
|
|
@ -211,7 +289,7 @@ and you must eliminate the first call to *car*.
|
|||
## Knowing what constructs need conversion
|
||||
|
||||
You *should* (but are not required to)
|
||||
eliminate all uses of symbols TRUE and FALSE from a script
|
||||
eliminate most uses of symbols TRUE and FALSE from a script
|
||||
using v3 dialect.
|
||||
|
||||
You should eliminate many, *but not all*, uses of the *car* function wrapping a call to the PDB,
|
||||
|
|
@ -234,7 +312,7 @@ Return Values
|
|||
Additional Information
|
||||
```
|
||||
This also returns a single value.
|
||||
The single value is a list i.e. container.
|
||||
But the single value is a list i.e. container, of strings.
|
||||
In the v2 dialect, this returned a list wrapped in a list,
|
||||
for example (("foo" "bar")).
|
||||
|
||||
|
|
@ -247,7 +325,7 @@ You should not need to change scripts on calls to PDB procedures returning C voi
|
|||
Some scripts might examine the result of a call to a void PDB procedure, thinking that (#t) is the success of the call,
|
||||
but that is a misconception and should be fixed.
|
||||
|
||||
Calls to PDB procedures that return C void return (#t) in v2 and the empty list (), sometimes called nil, in v3 dialect.
|
||||
Calls to PDB procedures that return C void return (#t) in v2 and the empty list () i.e. nil in v3 dialect.
|
||||
|
||||
## Details of the implementation
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue