文字範本 |
|
巨集處理器的一個缺點就是它們沒有資料結構。Lua 舊版本中提供的一個範例 (lua-4.0.1/test/examples/www/db.lua) 說明了如何以組態檔中的資料結構值來填寫範本檔的良好技巧。
如果您唯一要做的只是將字串中的變數取代為表格中的值,請參閱 StringInterpolation。
以下這個模組 `Expand.lua` [5] 使用 Bentley's 巨集擴充演算法,以及範本字串中變數參考的 GNU make 語法。它還有一些從 Mark J. Dominus 的 `Text::Template.pm` 和 Sriram Srinivasan 在 O'Reilly 的《進階 Perl 程式設計》第 17 章中範本驅動的程式碼產生器 `Jeeves` 獲得的改良。
目標是有一個稱為 `expand` 的函式,這個函式會掃描範本字串的變數參考,並遞迴地取代它們,使用在列出的某個表格或函式中找到的值。
範本語法非常簡單。對表格成員和變數的參考表示為 `$ {varname` } 或 `$(varname)`,或如果是單字元變數名稱,則表示為 `$x`。
也可以在 `$ {expr` } 或 `$(expr)` 中包裹回傳字串的簡單 Lua 運算式。
Lua 陳述式可以在下述中的一個中進行包裝
$(do ... end)
$(if ... end)
$(for ... end)
$(while ... end)
$(repeat ... until ...)
Lua 程式碼可以設定一個名為 `OUT` 的變數,這個變數將取代範本字串中程式碼的位置。
Lua 運算式和陳述式由 `loadstring` 評估,而函式環境則設定為第一個表格。
以下範例說明如何使用 `expand`。請注意 `Expand.lua` 僅適用於 Lua 5.0。
expand = require'Expand' template = [[ you can access variables: $v or environment variables: ${HOME} you can call functions: ${table.concat(list, ', ')} this list has ${list.n} elements ${string.rep('=', list.n)} ${table.concat(list)} ${string.rep('=', list.n)} or evaluate code inline ${for i=1,list.n do OUT = table.concat{ OUT, ' list[', i, '] = ', list[i], '\n'} end} you can access global variables: This example is from ${mjd} at $(mjdweb) The Lord High Chamberlain has gotten ${L.n} things for me this year. ${do diff = L.n - 5 more = 'more' if diff == 0 then diff = 'no' elseif diff < 0 then diff = -diff more = 'fewer' end end} That is $(diff) $(more) than he gave me last year. values can have other variables: $(ref) ]] mjd = "Mark J. Dominus" mjdweb = 'http://perl.plover.com/' L = { 'A', 'B', 'C', 'D', n=4} local x = { v = 'this is v', list = L, ref = "$(mjd) made Text::Template.pm" } -- fill in the template with values in table x io.write(expand(template, x, _G, os.getenv))
以下是上面範例產生的輸出
you can access variables: this is v or environment variables: /home/pshook you can call functions: A, B, C, D this list has 4 elements ==== ABCD ==== or evaluate code inline list[1] = A list[2] = B list[3] = C list[4] = D you can access global variables: This example is from Mark J. Dominus at http://perl.plover.com/ The Lord High Chamberlain has gotten 4 things for me this year. That is 1 fewer than he gave me last year. values can have other variables: Mark J. Dominus made Text::Template.pm
false
,則會對範圍內的字串進行巨集擴充。如果 varname 是表格,那麼在對範圍內的字串進行巨集擴充時,會將其作為第一個要搜尋的表格。可用於範例產生的一項有用的功能為 $(foreach tabname ...)
語法。如果 tabname 是包含資料表格清單的表格,那麼巨集擴充會對 tabname
中的每個資料表格執行封閉字串,其結果將會串接在一起。
expand = require'Expand' fun_temp = [[ ============================================================================== $(foreach funcs ${type} x = ${name}( ${table.concat(args, ', ')} ) { $(code) $(when stuff x = $x; y = $y; ) reutrn $(exit); } ) ============================================================================== ]] fun_list = { exit = 1; stuff = false; funcs = { { type = 'int'; name = 'bill'; args = { 'a', 'b', 'c' }; code = 'something'; stuff = { x=99, y=34 }; }; { type = 'char *'; name = 'bert'; args = { 'one', 'two', 'three' }; code = 'something else'; exit = 2 }; }; } io.write(expand(fun_temp, fun_list, _G))
============================================================================== int x = bill( a, b, c ) { something x = 99; y = 34; reutrn 1; } char * x = bert( one, two, three ) { something else reutrn 2; } ==============================================================================
此網頁的第一個版本為 OldTextTemplate。