Scheme語言的基本語法

 

        本文主要參考Gimp User Manual Chapter 43,Mike Terry’s Black School Of Script-Fu,Author Mike Terry。

 

一、          前言:

關於Script-Fu

使用GIMP的視窗界面來處理影像的任何動作都有相對應的函數(function or procedure ),執行[GIMP] ->Xtns -> DB Browser產生一DB Browser對話盒,這對話盒提供了GIMP所有函數的輸入變數的資料形態、輸出變數的資料形態、該函數的功能…..等相關資訊。如:gimp-edit-copy、gimp-edit-paste、gimp-edit-cut對應的便是最常使用的影像複製、影像貼上、影像剪下等動作。

Script-Fu所使用的語言是Scheme一種類似Lisp的語言。每個在GIMP程式主畫面選單的Script-Fu,或影像的浮動選單的Script-Fu都可在DB Browser對話盒找得到對應的函數。[GIMP] -> Xtns -> Script-Fu -> Web Page Themes -> Gimp.Org -> Big Header這動作所對應的函數為script-fu-big-header-gimp-org。

GIMP的Script-Fu就好像UNIX的Shell Script,透過Script-Fu的Scheme語言你可以組合GIMP處理影像的動作達到你想要的功能,讓這些處理影像的動作自動化。

學習Script-Fu的最好方法就是閱讀gimp/scripts目錄下的*.scm檔。

 


 

二、Script-Fu Console:

Script-Fu Console對話盒

 

執行[GIMP] -> Xtrns -> Script-Fu -> Console會出現Script-Fu Console對話盒。你可以在Current Command文字輸入框內輸入你要執行的命令。

    Scheme語言並沒有很好的除錯工具,造成了後來有人發展Perl、TCL、Python來控制Gimp的函式。

    你可以在Script-Fu Console對話盒內練習Scheme的語法。

 

在Current Command文字輸入框內輸入 (* 3 5)

得到 15

輸入 (* 6 7)

得到 13

 

輸入 ((- (* 3 5) (+ 6 7))

得到 2

(let* ((x 3) (y 5))(* x y))

得到 15

 

本式子可看成:

(let* (

(x 3)

(y 5)

)

(* x y)

)

輸出 (* x y)

得到 錯誤訊息

 

離開let* ()的括號外,原設定的區域變數x、y就變成沒有宣告。故有錯誤訊息

鍵入(script-fu-slime-logo "Gimp" 72 "-*-ComicsCarToon-*-r-*-*-24-*-*-*-p-*-*-*")

相當於執行[image] -> Script-Fu -> Logo -> Slime,使用預設的參數設定。

得到

鍵入(script-fu-gradient-example 400 30 )

相當於執行[image] -> Script-Fu ->

使用預設的參數設定。

得到左圖。

 

三、Scheme的語法:

由前一節的練習是否有發現Scheme語法的規則。

完整的敘述

(let* (

(x 3)

(y 5)

)

(* x y)

)

l          括號()特別多

l          每一個完整的敘述(statement)都要用括號()括起來。

l          括號()內的第一項一定是函數名稱或運算子。

註解

  ;

l          分號;為註解符號。

  運算式

(* 3 5)

 

l          運算式為前序(prefix)運算式,

l          (* 3 5)相當於3*5

l          3*5是中序(infix)運算式

l          若你不習慣前序表示式,你可以將運算子視為函數。

l          * 視為函數,3、5視為參數。

l          在中序運算式3*5, 運算子*與運算元3、5中間不會有空白(space);但前序運算式(* 3 5),*與3中間一定有空白。

 運算式

 (* 6 7)

l          (* 6 7) 相當於6*7

 運算式

 ((- (* 3 5) (+ 6 7))

l          ((- (* 3 5) (+ 6 7)) 相當於3*5-6*7

區域變數

(let* (

(x 3)

(y 5)

)

(* x y)

)

l          使用 let* ()來宣告與使用區域變數

l          語法:(let* (variables) expressions)

l          左式:設定 x=3、y=5,而後執行運算x*y

l          離開let* ()的括號外,原設定的區域變數就變成沒有宣告。

 

  函數定義與宣告

(define (Multiply X Y)

        (* X Y)

  )

 

 函數使用

 (Multiply 3 5) 得到15

l          使用define來定義函數

l          語法:(define (name param-list) expressions),name表函數名稱、param-list表輸入函數的參數。

l          左式:設定一個乘法函數

l          參數型態:參數不用設定參數型態,幾乎所有script語言都是如此。

l          回傳值:函數內的最後一個敘述為回傳值。

l          (Multiply (Multiply 3 5) 2)會得到多少?

 

  串列

   ‘(1 6 8)

l          使用撇號 ‘(apostrophe)來定義串列

l          語法:‘(a b c)

l          撇號 ‘ 指示在括號()內的是串列而不是一個單值

l          串列(list)相當於陣列,儲存多個單值。

(let* (x 5) x)

l          在Console對話盒鍵入左式得到5

(let* (x ‘(1 6 8)) x)

l          在Console對話盒鍵入左式得到(1 6 8)

(let* (x ‘(“Gimp” 1.2 “v”))

l          串列的原素可以混合各種資料形態

 

串接

(cons “Gimp” (1 6 8) )

l          使用cons來連結串列產生新的串列

l          左式:輸出結果(“Gimp” 1 6 8)

 

抓取串列內元素

(car ‘(“Gimp” 2 3 4))

l          car抓取串列內第一個元素

l          左式:輸出結果”Gimp”

 

(cdr ‘(“Gimp” 1 6 8))

l          cdr抓取串列內除第一個元素外的其餘元素。

l          左式:輸出結果(2 3 4)

 

(car (cdr ‘(“Gimp” 1 6 8)))

l          car(cdr())抓取第二個元素

l          左式:輸出結果2