[Part I. GIMP基礎功]

[Part II. 一種效果的誕生]
[Part III. Script-Fu的秘密]



21.9 Python 轉為 Scheme 的「轉碼程式」

可以先寫好 Python-Fu ,再將它轉為 Script-Fu
  • 下面這四篇文章,提供了扎實的 GIMP 視窗介面的練習。
  • 文章的後面,列出了,等價的 Python-Fu 程式碼。
  • 對大多數人而言,Python 是比 Scheme 容易。
  • 讀者可利用,下面的「轉碼程式」,將 Python 轉為 Scheme 。


「轉碼程式」的 Python 程式碼 scm_to_py_.py
  • 經過一番摸索,可以將「轉碼的流程」寫成 Python 程式。
  • 這個「轉碼程式」無法轉換加減乘除四則運算。
  • 這個「轉碼程式」無法完全正確轉換,最終還是需要一些手工的校正
  • 這個「轉碼程式」使用正規表示式,將 Python code 轉為 Scheme code
    • tmp.scm 表示 Scheme code 的檔案
    • tmp.py 表示 Python code 的檔案
    • 將所有的程式碼儲存在 py_to_scm_.py 的檔案內
    • 將 py_to_scm_.py 檔案權限設為可執行
    • 準備好 tmp.py
    • 終端機下,鍵入 ./py_to_scm_.py
    • 執行後,就會得到 tmp.scm

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import re
f_py = open('./tmp.scm', 'w')
f_scm = open('./tmp.py', 'r')

# 請注意 Python 的縮排規則,否則可能會出錯
# 還要注意 Python 各種的逃脫字符(escape characters)
# 所有的「正規表示式」都包裹在這個 for 迴圈之內
for line in f_scm:
  # 取代註解符號
  line = re.sub('\#', ';', line)

  p_with_pdb = re.compile('pdb')
  p = re.compile('pdb.[a-z|A-Z|0-9|\'|\"|\(||_|\s|\,|\.|+|-|\*|/]*\)\n')
  if re.search(p_with_pdb, line):
    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)

  if re.search(p_with_pdb, line):
    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)

  # 開頭加上(define
  p_with_eq_sign = re.compile(' = ')
  if re.search(p_with_eq_sign, line):
    line = "(define " + line

  # 注意 line 原本就附帶有換行符號 \n
  # 因此不能 line = line + ")"
  # 這樣會把右括號 ) 推擠到下一行的開頭
  p_with_eq_pdb = re.compile(' \= pdb.')
  if re.search(p_with_eq_pdb, line):
    line = re.sub(' \= pdb.', ' (car ', line)
    line = re.sub('\n', '', line) + ")\n"

  p_with_eq = re.compile(' = ')
  if re.search(p_with_eq, line):
    line = re.sub(' = ', ' ', line)
    line = re.sub('\n', '', line) + ")\n"

  p_with_plug = re.compile('plug')
  p = re.compile('plug_in_[a-z|_]* ')
  if re.search(p_with_plug, line):
    if re.search(p, line):
      m = re.search(p, line)
      find_p = m.group(0)
      print find_p,
      new_p = find_p + "RUN-NONINTERACTIVE "
      line = p.sub(new_p, line)

  # 直接用取代的方式,修正括號 () 的錯誤
  line = re.sub('pdb.gimp_context_push\(\)', '(gimp_context_push)', line)
  line = re.sub('pdb.gimp_displays_flush\(\)', '(gimp_displays_flush)', line)
  line = re.sub('pdb.gimp_context_pop\(\)', '(gimp_context_pop)', line)
  # 修正括號 ( 的錯誤
  line = re.sub('pdb.', '(', line)
  # 修正括號 - 的錯誤
  line = re.sub('_', '-', line)
  #也可使用 print 直接將結果印在標準輸出
  #print line,
  f_py.write(line)
  #for 迴圈結束,重要的敘述,都在這個 for 迴圈之內

f_scm.close()
f_py.close()