GIMP Chat http://gimpchat.com/ |
|
Gimp Lambda Lib version 1.0.0 for Script-Fu http://gimpchat.com/viewtopic.php?f=9&t=19719 |
Page 1 of 1 |
Author: | AlSchemist [ Tue Nov 30, 2021 3:42 pm ] |
Post subject: | Gimp Lambda Lib version 1.0.0 for Script-Fu |
Foreword: this article focus more about the Scheme language implemented in Script-Fu for Gimp 2.10.28. Scheme is a Lisp dialect that is to say a functional programming language where f(x, y) is noted (f x y). 1. What are the features that Script-Fu supports? Open the Script-Fu console: Alt+filte(R)s → (S)cript-Fu → (C)onsole Copy in the clipboard by Ctrl+C the variable *features* between two stars then paste it in the input area of the Script-Fu console. Press ENTER to validate the command. The two stars mean that it is a predefined variable such *pi* 3.141592654 or *seed* 1 Code: Select all *features* ;-> (srfi-0 tinyscheme) is the list returned by Script-Fu. According to Wikipedia, SRFI stands for Scheme Requests For Implementation. The number "0" indicates the first level of SRFI. SRFI-0 by Marc Feeley 1999 is about "Feature-based conditional expansion construct" in short cond-expand. It is a conditional instruction to build libraries for specific targets for example the target "tinyscheme" that appears in 2nd position of the list returned by *features*. Attachment: LegacyLib.jpg [ 71.48 KiB | Viewed 2069 times ] If you edit for example in Notepad++: Code: Select all C:\Program Files\GIMP 2\share\gimp\2.0\scripts\script-fu.init you will find how is defined *features* line 684 then two lines after, cond-expand as a macro. In fact, Script-Fu supports more than SRFI-0 but partially. Retain that script-fu.init, script-fu-compat.init and plug-in-compat.init are the foundations of the Gimp 2.10.28 legacy library for Script-Fu. script-fu-compat.init and plug-in-compat.init are more for the compatibility with SIOD for Gimp 2.2 and mainly TinyScheme since Gimp 2.4 The Scheme file extension is .scm However the legacy library for Script-Fu is implemented in three text file source code .init The legacy library is automatically loaded at each time that you run Gimp. |
Author: | AlSchemist [ Wed Dec 01, 2021 3:17 pm ] |
Post subject: | Gimp Lambda Lib v1.0.0 for Gimp 2.10.28 Script-Fu |
2. Introducing Gimp Lambda Lib version 1.0.0 Attachment: filemngt-scripts.png [ 79.87 KiB | Viewed 2000 times ] GimpLambdaLib v1.0.0.0 2021 by AlSchemist is a free library for Gimp 2.10.28 Script-Fu that supports more SRFI than the legacy library supplied by default with Gimp. 2.1 Download Gimp Lambda Lib Where are the source files *.scm? In the AlSchemist's github. Browse the release: you can freely download the zipped archive of the source code V1.0.0.zip under "Assets". 2.2 Install Gimp Lambda Lib As usual, to install a .scm script, copy the source code in the Gimp script folder of the user: Code: Select all Copy *.scm "C:\Users\YourUserName\AppData\Roaming\GIMP\2.10\scripts\" Replace YourUserName with your Windows user name. Of course, it is not mandatory to copy all scripts *.scm You could make a progressive integration of the Gimp Lambda Lib step by step "à la carte". On consult 2.2. Installing Script-Fus However be sure to begin with script files of rank 0 that is to say beginning with "0". 2.3 How to know if Gimp Lambda Lib is well installed? Attachment: srfi-000-features.png [ 23.83 KiB | Viewed 2000 times ] Gimp menu "Filters" > "Script-Fu" > "Console" As in the previous post, copy in the clipboard by Ctrl+C the variable *features* then paste it in the input area of the Script-Fu console. Code: Select all *features* ;-> (tinyscheme srfi-0 srfi-1 srfi-2 srfi-6 srfi-8 srfi-9 srfi-13 srfi-23 srfi-30 srfi-32 srfi-47 srfi-60 srfi-66 srfi-111) is the list returned by Script-Fu. The SRFI numbers are a little bit abstract. Consider the supplied source code of rank 1 code-named 1srfi-000-cond-expand.scm Attachment: srfi-000-cond-expand.png [ 105.15 KiB | Viewed 2000 times ] 1srfi-000-cond-expand.scm explains and fixes the known bug of cond-expand in Gimp 2.10.28 since the "else" part is not implemented in the legacy library script-fu.init cond-expand tests if a SRFI is implemented or not. Code: Select all (cond-expand If you move 1srfi-000-cond-expand.scm to another folder than the Gimp script folder or if you did not yet install the Gimp Lambda Lib, Script-Fu will reply: ;-> #t without any message to really know if SRFI-38 is supported. |
Author: | AlSchemist [ Thu Dec 02, 2021 3:10 pm ] |
Post subject: | #| Multi-line block comment in Script-Fu |# |
3. SRFI-30 Nested Multi-line Comments The first script 0srfi-030-comment.scm of the Gimp Lambda Lib must be copied in the Gimp script folder of the user before any other source files of this library. SRFI-30 by Martin Gasbichler 2002 implements "Nested Multi-line Comments" between "#|" and "|#". Technically, Gimp Lambda Lib makes the integration of the SRFI-30 in the specific Gimp context of Script-Fu that exposes the system handler *sharp-hook*. Take a look at the two types of comments in the Script-Fu console: Attachment: iconGimpMultiCmt.png [ 81.88 KiB | Viewed 1928 times ] (For the sake of simplicity, it will be no longer mentioned that) you could copy and paste each code in the Script-Fu console then press ENTER key: Code: Select all #| Return Gimp version ;-> #<EOF> is the value of a comment according to Script-Fu. In Gimp 2.10.28, Script-Fu enables the single line comment starting with ";" until the end of line. SRFI-30 in Gimp Lambda Lib offers the block comment on several lines.
Attachment: srfi-030-comment.png [ 26.27 KiB | Viewed 1928 times ] Code: Select all #| SRFI-30 #| nested |# multi-line comment ;-> #<EOF> is returned by Script-Fu in the console. The second call of (gimp-version) is in a multi-line block comment. So instead of "(2.10.28)", Script-Fu replies #<EOF>, which is the value of a comment no matter the type of comment, full-line or multi-line. #<EOF> is also returned if a parenthesis is missing or if there is a syntax error. That is why each source code of the Gimp Lambda Lib never ends by a comment to avoid the returned value #<EOF>. Consult the last line 213 of 0srfi-030-comment.scm Code: Select all (closure? multiline-comment) Ask Script-Fu if the function multiline-comment is a closure that is to say a defined function. ;-> #t will reply Script-Fu that is to say multiline-comment is well defined in Script-Fu. The added-value of block multi-line comments in Gimp Lambda Lib is that the main functions are commented with a block comment above define with an example that you can directly copy and paste in the Script-Fu console like in this thread. The full-line comment ;-> indicates the expected result. If you have any issue to install or use the Gimp Lambda Lib, or if you wish more explanation about this thread, do not hesitate to reply with your questions since: Gimp Chat is the English forum of the Gimp Lambda Lib. |
Author: | AlSchemist [ Fri Dec 03, 2021 5:27 pm ] |
Post subject: | Initiation to Script-Fu from beginner to expert |
4. Seeking for deprecated functions Usage: Gimp menu "Filters" → "Script-Fu" → "Console" All codes could be copied (Ctrl+C) in the clipboard then pasted (Ctrl+V) in the input zone of the Script-Fu console. Press the ENTER key. In this thread, the expected result will be displayed after the green arrow ;-> 4.1 Revisiting gimp-procedural-db-query, car and cadr Do you remember the predicate deprecated? Firstly, we need the list of deprecated functions asking PDB: Procedural DataBase Code: Select all (gimp-procedural-db-query ".*" ".*deprecated.*" ".*deprecated.*" ".*" ".*" ".*" ".*") ;-> (204 ("gimp-brushes-get-brush-data" "gimp-drawable-transform-rotate-default" ... "gimp-convert-indexed")) Script-Fu returns a list with two elements:
To get the number of deprecated functions, use car that returns the first element of the given list. Code: Select all (car (gimp-procedural-db-query ".*" ".*deprecated.*" ".*deprecated.*" ".*" ".*" ".*" ".*")) ;-> 204 To get the list of deprecated functions, use cadr that returns the second element of the given list. Code: Select all (cadr (gimp-procedural-db-query ".*" ".*deprecated.*" ".*deprecated.*" ".*" ".*" ".*" ".*")) ;-> ("gimp-brushes-get-brush-data" ... "gimp-convert-indexed")) In fact, cadr is equivalent to: Code: Select all (car (cdr '(first second third etc))) ;-> second |
Author: | AlSchemist [ Fri Dec 03, 2021 5:34 pm ] |
Post subject: | (Let* ((localVariable1 init1) (localVariable2 ini2)) (body)) |
4.2 let* and its local variable(s), display vs. show We save the list of deprecated functions in a local variable called lstDeprecFnc in a structure called let*. Let us count the number of deprecated functions so we can compare with the expected value of 204: Code: Select all (let* ( (lstDeprecFnc (cadr (gimp-procedural-db-query ".*" ".*deprecated.*" ".*deprecated.*" ".*" ".*" ".*" ".*")))) ;-> Number of deprecated functions: 204 The function length returns the number of elements in the given list. If you have installed the Gimp Lambda Lib, you can simplify display and displayln by the generic show: Code: Select all (let* ( (lstDeprecFnc (cadr (gimp-procedural-db-query ".*" ".*deprecated.*" ".*deprecated.*" ".*" ".*" ".*" ".*")))) ;-> Number of deprecated functions: 204 |
Author: | AlSchemist [ Fri Dec 03, 2021 5:44 pm ] |
Post subject: | (Let loop ((prm1 init1) (prm2 init2)) (body)) |
4.3 let loop and not-pair? Let us introduce the basic iterator let loop to count the number of deprecated functions: Code: Select all (let* ( (lstDeprecFnc (cadr (gimp-procedural-db-query ".*" ".*deprecated.*" ".*deprecated.*" ".*" ".*" ".*" ".*")))) ;-> Number of deprecated functions: 204 loop is a function that accepts two parameters:
If the answer is true, in the then part, we call our function loop with:
The else part is reached if the lstWord becomes empty. We call our two display. Since there are more than one statement, we need to encapsulate them inside (begin ...). That is why, we prefer the version with the Gimp Lambda Lib introducing not-pair? = (not(pair? ...)) and the generic show without begin. Code: Select all (let* ( (lstDeprecFnc (cadr (gimp-procedural-db-query ".*" ".*deprecated.*" ".*deprecated.*" ".*" ".*" ".*" ".*")))) ;-> Number of deprecated functions: 204 We can simplify removing let*: Code: Select all (let loop ( (lstWord (cadr (gimp-procedural-db-query ".*" ".*deprecated.*" ".*deprecated.*" ".*" ".*" ".*" ".*"))) (count 0)) ;-> Number of deprecated functions: 204 |
Author: | AlSchemist [ Fri Dec 03, 2021 6:23 pm ] |
Post subject: | Level advanced: parsing a function |
4.4 proc->list and slow deprecated-list Download and install the old iccii-aquabou.scm version 1.3e in the script folder of the user. Restart Gimp. Then call the Gimp Lambda Lib function that transforms the definition of a function into a list. Code: Select all (proc->list script-fu-aqua-button2) ;-> (define (script-fu-aqua-button2 ... fond ombre base lum reflh))) The body of the legacy script-fu-aqua-button2 is enough long to scroll vertically the Script-Fu window. Hereafter enclosed is the parser seeking for deprecated functions in the definition of the function fnc: Code: Select all (define (deprecated-list fnc) ;-> deprecated-list In the let loop, the loop function accepts two parameters:
If item of the list of the body of fnc is a symbol (that is to say a word), we convert it to the string strItem with (symbol->string item). So we can extract its lenght len with (string-length strItem). The criteria if (and (> len 5) (not (member strItem lstDeprecUsed)) (member strItem lstDeprecFnc)) means:
Then part: the criteria matches. strItem is a deprecated function that we insert in the list of results by: (cons strItem lstDeprecUsed) (loop (cdr lstBody) (cons strItem lstDeprecUsed)) continues to parse the rest of the lstBody with partial result (cons strItem lstDeprecUsed). Else part: In case where item is not a symbol but a list: (if (list? item) (loop (cdr lstBody) (loop item lstDeprecUsed)) we loop at two levels:
Finally, if item is not a symbol and not a list, continue with the rest of lstBody with the current result in lstDeprecUsed: (loop (cdr lstBody) lstDeprecUsed) Let us call our new function deprecated-list with as parameter the legacy function script-fu-aqua-button2. Please pay attention that we directly use the name of the legacy function without double quotes. It is a procedure, a function, a closure but not a string. Code: Select all (deprecated-list script-fu-aqua-button2) What's happening? Nothing is written and the title of the title of the Script-Fu window becomes: Script-Fu (does not answer) or something like that. Please wait. Then... ;-> ("gimp-perspective" "gimp-selection-layer-alpha" "gimp-drawable-set-visible" "gimp-patterns-set-pattern" "gimp-blend" "gimp-gradients-set-gradient" "gimp-image-add-layer" "gimp-palette-set-background" "gimp-palette-set-foreground" "gimp-rect-select" "gimp-ellipse-select" "gimp-patterns-get-pattern" "gimp-gradients-get-gradient" "gimp-palette-get-background" "gimp-palette-get-foreground") Generally a second call is faster. So close Gimp, restart it and restore the same running context. How many times the parser needed to scan this legacy function? The function time-stat belongs to GimpLambdaLib: Code: Select all (let* ( (timeStart (gettimeofday))) ;-> 27 s 053 ms 816 µs for one run |
Author: | AlSchemist [ Fri Dec 03, 2021 6:35 pm ] |
Post subject: | Gimp Lambda Lib added-values: sorting, dichotomous search |
4.5 Advanced fast deprecated-list with binary search and sorting The added-value of the Gimp Lambda Lib is that you can improve the linear search of the function member using dichotomous research on sorted list:
Code: Select all (define (deprecated-list fnc) ;-> deprecated-list Code: Select all (deprecated-list script-fu-aqua-button2) ;-> ("gimp-blend" "gimp-drawable-set-visible" "gimp-ellipse-select" "gimp-gradients-get-gradient" "gimp-gradients-set-gradient" "gimp-image-add-layer" "gimp-palette-get-background" "gimp-palette-get-foreground" "gimp-palette-set-background" "gimp-palette-set-foreground" "gimp-patterns-get-pattern" "gimp-patterns-set-pattern" "gimp-perspective" "gimp-rect-select" "gimp-selection-layer-alpha") Close Gimp, restart it and restore the running context to compare with the slow version in the same conditions. How many times the advanced parser will need to scan this legacy function despite the conversion list to vector and the sorting: Code: Select all (let* ( (timeStart (gettimeofday))) ;-> 2 s 500 ms 395 µs for one run |
Author: | AlSchemist [ Sat Dec 04, 2021 4:07 pm ] |
Post subject: | Beautify Scheme code with pp: pretty-print |
5. Pretty-print or how to beautify Scheme code The real difficulty in the List dialects --no matter your level-- is to close correctly each open parenthesis. 5.1 Legacy pretty-print In 1991, Marc Feeley created the beautifier of source code called pp.scm standing for pretty-print. To optionally freely download pp.scm from the Indiana repository, you need any FTP software such as the free FileZilla. The legacy pretty-print begins by three full lines of comments starting with a semicolon in green: Attachment: pp-legacy.png [ 26.06 KiB | Viewed 1820 times ] Marc Feeley defined the de facto standard of presentation of Lisp code:
|
Author: | AlSchemist [ Sat Dec 04, 2021 4:23 pm ] |
Post subject: | Gimp Lambda Lib pretty-print |
Gimp Lambda Lib's beautifier: 2pp.scm of rank 2: The modern pretty-print is introduced with one multi-line block comment between "#|" and "|#" in dark blue. Attachment: pretty-print.png [ 101.39 KiB | Viewed 1820 times ]
In seeking for deprecated functions, we already used proc->list: Code: Select all (proc->list pp-call) ;-> (define (pp-call expr colFrom extra pp-item) (let* ((colAfter (wr (car expr) (pp-par-open colFrom))) (colMargin (- colAfter (remainder colAfter 4)))) (and colFrom (pp-down (cdr expr) colMargin (+ colMargin 4) extra pp-item)))) The resulting list is presented sequentially regrouping all closed unaligned parenthesis. The beautifier improves the presentation of the code and its readability: Code: Select all (pp pp-call) ;-> Code: Select all (define (pp-call expr colFrom extra pp-item)
Unlike the legacy pp, the modern pp has independent subroutines that can be called directly in the Script-Fu console. In the legacy version, those subroutines are embedded inside a main function. So the running context cannot be simulated. On the contrary, you can test each subroutine of the modern beautifier in the Script-Fu console to learn how pp works. To be continued... |
Author: | Wallace [ Sat Dec 04, 2021 5:32 pm ] |
Post subject: | Re: Gimp Lambda Lib version 1.0.0 for Script-Fu |
This is a lot to digest.
|
Author: | PixLab [ Sat Dec 04, 2021 10:38 pm ] |
Post subject: | Re: Gimp Lambda Lib version 1.0.0 for Script-Fu |
@AlSchemist, very cool avatar, it suits you perfectly A big for your in-deep explanations and doc, that's a lot of work, also we can feel a true passion behind your post, that's super |
Author: | AlSchemist [ Sun Dec 05, 2021 5:09 am ] |
Post subject: | Re: Gimp Lambda Lib version 1.0.0 for Script-Fu |
Wallace and PixLab. |
Page 1 of 1 | All times are UTC - 5 hours [ DST ] |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |