Markapl - Mark up as Perl.

作者:   發佈於: ,更新於:   #perl #cpan

Markapl 是最近在嘗試著實做的一個實驗性模組,主要的想法是試試 Devel::Declare 的能力,有沒有辨法讓 Perl 能用很近似於 Markaby (Mark up as Ruby) 的語法來產生 HTML。

這是一段以 Markaby 產生 HTML 的程式 (Ruby 程式):


html do
  head do
    title "Hello World"
  end

  body do
    div :id => "hi" do
        "Hello World"
    end
  end
end

而我所設想的 Perl 版的語法應該要是:


html {
  head { title { "Hello World" } }

  body {
    div(id => "hi") {
      "Hello World"
    }
  }
}

而其實 Template::Delcare 已經做完一大部份了,比較殘念的是,由於其實做是以sub-routine prototype 為基本,使得以下這一段語法一直都沒有辨法做到:


div(id => "hi") {
  "Helo World"
}

而最近實驗的 Markapl 則以不同的原理實做出此語法了,甚至還有一些更方便的語法:


# 如 Markaby
div(id => "salute") { "Hello World" }

# 定義 id
h1("#how-are-yoyu") { "how-are-you" }

# 定義 class name
div(".description") { "Here's a description div..." }

# 同時定義 id 與 class name
p("#help.notice") { "Please watch your step" }

如範例,我使其能用與 CSS 語法來產生元素的 id 與 class 這兩個很常用的屬性。因為這兩項屬性必定經常要被指定的關係,總覺得應該要有極方便的方法來表示之使用 CSS 語法十分直覺,因為這樣在寫 CSS 的時候,用的也是同樣的表示法,十分容易互相對照。

Markapl 已經釋出到 CPAN 上,而其開發中的程式碼檔案庫則是放在 GitHub,請前往 這裡 。歡迎大家參考。

後話:

Template::Declare 的實做方法,是以 sub-routine prototype 為基本。如果定義一個 有 prototype 的 sub-routine 如下:


sub div(&) { ... }

那麼在呼叫此 sub-routine 時,必需要傳入一個程式碼參照(CODE reference)進去:


div(sub { ... })

但 Perl 允許在有定義 prototype 的狀態之下,可以完全省略小括號,以及 sub 這個字,所以也能夠寫成:


div { ... }

但殘念的是,省去 sub 而直接將 { ... } 這樣的區塊當做是程式碼參照的這個行為,只適用於第一個參數,其後的參數若要傳程式碼參照,都必需要明確寫出 sub 才行。

後話二:

Markapl 的實做方法是利用 Devel::Declare 模組來做程式碼植入(code injection),也就是說:


div(id => "foo") {
  ...
}

會先在編輯時期被轉譯成如下程式碼:


div id => "foo", sub {
   ...
};

連最後的分號都自動補上了。

後話三:

由於 obra 的要求,目前正在重新實做 Template::Declare 處理語法的部份,使其能用一樣的方法,支援 Markapl 的語法,同時也相容於現有的 Template::Delcare 語法。這部份的開發進度請 看此

後話四:

原本想依照慣例,在聖誕節釋出的,沒想到忙完 $work 之後一看日期已經超過了,真是令人 orz。