顯示具有 Console 標籤的文章。 顯示所有文章
顯示具有 Console 標籤的文章。 顯示所有文章

2008年6月13日

FORMAT與PRINTF的用法

REBOL 3.0提供format與printf函數,這兩個函數的參數完全一樣。Format函數會傳出格式化的字串,而printf則會印出格式化的字串。事實上,printf內部直接呼叫format。

>> source printf
printf: make function! [[
"Formatted print."
fmt "Format"
val "Value or block of values"
][
print format :fmt :val
]]
>>

下面是它們的使用範例:

>> format [ 20 #"/" -10 ] [ %my-rebol-file.r 31023 ]
== "my-rebol-file.r / 31023"

>> printf [ 20 #"/" -10 ] [ %my-rebol-file.r 31023 ]
my-rebol-file.r / 31023
>>

printf與format都需要兩個參數,第一個是格式規則,第二個是代換內容的區塊(block)。格式規則區塊內可以出現四種元素:
  • 正整數:指定內容長度,如果內容超過指定長度,則自動放寬。如果內容不滿指定長度,則「補上空白」,且內容「向左對齊」。
  • 負整數:指定內容長度,如果內容超過指定長度,則自動放寬。如果內容不滿指定長度,則「補上空白」,且內容「向右對齊」。
  • 字元:直接放置一個字元
  • 字串:直接放置此字串

使用format時,還可以透過/pad,指定補上某字元(或字串),而不是補上空白。例如:



>> format/pad [ 20 #"/" -10 ] [ %my-rebol-file.r 31023 ] #"."
== "my-rebol-file.r...../.....31023"

Bugfix: ls與format

我已經修正完畢LS函數和FORMAT函數的Bug,下面列出的是FORMAT的定義。至於LS的定義修改方式很簡單,把LENGTH?用LENGTH+?取代即可。當FORMAT遇到中文時,終於不會出問題了!

LENGTH+?不會計算出字串的字元長度,而是會計算出「相當於多少個half-width字元」的長度。記得把前一篇文章的Full-Wide-Width-charset定義也加進來,因為LENGTH+?會用到這個定義。

我會找一天把修正後的結果透過DevBase遞交給REBOL公司。

length+?: func [str [string!] /local ans ] [
ans: 0
foreach ch str [
either find Full-Wide-Width-charset ch [
ans: ans + 2
] [
ans: ans + 1
]
]
]

format: make function! [[
"Format a string according to the format dialect."
rules {A block in the format dialect. E.g. [10 -10 #"-" 4]}
values
/pad p
/local out val
][
p: any [p #" "]
unless block? :rules [rules: reduce [:rules]]
unless block? :values [values: reduce [:values]]
out: make string! ""
foreach rule rules [
if word? :rule [rule: get rule]
switch type?/word :rule [
integer! [
val: first+ values
val: form :val
pad: (abs rule) - length+? val
if negative? pad [ pad: 0 ]
either positive? rule [
append out :val
append/dup out p pad
] [
append/dup out p pad
append out :val
]
]
string! [append out rule]
char! [append out rule]
]
]
if not tail? values [append out values]
head out
]]

Format函數與寬字元

REBOL 3.0有提供一個函數名為format,用來進行輸出文字的格式化。許多函數都會用到format,例如what、ls。

format一遇到中文就會失靈,輸出格式亂掉,這是因為中文字是寬字元(Wide Character)。為了要修正format的此錯誤,我剛剛把Unicode Standard Annex #11 (East Asian Width) 所附的檔案整理過,找出其中屬於Full-Width與Wide的字元。接下來,就等我(或任何人)有空去修正format函數的定義了。
full-wide-width-charset: charset [
#"^(1100)" - #"^(1159)"
#"^(115F)"
#"^(2329)" - #"^(232A)"
#"^(2E80)" - #"^(2E99)"
#"^(2E9B)" - #"^(2EF3)"
#"^(2F00)" - #"^(2FD5)"
#"^(2FF0)" - #"^(2FFB)"
#"^(3000)" - #"^(303E)"
#"^(3041)" - #"^(3096)"
#"^(3099)" - #"^(30FF)"
#"^(3105)" - #"^(312D)"
#"^(3131)" - #"^(318E)"
#"^(3190)" - #"^(31B7)"
#"^(31C0)" - #"^(31E3)"
#"^(31F0)" - #"^(321E)"
#"^(3220)" - #"^(3243)"
#"^(3250)" - #"^(32FE)"
#"^(3300)" - #"^(33FF)"
#"^(3400)" - #"^(4DB5)"
#"^(4E00)" - #"^(9FC3)"
#"^(A000)" - #"^(A48C)"
#"^(A490)" - #"^(A4C6)"
#"^(AC00)" - #"^(D7A3)"
#"^(F900)" - #"^(FA2D)"
#"^(FA30)" - #"^(FA6A)"
#"^(FA70)" - #"^(FAD9)"
#"^(FE10)" - #"^(FE19)"
#"^(FE30)" - #"^(FE52)"
#"^(FE54)" - #"^(FE66)"
#"^(FE68)"
#"^(FF01)" - #"^(FF60)"
#"^(FFE0)" - #"^(FFE6)"
]

2008年5月30日

使用Console(二)


REBOL預計會有兩個Console,目前已完成的只有文字模式的DevStdIO,而圖形模式的DevConsole短時間之內是不會出現的,看樣子我們得使用DevStdIO好一段時間。「使用Console」 這篇文章有介紹一些用法。除此之外,如果你要使用「複製 / 貼上」功能的話,你必須啟用「快速編輯模式」和「插入模式」。作法如下:

  1. 用滑鼠右鍵點選REBOL Console視窗的標題列,叫出系統選單。
  2. 從選單中選取「內容」。你會看到附圖的視窗。
  3. 將兩個編輯選項(「快速編輯模式」和「插入模式」)都選取。然後按下「確定」。

只要有上面的設定,你就可以用滑鼠選取文字,用滑鼠右鍵複製反白區的文字到剪貼簿;在沒有反白區的情況下,按下滑鼠右鍵可以將剪貼簿的文字貼到Console上。


2008年4月6日

在Block內安插換行記號

如果你想在console將block列印出來,你可能會希望block的內容不要擠在一起。其實,你可以在block內插入一些換行的記號,你可以每個元素後面插入換行記號,或者每隔n個元素後面插入換行記號。請看下面的範例:

>> data: [ 1 "A" 2 "B" 3 "C" ]
== [ 1 "A" 2 "B" 3 "C" ]
>> new-line/skip data true 2

new-line是一個函數(不要和newline混淆了,newline是一個字元)。上面的指令意思是:在data內每隔2個元素插入一個換行記號。true表示「要加入換行記號」。執行完後,你會發現現在每兩個元素就會換行:

>> data
== [
1 "A"
2 "B"
3 "C"
]

你可以利用new-line?來判斷某block是否具有換行記號:

>> new-line? data
== true

你可以利用new-line將換行記號移除:

>> new-line/all data false
== [ 1 "A" 2 "B" 3 "C" ]

2008年3月13日

把REBOL當Shell用

所謂的Shell,就是圍繞在OS核心外圍的使用者介面,你可以參考「當劇本遇上殼」這篇文章對Shell的說明。

本文章介紹一些常用的函數與用法,讓你可以將REBOL當作Shell,用來對OS做一些基本的檔案操作。

【目前的目錄】

如果你想知道目前的工作目錄為何,你可以利用what-dir函數,如下:

>> what-dir
== %/c/Documents%20and%20Settings/Jerry%20Tsai/桌面/

「==」表示前面的函數有傳出值,其值為「%/c/Documents%20and%20Settings/Jerry%20Tsai/桌面/」。

你也可以用pwd取代what-dir,效果完全一樣:

>> pwd
== %/c/Documents%20and%20Settings/Jerry%20Tsai/桌面/

REBOL的檔案表示方式,依照下面的規則:

  1. 開頭使用「%」
  2. 目錄的分隔符號使用「/」
  3. 中間如果有特殊字元,則使用「%」後面接著兩個十六進位數字,代表該特殊字元的編碼。以這裡的例子來說,空白的值,在ASCII編碼是十六進位的20。所以寫成%20
  4. 如果是目錄,則最後是「/」
  5. 如果是絕對路徑,則開頭的「%」後面會接著一個「/」。如果是相對路徑,則開頭的「%」後面不會出現一個「/」。

【檔案的轉換】

如果你對於上面描述的檔案規則覺得不習慣,可以利用to-local-file,將what-dir傳出的檔案轉成作業系統慣用的格式,作法如下:

>> to-local-file what-dir
== "C:\Documents 20and 20Settings\Jerry Tsai\桌面\"

因為to-local-file的傳出值是字串不是檔案,所以前後加上雙引號「"」。有一個函數和to-local-file做的事剛好事相反的,可以把作業系統檔案字串,轉成REBOL檔案,此函數名為to-rebol-file,範例如下:

>> to-rebol-file "C:\Program Files\"
== %/C/Program%20Files/

【改變目錄】

你可以使用change-dir(或cd)函數,改變目前的目錄,例如:

>> cd %/c/
>> pwd
== %/c/

你也可以利用相對路徑的表示方式(也就是開頭的「%」後面不寫「/」),例如:

>> pwd
== %/c/
>> cd %Program%20Files
>> pwd
== %/C/Program%20Files/

有兩個特殊的相對路徑表示方式:「%.」表示目前的目錄,「%..」表示往上一個目錄。依此類推,「%../../表示往上兩層目錄」。下面是一個範例:

>> pwd
== %/C/Program%20Files/
>> cd %..
>> pwd
== %/c/

【製造目錄】

你可以使用make-dir(或mkdir)函數,製作新的目錄,例如:

>> mkdir %abc/

這表示在目前的目錄下,建立一個abc目錄。再看一個例子:

>> mkdir/deep %/c/rebol/my-script/

這裡的mkdir後面緊接著出現「/deep」,意思是:在建立此目錄的過程中,如果有其他的目錄尚未建立,就一併建立。所以如果%/c/rebol/尚未存在,就會先建立%/c/rebol/,然後再建立%/c/rebol/my-script/。

像這種函數後面加上的修飾,我們稱為refinement。

【列出檔案】

你可以使用list-dir(或ls)函數,將某目錄下的檔案列出來,例如:

>> ls %/c/

如果後面沒有寫目錄,預定就是目前的目錄(%.),例如:

>> ls

list-dir(與ls)可以使用下面的refinement:
/l:表示每個檔案用一行顯示
/f:只列出檔案,不列出目錄
/d:只列出目錄,不列出檔案
/r:列出此目錄以及底下所有子孫目錄內的檔案

例如:

>> ls/l/r

當同時使用兩個以上的refinement時,順序無所謂,所以「ls/l/r」和「ls/r/l」是完全一樣的效果。

【取得檔案資訊】

你可以利用「modified?」取得檔案最後修改時間,用「size?」取得檔案大小,用「dir?」得知否為目錄(而非檔案)。例如:

>> modified? %/c/rebol/core.exe
== 5-Mar-2008/6:31
>> size? %/c/rebol/core.exe
== 219136
>> dir? %core.exe
== false

2008年3月10日

使用Windows Console


REBOL預計會有兩個Console,一個是文字模式的DevStdIO,一個是圖形模式的DevConsole。目前已完成的只有DevStdIO。在Windows作業系統上,DevStdIO也就是Windows console。因此,你需要知道Windows Console的基本用法,整理如下:
  • 左右方向鍵:在目前的命令列左右移動編輯游標。
  • Ctrl+左右方向鍵:按住Ctrl鍵不放開,再按下向左方向鍵,或向右方向鍵,在目前的命令列左右移動編輯游標,一次移動一個word,而不是一個字元。
  • Home:將編輯游標移動到目前命令列的開頭。
  • End:將編輯游標移動到目前命令列的尾端。
  • 上下方向鍵:調出歷史命令(之前輸入過的命令)。
  • 插入(Ins)鍵:在字元插入與字元覆蓋(overwrite)模式之間切換。
  • 刪除(Del)鍵:刪除游標後的字元。
  • 倒退(Backspace)鍵:刪除游標前的字元。
  • F7:在文字視窗內,躍出一個「命令歷史清單視窗」(如上圖所示),然後使用上下鍵選取命令,最後按下Enter執行命令。除了F7,我發現F2、F3、F4、F9也有特殊功能。
  • Ctrl+空白鍵:中文輸入切換。
  • 用滑鼠拖檔案進來:可以輸入該檔案的全名。

可惜的是目前還不能使用tab,進行補完(completion)。

想要離開此console,使用q或quit函數即可,如下所示:

>> quit

2008年3月6日

用REBOL 3.0列出Unicode字元表

REBOL 3.0 支援Unicode,而且是連console都支援Unicode,你可以在console中輸入或輸出任何Unicode字元,只要你有適當的字型,就不會有問題。

下面是一個簡短的範例,將0x0000-0xFFFF的全部Unicode列出,程式很簡單,所以我就不說明了:

for i 0 4095 1 [ 
prin rejoin [ newline to-hex/size i 3 "0 " ]
for j 0 15 1 [
prin [ to-char to-hex/size i * 16 + j 4 " " ]
]
wait .01
]