INSTRUCTIONS:
Download REBOL/View from http://www.rebol.com/download-view.html (.6 MB)
Run REBOL, click the "Console" icon, and paste in any of these examples.
*** THAT'S EVERYTHING YOU NEED TO GET STARTED WITH THIS TEXT ***
To make REBOL automatically open to the console every time it starts,
click the "User" link, and then uncheck "Open desktop at startup".
To use REBOL's built in text editor, type "editor none" at the console.
Press the F5 key while in the editor to save and run any edited code.
Be sure to type the header "REBOL []" at the top of any edited scripts.
If you install REBOL, any file saved with a ".r" extension will run
when its file icon is clicked (.r code files run just like .exe files).
Type "desktop" to reopen REBOL's default graphic desktop. See thousands
of additional code examples by clicking the "REBOL" and "Public" icons.
See http://re-bol.com for a complete REBOL tutorial with line-by-line
explanations of all the code in these examples. See the last example
in this document for a useful quick reference manual.
Metapad (http://liquidninja.com/metapad/download.html) is a great editor
for REBOL. Click Options -> Settings -> Primary External Viewer, and set
your REBOL path (usually C:\Program Files\rebol\view\rebol.exe).
DEMO APPLICATION (10 apps in 2890 characters):
REBOL[title:"Demo"]p: :append kk: :pick r: :random y: :layout q: 'image
z: :if gg: :to-image v: :length? g: :view k: :center-face ts: :to-string
tu: :to-url sh: :show al: :alert rr: :request-date co: :copy g y[style h
btn 150 h"Paint"[g/new k y[s: area black 650x350 feel[engage: func[f a e][
z a = 'over[p pk: s/effect/draw e/offset sh s]z a = 'up[p pk 'line]]]
effect[draw[line]]b: btn"Save"[save/png %a.png gg s al"Saved 'a.png'"]btn
"Clear"[s/effect/draw: co[line]sh s]]]h"Game"[u: :reduce x: does[al join{
SCORE: }[v b]unview]s: gg y/tight[btn red 10x10]o: gg y/tight[btn tan
10x10]d: 0x10 w: 0 r/seed now b: u[q o(((r 19x19)* 10)+ 50x50)q s(((r
19x19)* 10)+ 50x50)]g/new k y/tight[c: area 305x305 effect[draw b]rate 15
feel[engage: func[f a e][z a = 'key[d: select u['up 0x-10 'down 0x10 'left
-10x0 'right 10x0]e/key]z a = 'time[z any[b/6/1 < 0 b/6/2 < 0 b/6/1 > 290
b/6/2 > 290][x]z find(at b 7)b/6[x]z within? b/6 b/3 10x10[p b u[q s(last
b)]w: 1 b/3:((r 29x29)* 10)]n: co/part b 5 p n(b/6 + d)for i 7(v b)1[
either(type?(kk b i)= pair!)[p n kk b(i - 3)][p n kk b i]]z w = 1[clear(
back tail n)p n(last b)w: 0]b: co n sh c]]]do[focus c]]]h"Puzzle"[al{
Arrange tiles alphabetically:}g/new k y[origin 0x0 space 0x0 across style
p button 60x60[z not find[0x60 60x0 0x-60 -60x0]face/offset - x/offset[
exit]tp: face/offset face/offset: x/offset x/offset: tp]p"O"p"N"p"M"p"L"
return p"K"p"J"p"I"p"H"return p"G"p"F"p"E"p"D"return p"C"p"B"p"A"x: p
white edge[size: 0]]]h"Calendar"[do bx:[z not(exists? %s)[write %s ""]rq:
rr g/new k y[h5 ts rq aa: area ts select to-block(find/last(to-block read
%s)rq)rq btn"Save"[write/append %s rejoin[rq" {"aa/text"} "]unview do bx]]
]]h"Video"[wl: tu request-text/title/default"URL:"join"http://tinyurl.com"
"/m54ltm"g/new k y[image load wl 640x480 rate 0 feel[engage: func[f a e][
z a = 'time[f/image: load wl show f]]]]]h"IPs"[parse read tu join"http://"
"guitarz.org/ip.cgi"[thru
copy my to]i: last parse my none
al ts rejoin["WAN: "i" -- LAN: "read join dns:// read dns://]]h"Email"[
g/new k y[mp: field"pop://user:pass@site.com"btn"Read"[ma: co[]foreach i
read tu mp/text[p ma join i"^/^/^/^/^/^/"editor ma]]]]h"Days"[g/new k y[
btn"Start"[sd: rr]btn"End"[ed: rr db/text: ts(ed - sd)show db]text{Days
Between:}db: field]]h"Sounds"[ps: func[sl][wait 0 rg: load sl wf: 1 sp:
open sound:// insert sp rg wait sp close sp wf: 0]wf: 0 change-dir
%/c/Windows/media do wl:[wv: co[]foreach i read %.[z %.wav = suffix? i[p
wv i]]]g/new k y[ft: text-list data wv[z wf <> 1[z error? try[ps value][al
"Error"close sp wf: 0]]]btn"Dir"[change-dir request-dir do wl ft/data: wv
sh ft]]]h{FTP}[g/new k y[px: field"ftp://user:pass@site.com/folder/"[
either dir? tu va: value[f/data: sort read tu va sh f][editor tu va]]f:
text-list[editor tu join px/text value]btn"?"[al{Type a URL path to browse
(nonexistent files are created). Click files to edit.}]]]]
LANGUAGE BASICS:
print "Hello world"
alert "Alert is a FUNCTION. This text is its PARAMETER (or ARGUMENT)."
alert ("Parentheses can enclose parameters, but they aren't required.")
editor "This text is a parameter of the 'editor' function ... edit it."
browse http://rebol.com ; this function is 'browse' the parameter is a URL
request "Functions perform ACTIONS. Parameters are DATA. Make sense?"
; this is a comment
{
This is a multi line comment.
Comments don't do anything in a program.
They just remind the programmer what's happening in the code.
}
request-text ; These requester functions don't require any parameters,
request-date ; but like most functions, they RETURN a useful value.
request-color
request-file
request-dir
request-pass
alert request-text ; In all these examples, the 1st function uses a value
editor request-date ; RETURNED by the 2nd function, as its parameter. To
print request-file ; complete the 1st function, user response is needed.
editor request request-text ; Here, return values are CASCADED.
alert "First function on this line" alert "Second function, same line"
alert "No" alert "line" alert "endings" alert "are" alert "required"
alert "functions are" editor "automatically grouped with their parameters"
request-text/default "Text" ; many functions have "refinements" (options)
request-text/title "The /title refinement sets this header text"
request-text/title/default "Name:" "John Smith" ; 2 options together
request-text/title/offset "/offset repositions the requester" 10x100
request-pass/offset/title 10x100 "title" alert "Processing" ; 2 functions
request-file/file %temp.txt ; default file name
request-file/filter ["*.txt" "*.r"] ; only show .txt and .r files
request-file/only ; limit selection to a single file
request-file/save ; save dialog (instead of open dialog)
request-file/save/file/filter %temp.txt ["*.txt" "*.r"]
print 10 + 12 / 2 ; 22 / 2 = 11 Math is ALWAYS evaluated left to
print (10 + 12) / 2 ; 22 / 2 = 11 right. The only exception:
print 10 + (12 / 2) ; 10 + 6 = 16 Parentheses are evaluated first.
print "This is a string of text."
print {
Curly braces are used for
multi line text strings
(instead of quotes).
}
alert {To use "quotes" in a text string, put them inside curly braces.}
alert "You can use {curly braces} inside quotes."
alert "'Single quotes' can go inside double quotes..."
alert {'...or inside curly braces'}
alert {"ANY quote symbol" {can actually be used within} 'curly braces'}
alert "In many cases" alert {curly braces and quotes are interchangable.}
rejoin ["Hello " "World"] ; "rejoin" CONCATENATES (joins together) values
rejoin [{Concatenate } {as } {many items } {as } {you } {want.}]
rejoin [request-date { } request-color { } now/time { } $29.99]
alert rejoin ["You chose: " request "Choose one:"] ; CASCADE return values
join {"Join" only concatenates TWO items } {("rejoin" is more powerful).}
print rejoin ["This text is followed by a carriage return." newline]
print "This text is also followed by a carriage return.^/"
prin {'Prin' } prin {doesn't } prin {print } print {a carriage return.}
prin newpage ; clear console screen
print read http://rebol.com ; "read" retrieves the data from many sources
editor http://rebol.com ; the built in editor can also read many sources
print read %./ ; the % symbol is used for local files and folders
editor %./
write %temp.txt "test" ; write takes TWO parameters (file name and data)
editor %temp.txt
editor request-file/only ; "only" refinement limits choice to 1 file
write clipboard:// (read http://rebol.com) ; 2nd parameter in parentheses
editor clipboard://
print read dns://msn.com ; REBOL can read many built in protocols
print read nntp://public.teranews.com
write/binary %/c/bay.jpg (read/binary http://rebol.com/view/bay.jpg)
write/binary %tada.wav (read/binary %/c/windows/media/tada.wav)
write/binary %temp.dat (compress read http://rebol.com) ; COMPRESS DATA
print decompress read/binary %temp.dat ; DECOMPRESS DATA
print read ftp://user:pass@website.com/name.txt ; user/pass required
write ftp://user:pass@website.com/name.txt "text" ; user/pass required
editor ftp://user:pass@website.com/name.txt ; can save changes to server!
editor pop://user:pass@website.com ; read all emails in this account
send user@website.com "Hello" ; send email
send user@website.com (read %file.txt) ; email the text from this file
send/attach user@website.com "My photos" [%pic1.jpg %pic2.jpg pic3.jpg]
call/show "notepad.exe c:\config.sys" ; run OS shell command
view layout [image %pic1.jpg] ; view an image
view layout [image request-file/only] ; view a user selected image
insert s: open sound:// load request-file/only wait s close s ; play sound
insert s: open sound:// load %/c/windows/media/tada.wav wait s close s
rename %temp.txt %temp2.txt ; change file name
write %temp.txt read %temp2.txt ; copy file
write/append %temp2.txt "" ; create file (or if it exists, do nothing)
delete %temp2.txt
change-dir %../
what-dir
list-dir
make-dir %./temp
print read %./
x: 10 ; The COLON symbol assigns a value to a word label (a "variable")
print x
x: x + 1 ; increment variable by 1 (add 1 to the current value of x)
print x
y: "hello" z: " world"
print rejoin [y z]
probe rejoin [y z] ; PROBE shows RAW DATA (PRINT formats nice output)
print join y z
person: "john" ; variables (word labels) ARE ** NOT ** CASE SENSITIVE
print person print PERSON print PeRsOn
value1: value2: value3: "yes " ; here, all 3 variables are set to "yes "
print rejoin [value1 value2 value3]
name: ask "Enter your name: " ; "ask" gets text input from the user
print rejoin ["Hello " name]
filename: request-file/only
alert rejoin ["You chose " filename]
osfile: to-local-file filename ; REBOL uses its own multiplatform syntax
to-rebol-file osfile ; Convert from native OS file notation back to REBOL
the-url: http://website.com/subfolder
split-path the-url ; "split-path" breaks any file or URL into 2 parts
some-text: {
This is a multi line string of text.
Strings are a native data type, delineated by
quotes or curly braces, which enclose text.
REBOL has MANY other built in data types, all
delineated by various characters and text formats.
The "type" function returns a value's data type.
Below are just a few more native data types:
}
type? some-text
an-integer: 3874904 type? an-integer
a-decimal: 7348.39 type? a-decimal
web-site: http://musiclessonz.com type? web-site
email-address: user@website.com type? email-address
the-file: %/c/myfile.txt type? the-file
money-amount: $343.56 type? money-amount
color-tuple: 123.54.212 type? color-tuple
a-character: #"z" type? a-character
a-word: 'asdf type? a-word
html-tag: type? html-tag
binary-info: #{ddeedd} type? binary-info
image: load http://rebol.com/view/bay.jpg type? image
a-sound: load %/c/windows/media/tada.wav a-sound/type
to-decimal an-integer ; Convert values TO different types ("cast")
to-string web-site ; now the web site URL is surrounded by quotes
form web-site ; "form" also converts various values to string
form $29.99
alert form $29.99 ; the alert function REQUIRES a string parameter
alert $29.99 ; (this throws an error)
5 + 6 ; you can perform math operations with integers
"5" + "6" ; (error) you can't perform math with strings
(to-integer "5") + (to-integer "6") ; this eliminates the math problem
to-pair [12 43] ; creates a coordinate pair
as-pair 12 43 ; a better way to create a coordinate pair
to-binary 123.54.212 ; convert a REBOL color value to hex color value
to-binary request-color ; convert the color chosen by the user, to hex
to-tuple #{00CD00} ; convert a hex color value to REBOL color value
form to-tuple #{00CD00} ; covert the hex color value to a string
write/binary %floorplan8.pdf debase read clipboard:// ; email attachment
6:30am + 00:37:19 ; REBOL computes values appropriately for type
now
now + 0:0:59
now - 10
23x54 + 19x31
22x66 * 2
22x66 * 2x3
192.168.1.1 + 0.0.0.37
11.22.33.44 * 9 ; note that each IP segment value is limited to 255
0.250.0 / 2 ; an easy way to adjust color values
$29.99 * 5
x: 12 y: 33 q: 18 p: 7
(as-pair x y) + (as-pair q p) ; very common in graphics apps using coords
remove form to-money 1 / 233
remove/part form to-time (1 / 233) 6
random/seed now/time ; always use this line to get real random values
random 50 ; a random number between 0 and 50
random 50x100 ; left side is limited to 50, right limited to 100
random 222.222.222 ; each segment is limited to #s between 0 and 222
random $500
random "asdfqwerty" ; a random mix of the given characters
FLOW CONTROL (Conditional Evaluations and Loops):
if now/time > 12:00 [alert "It's after noon."] ; if (true) [do this]
if not now/time > 12:00 [alert "It's morning."]
unless now/time => 12:00 [alert "It's morning."]
if not now/time = 12:00 [alert "It's not noon."]
if now/time <> 12:00 [alert "It's not noon."]
if error? try [0 / 0] [alert "Divide by 0 error"] ; if error [do this]
if attempt [1 / 1] [alert "Successful"] ; if no error [do this]
attempt [0 / 0] ; ignore error
either now/time > 8:00am [ ; same as if/else
alert "It's time to get up!"
][
alert "You can keep on sleeping."
]
favorite-day: request-text/title "What's your favorite day of the week?"
switch/default favorite-day [
"Monday" [alert "Monday is the worst! The work week begins..."]
"Tuesday" [alert "Tuesdays and Thursdays are both ok, I guess..."]
"Wednesday" [alert "The hump day - the week is halfway over!"]
"Thursday" [alert "Tuesdays and Thursdays are both ok, I guess..."]
"Friday" [alert "Yay! TGIF!"]
"Saturday" [alert "Of course, the weekend!"]
"Sunday" [alert "Of course, the weekend!"]
] [alert "You didn't type in the name of a day!"]
name: "john"
case [
find name "a" [print {Your name contains the letter "a"}]
find name "e" [print {Your name contains the letter "e"}]
find name "i" [print {Your name contains the letter "i"}]
find name "o" [print {Your name contains the letter "o"}]
find name "u" [print {Your name contains the letter "u"}]
true [print {Your name doesn't contain any vowels!}]
]
name: "brian"
found: false
case/all [ ; /all evaluates ALL conditions, without breaking
find name "a" [print {Your name contains the letter "a"} found: true]
find name "e" [print {Your name contains the letter "e"} found: true]
find name "i" [print {Your name contains the letter "i"} found: true]
find name "o" [print {Your name contains the letter "o"} found: true]
find name "u" [print {Your name contains the letter "u"} found: true]
found = false [print {Your name doesn't contain any vowels!}]
]
value1: true value2: false
if ((value1 = true) and (value2 = true)) [
print "both true"
]
if ((value1 = true) or (value2 = true)) [
print "either one OR the other is true"
]
alarm-time: now/time + :00:10
forever [if now/time = alarm-time [alert "10 seconds have passed" break]]
while [now/date < 21-dec-2012] [print "Press [ESC] to quit"]
until [now/date >= 21-dec-2012] [print "It's now December 21, 2012"]
loop 50 [print "REBOL is great!"]
count: 0
loop 50 [
count: count + 1
print rejoin ["This is loop #: " count]
]
repeat count 50 [print rejoin ["This is loop #: " count]]
for counter 1 10 1 [print counter]
for counter 10 1 -1 [print counter]
for counter 10 100 10 [print counter]
for counter 1 5 .5 [print counter]
for timer 8:00 9:00 0:05 [print timer]
for dimes $0.00 $1.00 $0.10 [print dimes]
for date 1-dec-2005 25-jan-2006 8 [print date]
for alphabet #"a" #"z" 1 [prin alphabet]
folder: read %.
foreach file folder [print file]
SERIES ("blocks", data lists):
new-block: copy [] ; a new, empty block
some-names: ["John" "Bill" "Tom" "Mike"] ; a list of text strings
more-names: copy some-names ; a copy of the above list
probe more-names
same? more-names some-names ; NOT the exact same list, but a copy
same-names: some-names ; THESE labels now refer to the EXACT SAME list
probe same-names
same? same-names some-names ; change some-names and same-names CHANGES TOO
sortednames: sort copy some-names ; "copy" keeps some-names from changing
sortednames: sort some-names ; here, the some-names block has been sorted
print first sortednames ; here are 3 different ways to pick the 1st item:
print sortednames/1
print pick sortednames 1
print second sortednames ; 3 different ways to pick the 2nd item:
print sortednames/2
print pick sortednames 2
find some-names "John"
first find some-names "John"
find/last some-names "John"
select some-names "John" ; use series like dictionaries
reverse sortednames
length? sortednames
head sortednames
next sortednames
back sortednames
last sortednames
tail sortednames
at sortednames 2
skip sortednames 1
extract sortednames 3 ; every third item
index? sortednames
insert (at sortednames 3) "Lee"
append sortednames "George"
remove sortednames
remove find sortednames "Mike"
change sortednames "Phil"
change third sortednames "Phil"
poke sortednames 3 "Phil"
copy/part sortednames 2
replace/all sortednames "Lee" "Al"
probe form sortednames
probe mold sortednames
join some-names sortednames
intersect sortednames more-names
difference sortednames more-names
exclude sortednames more-names
union sortednames more-names
unique sortednames
clear sortednames
empty? sortednames
probe same-names
probe more-names
index-num: length? more-names
print pick more-names index-num
print pick more-names (index-num - 1)
print pick more-names (random length? more-names)
index-num: ((index? (find more-names "Tom")) - 1)
print pick more-names index-num ; 4 ways to pick items at a variable index
print more-names/:index-num
print compose [more-names/(index-num)]
print reduce [more-names/(index-num)]
; "READ" reads data byte-for-byte from file, "LOAD" performs a CONVERSION
; "WRITE" writes series byte-for-byte to file, "SAVE" performs CONVERSION
save %names.txt more-names ; series data saved to a text file
loaded-names: load %names.txt ; use "load" to read it into a variable
write %names2.txt mold more-names ; series saved but WITH SQUARE BRACKETS
loaded-names2: load %names2.txt ; "load" also correctly loads that file
read-names: to-block read %names.txt ; "read" requires "to-block" convert
read-names2: to-block read %names2.txt ; block within a block
probe read-names2 ; [["John" "Phil" "Tom" "Mike"]]
first read-names2 ; ["John" "Phil" "Tom" "Mike"]
write/binary %compressed.dat compress mold more-names ; compress and save
probe load decompress read/binary %compressed.dat ; read and decompress
save %compressed.dat compress mold more-names ; another way to save
probe load decompress load %compressed.dat ; and load compressed series
foreach name more-names [print name] ; FOR EACH item in list [do this]
foreach month system/locale/months [print month]
foreach file (read %./) [print file]
items: ["car" "boat" "house"]
foreach item items [print rejoin ["I like my " item]]
count: 0
foreach item items [
count: count + 1
print rejoin ["^/Item #" count ": " item]
]
big-block: [
[may june july]
[
[1 2 3]
[
[yes no]
[monday tuesday friday]
]
]
]
; Indentation makes the block easier to read, but is not required:
big-block: [[may june july][[1 2 3][[yes no][monday tuesday friday]]]]
probe first big-block ; 3 ways to get the first item in the block
probe big-block/1
probe pick big-block 1
probe second big-block ; 3 ways to get the second item in the block
probe big-block/2
probe pick big-block 2
probe first second big-block ; 1st block in the 2nd block in big-block
probe big-block/2/1
probe second second big-block ; 2nd block in the 2nd block in big-block
probe big-block/2/2
probe first second second big-block
probe big-block/2/2/1
probe second second second big-block
probe big-block/2/2/2
probe big-block/2/2/2/1
probe big-block/2/2/2/2
probe big-block/2/2/2/3
users: [
"John Smith" "123 Tomline Lane Forest Hills, NJ" "555-1234"
"Paul Thompson" "234 Georgetown Pl. Peanut Grove, AL" "555-2345"
"Jim Persee" "345 Pickles Pike Orange Grove, FL" "555-3456"
"George Jones" "456 Topforge Court Mountain Creek, CO" ""
"Tim Paulson" "" "555-5678"
]
probe extract users 3 ; the name column (every 3rd item)
probe extract/index users 3 2 ; address column (skip 3, starting on 2)
probe extract/index users 3 3 ; phone column (skip 3, starting on 3)
probe form users ; convert entire block to a string
foreach [name address phone] users [ ; get groups of 3 consecutive items
print rejoin [
"^/Name: " name
"^/Address: " address
"^/Phone: " phone
]
]
foreach name (extract users 3) [
if find name "a" [
print pick users ((index? find users name) + 2)
]
] ; prints phone numbers for all names that contain the letter "a"
do [
prin newpage
field: to-integer ask {Field to search (1=name, 2=address, 3=phone): }
search-text: ask {Text to search for: }
foreach [name address phone] users [
if find (pick reduce [name address phone] field) search-text [
print rejoin [
newline
"Name: " name newline
"Address: " address newline
"Phone: " phone newline
]
]
]
] ; "do" allows us to run some interactive console code such as "ask"
forever [
prin newpage
count: 1
sorted-names: sort extract users 3
foreach name sorted-names [
print rejoin [newline count " - " name]
count: count + 1
]
choice: to-integer ask "^/^/Selection: "
unless choice > (length? sorted-names) [
chosen: index? find users (pick sorted-names choice)
print newline
for i chosen (chosen + 2) 1 [print pick users i]
continue: ask "^/^/[ENTER] to continue, 'Q' to quit..."
if continue = "q" [prin newpage halt]
]
]
append users ["Joe Thomas" "" "555-321-7654"] ; append to end of list
name: "Alex Sharp" address: "937 Boll Rd" phone: "555-294-2834"
repend users [name address phone] ; append variable values
insert (at users 4) [
"Tom Adams" "321 Way Lane Villageville, AZ" "555-987-6543"
]
remove (at users 4) ; remove 1 item
remove/part (at users 4) 2 ; remove 2 items
change (at users 1) "Jonathan Smith"
remove (at users 1) insert (at users 1) "Jonathan Smith"
foreach item users [
replace item "John Smith" "Jonathan Smith"
]
new-users: copy []
foreach [name address phone] users [
append/only new-users reduce [name address phone]
] ; append/only inserts blocks as blocks, instead of as individual items
editor new-users
field: 2 sort/compare new-users func [a b] [(at a field) < (at b field)]
editor new-users ; sorted by the 2nd field (by address)
users: copy []
foreach block new-users [append users reduce block] ; "flatten" block
editor users
copy/part users 3
copy/part (at users 4) 3
copy at tail users -3
copy/part (at users 7) 3
copy/part (find users "Jim Persee") -3
copy/part (skip (find users "Jim Persee") -6) 3
alert form (copy/part users 3)
chosen: request-list "Choose a person: " (extract users 3)
alert form reduce [copy/part find users chosen 3]
alert reform [copy/part find users chosen 3]
chosen: request-list "Choose an address: " (extract/index users 3 2)
alert reform [copy/part at (find users chosen) -1 3]
x: ["one" "two" "three" "four" "five" "six"]
move/to (find x "five") 2
print x ; item position changed
x: ["asdf" "qwer" "zxcv" "uiop" "hjkl" "vbnm"]
y: head clear skip tail x -2
probe y ; last 2 items removed
data: [
1 2 3 [4 5 6]
7 8 9 [0 9 8 7 6 5 4 3 2 1]
3 4 5 [6 3 1 7 8 0]
]
counter: 1
foreach [col1 col2 col3 col4] data [
print rejoin [
"Row: " counter newline
"Column1: " col1 newline
"Column2: " col2 newline
"Column3: " col3 newline
"Column4 (sorted): " (sort col4) newline newline
]
counter: counter + 1
]
foreach file read %. [
if (suffix? file) = %.tester [
rename file to-file (replace to-string file ".tester" ".test")
]
] ; directories are just lists of files - all series operations work
list-dir
for i 1 length? pp: open pop://user@site.com 1 compose [
ask find pp/(i) "Subject:"
]
foreach line reverse copy system/console/history [print line]
replace/all replace/all replace/all replace/all form now/precise trim {
/} "" ":" "x" "-" "q" "." "" ; useful unique string generator
some-items: ["item1" "item2" "item3" "item4"]
an-image: load http://rebol.com/view/bay.jpg
append some-items an-image ; block now contains 4 strings and an image
save/all %some-items.txt some-items ; save it all to a simple text file
some-items: load %some-items.txt ; load it back and use it later
view layout [image fifth some-items]
photo1: load http://rebol.com/view/bay.jpg
photo2: load http://rebol.com/view/demos/palms.jpg
photo-block: reduce [photo1 photo2]
; or photo-block: compose [(photo1) (photo2)]
foreach photo photo-block [view layout [image photo]]
STRINGS (series of characters):
the-string: "abcdefghijklmnopqrstuvwxyz"
copy/part the-string 7
copy at tail the-string -7
copy/part (at the-string 12) 7
copy/part (find the-string "m") -7
copy/part (skip (find the-string "t") -12) 7
the-string/7
pick the-string 7
seventh the-string
replace the-string "cde" "123"
change (at the-string 7) "7"
poke the-string 7 #"7"
poke the-string 7 (to-char "7")
print the-string
remove/part (at the-string 3) 15
print the-string
insert (at the-string 3) "cdefghijklmnopq"
print the-string
insert/dup head the-string "-+ " 3
print the-string
replace/all the-string "-+ " " "
print the-string
trim the-string
print the-string
extract the-string 3
to-integer third the-string
to-char 99
to-string to-char 99
to-string now
to-string $2344.44
to-string to-char 99
to-string system/locale/months
form now
form $2344.44
form to-char 99
form system/locale/months
the-block: copy []
foreach item the-string [append the-block item]
probe the-block
GUI WINDOWS (graphic user interfaces):
; VIEW LAYOUT [block of widgets] ; basic syntax
;
; view layout [
; widget1 properties [BLOCK OF ACTIONS TO BE PERFORMED BY WIDGET1]
; widget2 properties [BLOCK OF ACTIONS TO BE PERFORMED BY WIDGET2]
; ]
view layout [area btn "Click Me"] ; text area and button with some text
view layout [
area
btn "Click Me" [alert "You can type in the square area."]
]
view center-face layout [ ; center the GUI window on the screen
a: area ; label this text area "a"
btn "Save" [ ; do this when the button is clicked:
write %temp.txt a/text ; write the text in the area to a file
alert "Saved" ; notify the user
]
]
view layout [
f1: field "123" ; Text fields ONLY hold string values.
f2: field "http://rebol.com"
btn "Show Data Types" [
print type? f1/text ; Field text must be CONVERTED to
print type? f2/text ; expected REBOL data types for use:
]
btn "Multiply" [print (to-integer f1/text) * 2] ; convert to number
btn "Browse" [browse (to-url f2/text)] ; convert to URL
btn "Error" [print f1/text * 2] ; you can't perform math on strings
]
; ALWAYS use "show" to update ANY screen changes, as in this text editor:
view layout [
a: area 600x350 wrap ; 600 pixels wide by 350 pixels tall
across ; layout next widgets horizontally
f: field 500 "filename.txt" ; 500 pixels across, with default text
btn "Load" [ ; do the following lines when clicked:
f/text: request-file/file f/text ; set text to selected file name
show f ; TEXT CHANGED so widget must be updated
a/text: read to-file f/text ; set area text to data read from file
show a ; TEXT CHANGED so widget must be updated
]
btn "Save" [ ; do the following lines when clicked:
write (request-file/only/save/file f/text) a/text ; write the
alert "Saved" ; text in the area widget, to a file
] ; selected by the user, notify when done
]
view gui: layout [ ; label the entire GUI layout
size 600x400 ; set the window size
backdrop white ; set the window background color
field1: field 560
field2: field 560
area1: area 560x235 wrap
btn "Save" [
save-block: copy []
append save-block field1/text
append save-block field2/text
append save-block area1/text
save %save.txt save-block
alert {SAVED -- Now try running this script again, and load
the data back into the fields.}
]
btn "Load" [
save-block: load %save.txt
field1/text: save-block/1
field2/text: save-block/2
area1/text: save-block/3
show gui ; UPDATE ENTIRE GUI to show changes
]
]
view layout[
h1 "Send:" ; big bold text widget (h1, h2, h3, ...)
btn "Server settings" [ ; save user's email settings in REBOL:
system/schemes/default/host: request-text/title "SMTP Server:"
system/schemes/pop/host: request-text/title "POP Server:"
system/schemes/default/user: request-text/title "SMTP User Name:"
system/schemes/default/pass: request-text/title "SMTP Password:"
system/user/email: to-email request-text/title "Email Address:"
]
a: field "user@website.com"
s: field "Subject"
b: area
btn "Send" [attempt [
send/subject (to-email a/text) b/text s/text
alert "Sent"
]] ; "attempt" handles potential errors sending mail
h1 "Read:"
f: field "pop://user:pass@site.com"
btn "Read" [editor to-url f/text]
]
REBOL [title: "My Title"] ; this appears in the title bar of a GUI window
view layout [
h3 "SOME POSITIONING EXAMPLES:"
across
btn "side" btn "by" btn "side"
return
btn "on the next line"
tab
btn "over a bit"
tab
btn "over more"
below
btn 160 "underneath" btn 160 "one" btn 160 "another"
at 359x256
btn "at 359x256"
]
write/append %save.txt "" ; A useful data management program
view center-face gui: layout [
text "Part Number:"
x: field 560
text "Part Name:"
y: field 560
text "Description:"
z: area wrap 560x235
across
btn "Save" [
do-face d 1 ; do all the delete button's code
save %save.txt repend file [x/text y/text z/text]
]
btn "Load" [
chosen: request-list "Select:" extract (file: load %save.txt) 3
if chosen = none [return]
i: index? find file chosen
x/text: pick file i
y/text: pick file (i + 1)
z/text: pick file (i + 2)
show gui
]
d: btn "Delete" [
if true = request "Sure?" [
remove/part (find (file: load %save.txt) x/text) 3
save %save.txt file
alert "Done"
]
]
btn "Clear" [x/text: copy "" y/text: copy "" z/text: copy "" show gui]
do [focus x]
]
write/append %recipes.txt "" ; The program above, altered to hold recipes
view center-face gui: layout [
text "Recipe Name:"
x: field 560
text "Ingredients:"
y: area wrap 560x135
text "Preparation Instructions:"
z: area wrap 560x135
across
btn "Save" [
do-face d 1 ; do all the delete button's code
save %recipes.txt repend file [x/text y/text z/text]
]
btn "Load" [
chosen: request-list "Select:" extract (file: load %recipes.txt) 3
if chosen = none [return]
i: index? find file chosen
x/text: pick file i
y/text: pick file (i + 1)
z/text: pick file (i + 2)
show gui
]
d: btn "Delete" [
if true = request "Sure?" [
remove/part (find (file: load %recipes.txt) x/text) 3
save %recipes.txt file
alert "Done"
]
]
btn "Clear" [x/text: copy "" y/text: copy "" z/text: copy "" show gui]
do [focus x]
]
write/append %s "" ; A very compact version of the above program
view center-face g: layout [
h3 "Name:" x: field h3 "Info:" z: area wrap across
btn "Save" [do-face d 1 save %s repend f [x/text z/text]]
btn "Load" [
c: request-list" Select:" extract (f: load %s) 2
if c = none [return]
x/text: first find f c z/text: select f x/text show g
]
btn "New" [x/text: copy "" z/text: copy "" show g focus x]
d: btn "Delete" [
if true = request "Sure?" [
remove/part (find (f: load %s) x/text) 2 save %s f alert "ok"
]
]
]
s: ftp://user:pass@website.com/public_html/s.txt ; edit this account info
write/append s "" ; an Internet version of the above program
view center-face g: layout [
h3 "Name:" x: field h3 "Info:" z: area wrap across
btn "Save" [do-face d 1 save s repend f [x/text z/text]]
btn "Load" [
c: request-list" Select:" extract (f: load s) 2
if c = none [return]
x/text: first find f c z/text: select f x/text show g
]
btn "New" [x/text: copy "" z/text: copy "" show g focus x]
d: btn "Delete" [
if true = request "Sure?" [
remove/part (find (f: load s) x/text) 2 save s f alert "ok"
]
]
]
; browse s
; The word "value" refers to data contained in a currently active widget:
view layout [
text "Some widgets with values and size/color properties. Try them:"
button red "Click Me" [alert "You clicked the red button."]
f: field 400 "Type some text here, then press the [Enter] key" [
alert value ; SAME AS alert f/text
]
t: text-list 400x300 "Select this line" "Then this one" "Now this" [
alert value ; SAME AS alert t/text
]
check yellow [alert "You clicked the yellow check box."]
button "Quit" [quit]
]
print "GUI Output:^/"
view layout [
h1 "Some More GUI Widgets:"
box red 500x2
drop-down 200 data system/locale/months [
a/text: join "Month: " value show a
]
a: field
slider 200x18 [bar1/data: value show bar1]
bar1: progress
scroller 200x16 [bar2/data: value show bar2]
bar2: progress
across
toggle "Click here" "Click again" [print value]
rotary "Click" "Again" "And Again" [print value]
choice "Choose" "Item 1" "Item 2" "Item 3" [print value]
return
x: radio y: radio z: radio
btn "Get Radio States" [print [x/data y/data z/data]]
return
led
arrow
below
code "Code text"
tt "Typewriter text"
text "Little Text" font-size 8
title "Centered title" 500
]
; List Widget:
y: read %. c: 0 x: copy []
foreach i y [append/only x reduce [(c: c + 1) i (size? to-file i)]]
slider-pos: 0
view center-face layout [
across space 0
the-list: list 400x400 [
across space 0x0
text 50 purple
text 250 bold [editor read to-file face/text]
text 100 red italic
return box green 400x1
] supply [
count: count + slider-pos
if none? q: pick x count [face/text: none exit]
face/text: pick q index
]
scroller 16x400 [
slider-pos: (length? x) * value
show the-list
]
]
view layout [
area 400x400 load http://rebol.com/view/bay.jpg effect [
Fit Flip Emboss ; you can fit images on most widgets
]
]
effects: [ ; and there are MANY more effects:
invert contrast 40 colorize 0.0.200 gradcol 1x1 0.0.255 255.0.0 tint 100
luma -80 multiply 80.0.200 grayscale emboss flip 0x1 flip 1x0 rotate 90
reflect 1x1 blur sharpen aspect tile tile-view
]
view layout [area effect [gradient red blue]] ; gradients are color fades
view layout [
size 500x400
backdrop effect [gradient 1x1 tan brown]
box effect [gradient 123.23.56 254.0.12]
box effect [gradient blue gold/2]
]
view layout [
btn "Right/Left Click Me" [alert "left click"] [alert "right click"]
]
gui: layout [
across
btn "Fields" [window/pane: pane1 show window]
btn "Text List" [window/pane: pane2 show window]
return
window: box 400x200
]
pane1: layout/tight [field 400 field 400 area 400]
pane2: layout/tight [text-list 400x200 data system/locale/days]
window/pane: pane1
view center-face gui
svv/vid-face/color: white
alert "New global background color is now white."
; The word "offset" refers to a widget's coordinate position.
; The word "style" builds a new widget with the specified style & actions:
view center-face layout [
origin 0x0 space 0x0 across
style piece button 60x60 [
if not find [0x60 60x0 0x-60 -60x0] (face/offset - empty/offset) [
return ; exit from the widget action (don't do anything else)
]
temp: face/offset
face/offset: empty/offset
empty/offset: temp
]
piece "1" piece "2" piece "3" piece "4" return
piece "5" piece "6" piece "7" piece "8" return
piece "9" piece "10" piece "11" piece "12" return
piece "13" piece "14" piece "15"
empty: piece 200.200.200 edge [size: 0]
]
view center-face layout [
size 600x440
h3 "Press the left or right arrow key"
key keycode [left] [alert "You pressed the LEFT arrow key"]
key keycode [right] [alert "You pressed the RIGHT arrow key"]
btn #"a" "Click Me or Press the 'a' Key" [alert "clicked or pressed"]
]
; Here's a little program to show all key codes:
insert-event-func func [f e] [if e/type = 'key [print mold e/key] e]
view layout [text "Type keys to see their character/keycode"]
view gui: layout [ ; how to refer to the main layout window:
btn1: btn "Button 1"
btn2: btn "Remove all widgets from window" [
foreach item system/view/screen-face/pane/1/pane [
remove find system/view/screen-face/pane/1/pane item
]
show gui
]
]
; "Feel" and "Engage" together detect events:
view layout [
text "Mouse me." feel [
engage: func [face action event] [
if action = 'up [print "You just released the mouse."]
]
]
]
print "Click anywhere in the window, then click the text."
view center-face layout [
size 400x200
box 400x200 feel [
engage: func [f a e] [ ; f a e = face action event
print rejoin ["Mouse " a " at " e/offset]
]
]
origin
text "Click me" [print "Text clicked"] [print "Text right-clicked"]
box blue [print "Box clicked"]
]
movestyle: [ ; generic click and drag code
engage: func [f a e] [
if a = 'down [
initial-position: e/offset
remove find f/parent-face/pane f
append f/parent-face/pane f
]
if find [over away] a [
f/offset: f/offset + (e/offset - initial-position)
]
show f
]
]
view layout/size [
style moveable-object box 20x20 feel movestyle
at random 600x400 moveable-object (random 255.255.255)
at random 600x400 moveable-object (random 255.255.255)
at random 600x400 moveable-object (random 255.255.255)
at random 600x400 moveable-object (random 255.255.255)
at random 600x400 moveable-object (random 255.255.255)
text "This text and all the boxes are movable" feel movestyle
] 600x440
; The following box code creates a repeating, multitasking loop in a GUI.
; The "within" function checks for graphic collisions:
view center-face layout [
size 400x400
btn1: btn red
at 175x175 btn2: btn green
box 0x0 rate 0 feel [engage: func [f a e] [if a = 'time [
btn1/offset: btn1/offset + 5x5
show btn1
if within? btn1/offset btn2/offset 1x1 [alert "Collision" unview]
]]]
]
; Here's another, faster performing way to do GUI loops and multitasking:
gui: view/new center-face layout [
size 400x400
btn1: btn red
at 175x175 btn2: btn green
]
forever [
wait .02
btn1/offset: btn1/offset + 5x5 show gui ; show btn1
if within? btn1/offset btn2/offset 1x1 [alert "Collision"]
if btn1/offset/1 > 300 [alert "done" quit]
]
view center-face layout [ ; follow all mouse movements
size 600x440
at 270x209 b: btn "Click Me!" feel [
detect: func [f e] [
if e/type = 'move [
if (within? e/offset b/offset 59x22) [
b/offset: b/offset + ((random 50x50) - (random 50x50))
if not within? b/offset -59x-22 659x462 [
b/offset: 270x209
]
show b
]
]
e
]
]
]
; To trap other events (this example traps and responds to close events):
insert-event-func [
either event/type = 'close [
really: request "Really close the program?"
if really = true [unview]
] [event] ; always return other events
]
view center-face layout [size 600x400]
insert-event-func [ ; this example traps resize events
either event/type = 'resize [
fs: t1/parent-face/size
t1/offset: fs / 2x2
t2/offset: t1/offset - 50x25
t3/offset: t1/offset - 25x50
show gui none
] [event]
]
svv/vid-face/color: white
view/options gui: layout [
across
t1: text "50x50"
t2: text "- 50x25"
t3: text "- 25x50"
] [resize]
; Use "to-image" to create a SCREEN SHOT of any layout:
picture: to-image layout [
page-to-read: field "http://rebol.com"
btn "Display HTML"
]
save/png %layout.png picture ; save the image to a file
browse %layout.png
flash "Waiting..." wait 3 unview ; a simple info screen
inform layout [btn "Click Me" [flash "Waiting..." wait 3 unview]]
; Embed files (images, sounds, etc.) in code:
system/options/binary-base: 64
editor picture: compress to-string read/binary to-file request-file/only
view layout [image load (to-binary decompress picture)]
logo-pic: load to-binary decompress #{
789C018A0375FC89504E470D0A1A0A0000000D49484452000000640000001808
020000008360CFB90000001374455874536F667477617265005245424F4C2F56
6965778FD916780000033249444154789CD599217402310C86F7CE6227B1481C
1637874362B1382C1687C4A15168240A89C5A2B058ECDEBE47DFFA429276DCEE
10FDCD582F97267FD33F2D7CF47ABDCF32D1ED76E7F3F9ED76FB4EE0743A8D46
A3B6A683A80FFE540562381C1E8FC7144D12DBEDB6951C3B9D4E91648DC7E34C
41B925465D349C14A2CA230BA65EA729E27C3E37CCB43CB228905A3525B1DBED
9A4CED93851C7C193088A0667C0D0603FB5640BFDFB7F648C0D0836B1C41C22E
11D7EBF57038F074BFDF534429BE2693891B4626CE1C59BC7CB95CDC99EEF7FB
66B349F922D65A4B4A8DE0D0B547B9DD85212B6B4CB4D3E994B055FEE8943566
30134626BBDA64052C974BD757A637B1DA2E599959A05EE61F4032D62C55EFBC
6EED01878954188DC80AE714C07126D24F91BBBE6265A129B3D96C2A4085BB64
459FEBF51A1B2692E5A9FA17A428B562EBE595A1F29650AD5C6B9525FD4621E0
A95D73491606F9046C94101A06178B4518E19122023655DA184B03ECA15BE98E
6D9D302E536E8D2C96A5FF0061458FEE9EAA045958720EDCFC82CF145A9E2C7C
52BC6CF0503B8C2B2200DAACD24698A4B710361E6421930E05A85E9484BE51B3
0885AE9727CB22A5591981B73D1AC6A58D2ABD5892DF46C5993DCFF25BC8828E
14538AACEB3390A43C59D890213B5D2AA3D2AC3C59ABD54ACE2E85C29E36DE42
162B8C0AC47F0942B512972CCCF0D91170ED6594ECC130288549ED44744DE52C
771381C571D5AFEDB14B2E79CB022F13C834A056049EFCE35C2A7449877A2B00
2D872635082FEA2D267D8BC047AD910D3875CE9247078A826259FC8234F264E1
9FAD4AAC52015465D973193B3755B611B417FB562A0C66C77EF7001F5463FD83
2CF20F83B2B8E0C22DAE760FA556B32AAF87B86A18C18259CFAA3567C250C7C3
1AE72CD95350531BD93FAE3B6CEADB33188174FCBBD77B7B7A0841DAB6C3EBEE
F13DE8696B6455E222ADCE23F162ECF644064709A47AA8FD3632BFAD78EA5E92
D947500C3BB04CAD419F3D5B05580DC127118E3D2866CAFB8AC6CAFCEB68F895
56796455CF47AAD741F5B957D4D751245980BD569729B723D742A964558FFB4D
EAB6A440BF6ACE54157EB028F7A730B695BDF749D05EA9C1B612C4CF0F396EDC
8E943F5C020000000049454E44AE426082CAEBA2D78A030000
} ; this example embedded image was created with the script above
view layout [image logo-pic]
; Here are all the main GUI words that you should get to know:
VID-STYLES--GUI-WIDGETS: [
face blank-face IMAGE BACKDROP BACKTILE BOX BAR SENSOR KEY BASE-TEXT
VTEXT TEXT BODY TXT BANNER VH1 VH2 VH3 VH4 LABEL VLAB LBL LAB TITLE
H1 H2 H3 H4 H5 TT CODE BUTTON CHECK CHECK-MARK RADIO CHECK-LINE
RADIO-LINE LED ARROW TOGGLE ROTARY CHOICE DROP-DOWN ICON FIELD INFO
AREA SLIDER SCROLLER PROGRESS PANEL LIST TEXT-LIST ANIM BTN BTN-ENTER
BTN-CANCEL BTN-HELP LOGO-BAR TOG
]
LAYOUT-WORDS: [
return at space pad across below origin guide tab tabs indent style
styles size backcolor backeffect do
]
STYLE-FACETS--ATTRIBUTES: [
edge font para doc feel effect effects keycode rate colors texts help
user-data with bold italic underline left center right top middle
bottom plain of font-size font-name font-color wrap no-wrap as-is
shadow frame bevel ibevel
]
SPECIAL-STYLE-FACETS: [
ARROW: [up right down left] ROTARY: data CHOICE: data DROP-DOWN:
[data rows] FIELD: hide INFO: hide AREA: hide LIST: [supply map
data] TEXT-LIST: data ANIM: [frames rate]
]
FUNCTIONS:
; ANY string or block of data can be treated like a function:
some-actions: [
alert "Here is one action."
print "Here's a second action."
write %/c/anotheraction.txt "Here's a third action."
]
do some-actions
write clipboard:// {alert "This code was run from the clipboard"}
do read clipboard:// ; copy, paste and run ANY code this way
write %some-code.r {
REBOL [] ; executable code saved to a file must begin with this header
print rejoin [newpage "The code in %some-code.r just ran." newline]
}
do %some-code.r
write ftp://user:pass@site.com/public_html/some-code.r {
REBOL []
print "The code in http://site.com/some-code.r just ran."
}
do http://site.com/some-code.r
the-word: to-word request-list "choose a word:" (first system/words)
do rejoin ["help " the-word] ; you can DO any rejoined text
cls: does [prin "^(1B)[J"] ; same as "prin newpage"
cls ; no "do" required when a word is defined with "does"
x: 10
change-x-globally: func [y z] [x: y + z]
change-x-globally 10 20
print x
x: 10
change-x-locally: func [y z /local x] [x: y + z]
change-x-locally 10 20
print x
compute: func [x y /multiply /divide /subtract] [
if multiply [return x * y]
if divide [return x / y]
if subtract [return x - y]
return x + y
]
compute/multiply 10 20
compute/divide 10 20
compute/subtract 10 20
compute 10 20
concatenate-string-or-num: func [
"This function will only concatenate strings or integers."
val1 [string! integer!] "First string or integer"
val2 [string! integer!] "Second string or integer"
] [
join val1 val2
]
help concatenate-string-or-num
concatenate-string-or-num "Hello " "there." ; this works correctly
concatenate-string-or-num 10 20 ; this works correctly
concatenate-string-or-num 10.1 20.3 ; this creates an error
do [
print "^/This example builds a line of code, and then executes it.^/"
function: ask "Enter a function, such as 'print' or 'editor': "
parameter: ask "Enter a parameter, such as some random text: "
print rejoin [function { "} parameter {"}]
do rejoin [function { "} parameter {"}]
do compose [(to-word function) (parameter)]
print "That's a very simple way to accomplish metaprogramming tasks."
]
write %imported-func.r {
REBOL [title: "play-sound"]
play-sound: func [sound-file] [
wait 0
insert sound-port: open sound:// load sound-file
wait sound-port
close sound-port
]
}
do %imported-func.r
play-sound %/C/WINDOWS/Media/chimes.wav
editor mold :read-cgi ; get the code of any function
request: do replace/all mold :request "bold" "" ; redefine function
request/ok/type "An alert without bold text" 'alert
SEVERAL APPLICATION EXAMPLES:
REBOL [title: "Data Card File"]
write/append %data.txt "" ; create the file if it doesn't exist
database: load %data.txt
view center-face gui: layout [
text "Load an existing record:"
name-list: text-list blue 400x100 data sort (extract database 4) [
if value = none [return]
marker: index? find database value
n/text: pick database marker
a/text: pick database (marker + 1)
p/text: pick database (marker + 2)
o/text: pick database (marker + 3)
show gui
]
text "Name:" n: field 400
text "Address:" a: field 400
text "Phone:" p: field 400
text "Notes:" o: area 400x100
across
btn "Save" [
if n/text = "" [alert "You must enter a name." return]
if find (extract database 4) n/text [
either true = request "Overwrite existing record?" [
remove/part (find database n/text) 4
] [
return
]
]
save %data.txt repend database [n/text a/text p/text o/text]
name-list/data: sort (extract copy database 4)
show name-list
]
btn "Delete" [
if true = request rejoin ["Delete " n/text "?"] [
remove/part (find database n/text) 4
save %data.txt database
do-face clear-button 1
name-list/data: sort (extract copy database 4)
show name-list
]
]
clear-button: btn "New" [
n/text: copy ""
a/text: copy ""
p/text: copy ""
o/text: copy ""
show gui
]
]
REBOL [title: "Calculator"]
prev-val: cur-val: 0 cur-eval: "+" display-flag: false
print "0"
view center-face layout/tight [
size 300x350 space 0x0 across
display: field 300x50 font-size 28 "0" return
style butn button 100x50 [
if display-flag = true [display/text: "" display-flag: false]
if display/text = "0" [display/text: ""]
display/text: rejoin [display/text value]
show display
cur-val: display/text
]
style eval button 100x50 brown font-size 13 [
prev-val: cur-val
display/text: "" show display
cur-eval: value
]
butn "1" butn "2" butn "3" return
butn "4" butn "5" butn "6" return
butn "7" butn "8" butn "9" return
butn "0" butn "." eval "+" return
eval "-" eval "*" eval "/" return
button 300x50 gray font-size 16 "=" [
if display-flag <> true [
if ((cur-eval = "/") and (cur-val = "0")) [
alert "Division by 0 is not allowed." break
]
prin rejoin [prev-val " " cur-eval " " cur-val " = "]
print display/text: cur-val: do rejoin [
prev-val " " cur-eval " " cur-val
]
show display
display-flag: true
]
]
]
REBOL [title: "Simple Search"]
phrase: request-text/title/default "Text to Find:" "the"
start-folder: request-dir/title "Folder to Start In:"
change-dir start-folder
found-list: ""
recurse: func [current-folder] [
foreach item (read current-folder) [
if not dir? item [ if error? try [
if find (read to-file item) phrase [
print rejoin [{"} phrase {" found in: } what-dir item]
found-list: rejoin [found-list newline what-dir item]
]] [print rejoin ["error reading " item]]
]
]
foreach item (read current-folder) [
if dir? item [
change-dir item
recurse %.\
change-dir %..\
]
]
]
print rejoin [{SEARCHING for "} phrase {" in } start-folder "...^/"]
recurse %.\
print "^/DONE^/"
editor found-list
halt
REBOL [title: "Catch Game"]
alert "Arrow keys move left/right (up: faster, down: slower)"
random/seed now/time speed: 11 score: 0
view center-face layout [
size 600x440 backdrop white across
at 270x0 text "Score:" t: text bold 100 (form score)
at 280x20 y: btn 50x20 orange
at 280x420 z: btn 50x20 blue
key keycode [left] [z/offset: z/offset - 10x0 show z]
key keycode [right] [z/offset: z/offset + 10x0 show z]
key keycode [up] [speed: speed + 1]
key keycode [down] [if speed > 1 [speed: speed - 1]]
box 0x0 rate 0 feel [engage: func [f a e] [if a = 'time [
y/offset: y/offset + (as-pair 0 speed) show y
if y/offset/2 > 440 [
y/offset: as-pair (random 550) 20 show y
score: score - 1
]
if within? z/offset (y/offset - 50x0) 100x20 [
y/offset: as-pair (random 550) 20 show y
score: score + 1
]
t/text: (form score) show t
]]]
]
REBOL [title: "Catch Game"]
random/seed now s: 0 p: 10
r: func [x] [y/offset: as-pair random 550 20 s: s + x]
view/new center-face g: layout [
size 600x440 backdrop white across
at 270x0 t: text 100 "Score: 0"
at 280x20 y: btn 50x20 orange
at 280x420 z: btn 50x20 blue
key keycode [left] [z/offset: z/offset - 10x0]
key keycode [right] [z/offset: z/offset + 10x0]
key keycode [up] [p: p + 1]
key keycode [down] [if p > 1 [p: p - 1]]
]
forever [
y/offset: y/offset + as-pair 0 p
if overlap? z y [r +1] if y/offset/2 > 440 [r -1]
t/text: join "Score: " s show g wait .02
]
REBOL [title: "Catch Game"]
s: 1 p: 3 d: 10 n: now/time random/seed now
r: func [x] [y/offset: random 550x-20 s: s + x p: p + .1]
view/new g: layout [
size 600x440 backdrop white t: text 200
y: btn red #" " [d: negate d] at 350x415 z: btn blue
]
forever [
y/offset/2: y/offset/2 + round p z/offset/1: z/offset/1 - d
if overlap? z y [r +1] if y/offset/2 > 435 [r -1]
t/text: rejoin ["Pieces: " s " | Score: " now/time - n]
show g wait .01 if s = 0 [alert "Game Over" quit]
]
REBOL [title: "Catch Game Stop"]
s: 1 p: 3 d: 10 n: now/time random/seed now
r: func [x] [y/offset: random 550x-20 p: p + .1 s: s + x]
view/new center-face g: layout [
size 600x440 backdrop white t: text 200
y: btn red #" " [d: negate d] at 350x415 z: btn blue
]
forever [
y/offset/2: y/offset/2 + round p z/offset/1: z/offset/1 - d
z/offset/1: switch/default z/offset/1 [0 [0 + d] 550 [550 + d]][
z/offset/1
]
if overlap? z y [r +1] if y/offset/2 > 420 [r -1]
t/text: rejoin ["Pieces: " s " | Time: " now/time - n]
wait .01 if s = 0 [alert t/text quit] show g
]
REBOL [title: "Catch Game Stop Minimal (favorite)"]
s: 1 p: 3 d: 10 n: now/time random/seed now
r: func [x] [y/offset: random 550x-20 p: p + .1 s: s + x]
view/new center-face g: layout[
size 600x440 t: text 200 y: btn red #" "[d: negate d] at 350x415 z: btn
]
forever [
y/offset/2: y/offset/2 + round p z/offset/1: z/offset/1 - d
z/offset/1: switch/default z/offset/1[0[0 + d]550[550 + d]][z/offset/1]
if overlap? z y [r +1] if y/offset/2 > 420 [r -1]
t/text: form now/time - n wait .01 if s = 0[alert t/text quit] show g
]
REBOL [title: "Catch Game Stop Minimal High Score (favorite)"]
s: 1 p: 3 d: 10 n: now/time random/seed now
r: func [x] [y/offset: random 550x-20 p: p + .1 s: s + x]
view/new center-face g: layout[
size 600x440 t: text 200 y: btn red #" "[d: negate d] at 350x415 z: btn
]
forever [
y/offset/2: y/offset/2 + round p z/offset/1: z/offset/1 - d
z/offset/1: switch/default z/offset/1[0[0 + d]550[550 + d]][z/offset/1]
if overlap? z y [r +1] if y/offset/2 > 420 [r -1]
t/text: form now/time - n wait .01 show g if s = 0 [
write/append %h "" save %h append h: load %h reduce
[request-text/title "Name:"t/text now]request-list"High Scores:"h q
]
]
REBOL [title: "Catch"]
bonuses: 1
speed: 3
direction: 10
starttime: now/time
random/seed now
restart: func [add-or-subtract] [
faller/offset: random 550x-20
speed: speed + .1
bonuses: bonuses + add-or-subtract
]
view/new center-face gui: layout[
size 600x440
scoreboard: text 200
faller: btn red #" " [direction: negate direction]
at 350x415 player: btn
]
forever [
faller/offset/2: faller/offset/2 + round speed
player/offset/1: player/offset/1 - direction
player/offset/1: switch/default player/offset/1 [
0 [0 + direction]
550 [550 + direction]
][
player/offset/1
]
if overlap? player faller [restart 1]
if faller/offset/2 > 420 [restart -1]
scoreboard/text: form now/time - starttime
wait .01
if bonuses = 0 [
alert scoreboard/text quit
write/append %highscores.txt ""
save %highs.txt append highscores: load %high.txt reduce [
request-text/title "Name:" scoreboard/text now
]
request-list "High Scores:" highscores
quit
]
show gui
]
REBOL[]s: 1 p: 3 d: 10 n: now/time random/seed now r: func[x][y/offset:
random 550x-20 p: p + .1 s: s + x]view/new g: layout[size 600x440 t: text
200 y: btn red #" "[d: negate d]at 350x415 z: btn]forever[y/offset/2:
y/offset/2 + round p z/offset/1: z/offset/1 - d z/offset/1: switch/default
z/offset/1[0[0 + d]550[550 + d]][z/offset/1]if overlap? z y[r +1]if
y/offset/2 > 420[r -1]t/text: form now/time - n wait .01 if s = 0[alert
t/text quit]show g]
REBOL[title: "Catch Bounce"]
s: 1 p: 3 d: 10 n: now/time random/seed now
r: func [x] [y/offset: random 550x-20 p: p + .1 s: s + x]
view/new center-face g: layout[
size 600x440 t: text 200 y: btn red #" "[d: negate d] at 350x415 z: btn
]
forever [
y/offset/2: y/offset/2 + round p z/offset/1: z/offset/1 - d
d: switch/default z/offset/1 [0 [negate d] 550 [negate d]] [d]
if overlap? z y [r +1] if y/offset/2 > 420 [r -1]
t/text: form now/time - n wait .01 if s = 0[alert t/text quit] show g
]
REBOL[title: "Catch Bounce"]
count: 1 speed: 3 dir: 10 start: now/time random/seed now
restart: func [x] [
faller/offset: random 550x-20
speed: speed + .1
count: count + 1
]
view/new center-face gui: layout [
size 600x440
timer: text 200
faller: btn red #" " [dir: negate dir]
at 350x415 player: btn
]
forever [
faller/offset/2: faller/offset/2 + round speed
player/offset/1: player/offset/1 - dir
if find [0 550] player/offset/1 [dir: negate dir]
if overlap? player faller [restart 1]
if faller/offset/2 > 420 [restart -1]
timer/text: form now/time - start
if count = 0 [alert timer/text quit]
wait .01 show gui
]
REBOL [title: "Simple Data Retrieval App - Console"]
users: [
["John" "Smith" "123 Tomline Lane" "Forest Hills, NJ" "555-1234"]
["Paul" "Thompson" "234 Georgetown Pl." "Peanut Grove, AL" "555-2345"]
["Jim" "Persee" "345 Pickles Pike" "Orange Grove, FL" "555-3456"]
["George" "Jones" "456 Topforge Court" "Mountain Creek, CO" ""]
["Tim" "Paulson" "" "" "555-5678"]
]
a-line: copy [] loop 65 [append a-line "-"]
a-line: trim to-string a-line
print-all: does [
foreach user users [
print a-line
print rejoin ["User: " user/1 " " user/2]
print a-line
print rejoin ["Address: " user/3 " " user/4]
print rejoin ["Phone: " user/5]
print newline
]
]
forever [
prin "^(1B)[J"
print "Here are the current users in the database:^/"
print a-line
foreach user users [prin rejoin [user/1 " " user/2 " "]]
print "" print a-line
prin "Type the name of a user below "
print "(part of a name will perform search):^/"
print "Type 'all' for a complete database listing."
print "Press [Enter] to quit.^/"
answer: ask {What person would you like info about? }
print newline
switch/default answer [
"all" [print-all]
"" [ask "Goodbye! Press any key to end." quit]
][
found: false
foreach user users [
if find rejoin [user/1 " " user/2] answer [
print a-line
print rejoin ["User: " user/1 " " user/2]
print a-line
print rejoin ["Address: " user/3 " " user/4]
print rejoin ["Phone: " user/5]
print newline
found: true
]
]
if found <> true [
print "That user is not in the database!^/"
]
]
ask "Press [ENTER] to continue"
]
REBOL [title: "Simple Data Retrieval App - GUI"]
users: [
["John" "Smith" "123 Tomline Lane" "Forest Hills, NJ" "555-1234"]
["Paul" "Thompson" "234 Georgetown Pl." "Peanut Grove, AL" "555-2345"]
["Jim" "Persee" "345 Pickles Pike" "Orange Grove, FL" "555-3456"]
["George" "Jones" "456 Topforge Court" "Mountain Creek, CO" ""]
["Tim" "Paulson" "" "" "555-5678"]
]
user-list: copy []
foreach user users [append user-list user/1]
user-list: sort user-list
view display-gui: layout [
h2 "Click a user name to display their information:"
across
list-users: text-list 200x400 data user-list [
current-info: []
foreach user users [
if find user/1 value [
current-info: rejoin [
"FIRST NAME: " user/1 newline newline
"LAST NAME: " user/2 newline newline
"ADDRESS: " user/3 newline newline
"CITY/STATE: " user/4 newline newline
"PHONE: " user/5
]
]
]
display/text: current-info
show display show list-users
]
display: area "" 300x400 wrap
]
REBOL [title: "Blogger"]
page: "blog.html"
ftp-url: ftp://user:pass@site.com/public_html/folder/ ; USER/PASS REQUIRED
html-url: join http://site.com/folder/ page
save/png %dot.png to-image layout/tight [box white 1x1] ; blank image
view center-face gui: layout [
h2 (form html-url)
text "Title:" t: field 400
text "Link:" l: field 400
text "Image:" i: btn 400 [i/text: request-file show i]
text "Text:" x: area 400x100
across
btn "Upload" [
if error? try [existing-text: read html-url] [
make-dir ftp-url
write (join ftp-url page) ""
existing-text: copy ""
]
picture: last split-path to-file i/text
write/binary (join ftp-url picture) (read/binary to-file i/text)
write (join ftp-url page) rejoin [
{