總結:Script-fu 與 Python-fu 架構一樣,語法有很大的差別
- Python-fu 有物件導向的呼叫方式語法。
- 同樣功能的函式, Python-fu 有物件導向的呼叫方式。
- pdb.gimp_image_new(width, height, RGB)相當於 gimp.Image(width, height, RGB)
- 減號 - 要改成底線 _ ,gimp-image-new 要改成 pdb.gimp_image_new
- Python 的敘述 statement 通常以行為單位,Scheme 則用括號()括住。
- Python 的敘述 statement 可用分號 ; 來區隔,但「PEP 8 -- Style Guide for Python Code」 建議用換行來區隔不同的敘述。
- Python 的註解是井號 # 開頭,Scheme 的註解是分號 ; 開頭。
「轉碼程式」的 Python 程式碼 scm_to_py_.py
- 經過一番摸索,可以將「轉碼的流程」寫成 Python 程式。
- 這個「轉碼程式」無法轉換加減乘除四則運算。
- 這個「轉碼程式」無法完全正確轉換,最終還是需要一些手工的校正。
- 這個「轉碼程式」使用正規表示式,將 Scheme code 轉為 Python code
- tmp.py 表示 Python code 的檔案
- tmp.scm 表示 Scheme code 的檔案
- 將所有的程式碼儲存在 scm_to_py_.py 的檔案內
- 將 scm_to_py_.py 檔案權限設為可執行
- 準備好 tmp.scm
- 終端機下,鍵入 ./scm_to_py_.py
- 執行後,就會得到 tmp.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re
f_py = open('./tmp.py', 'w')
f_scm = open('./tmp.scm', 'r')
# 請注意 Python 的縮排規則,否則可能會出錯
# 還要注意 Python 各種的逃脫字符(escape characters)
# 所有的「正規表示式」都包裹在這個 for 迴圈之內
for line in f_scm:
# 取代註解符號
line = re.sub('\;', '#', line)
# 刪掉(define
line = re.sub('\(define ', '', line)
# 函數參數值的間隔符號,空白改為逗號
p_with_pdb_if = re.compile('pdb')
if p_with_pdb_if:
line = re.sub(' ', ', ', line)
# car 是取出函數的回傳值串列的"頭"(第一個元素)
# 等號 = 表示參數值的指派,或接收函數的回傳值
# 多數的函數回傳值只有一個元素(或一個物件)
# 因此,這樣的修改是可行的
line = re.sub('\, \(car\, \(', ' = ', line)
line = re.sub('\-1', 'neg1', line)
# Scheme 與 Python 函數命名規則略微不同
# Scheme 函數名稱以減號 - 串接
# 改為以底線 _ 串接
line = re.sub('\-', '_', line)
line = re.sub('gimp_', 'pdb.gimp_', line)
line = re.sub('script_fu_', 'pdb.script_fu_', line)
line = re.sub('plug_in_', 'pdb.plug_in_', line)
line = re.sub('RUN_NONINTERACTIVE, ', '', line)
# Python-Fu 預設就是 RUN_NONINTERACTIVE
# 因此,刪掉 RUN_NONINTERACTIVE,
# Scheme 與 Python 括號 () 的使用方式有很大的差異
line = re.sub('\)', '', line)
line = re.sub('\(', '', line)
#
p = re.compile('pdb.[a-z|_]*\, ')
if re.search(p, line):
m = re.search(p, line)
find_p = m.group(0)
new_p = re.sub(', ', '(', find_p)
line = p.sub(new_p, line)
# 過濾出 pdb.開頭 \n 結尾 的字串
p = re.compile('pdb.[a-z|A-Z|0-9|\'|\"|\(||_|\s|\,|\.|+|-|\*|/]*\n')
if re.search(p, line):
m = re.search(p, line)
find_p = m.group(0)
new_p = re.sub('\n', ')\n', find_p)
line = p.sub(new_p, line)
# 直接用取代的方式,修正括號 () 的錯誤
line = re.sub('gimp_context_push', 'gimp_context_push(', line)
line = re.sub('gimp_displays_flush', 'gimp_displays_flush(', line)
line = re.sub('gimp_context_pop', 'gimp_context_pop(', line)
# 讓等號 = 出現在變數值指派的地方
p_with_pdb_if = re.compile('pdb|if')
p = re.compile('[0-9|TRUE|FALSE]\n')
if not re.search(p_with_pdb_if, line):
if re.search(p, line):
m = re.search(p, line)
find_p = m.group(0)
line = re.sub('\, ', ' = ', line)
p = re.compile('set\!\, [a-z|_]*\, ')
if re.search(p, line):
m = re.search(p, line)
find_p = m.group(0)
new_p = re.sub(', ', ' = ', find_p)
line = p.sub(new_p, line)
line = re.sub('set\!\, ', '', line)
line = re.sub('set\! \= ', '', line)
p = re.compile('^if')
if re.search(p, line):
m = re.search(p, line)
find_p = m.group(0)
line = re.sub('\, TRUE', ':', line)
line = re.sub('\, =\, ', ' ', line)
line = re.sub('neg1', '-1', line)
#也可使用 print 直接將結果印在標準輸出
#print line,
f_py.write(line)
#for 迴圈結束,重要的敘述,都在這個 for 迴圈之內
f_scm.close()
f_py.close()