• Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

AltME groups: search

Help · search scripts · search articles · search mailing list

results summary

worldhits
r4wp134
r3wp1094
total:1228

results window for this page: [start: 601 end: 700]

world-name: r3wp

Group: All ... except covered in other channels [web-public]
Anton:
5-Sep-2006
switch2: func [

    "Selects a choice and evaluates the first block that follows it."
    [throw]
    value "Value to search for."
    cases [block!] "Block of cases to search."
    /default case [block!] "Default case if no others are found."
    /local rule
][
	rule: [
		1 1 () ; <-- value
		to block! set value block! (return do value) 
		to end
		| skip to () ; <-- type? value
	]
	rule/3: value
	change back tail rule type? value
	any [
		parse cases [some rule]
		do case
	]
]

;test
repeat n 10 [
	print [
		n

  switch2/default n [2 4 6 ['even] 1 3 5 ['odd]] [mold "--default--"]
	]
]
switch2 1 []
switch2/default 1 [] ["--default--"]
Anton:
5-Sep-2006
switch2: func [

    "Selects a choice and evaluates the first block that follows it."
    [throw]
    value "Value to search for."
    cases [block!] "Block of cases to search."
    /default case [block!] "Default case if no others are found."
    /local rule
][
	rule: [
		1 1 () ; <-- value
		to block! set case block! ; <- re-use the 'case variable
		to end
		| skip to () ; <-- type? value
	]
	rule/3: value
	change back tail rule type? value
	parse cases [some rule]
	do case
]

{switch2: func [

    "Selects a choice and evaluates the first block that follows it. 
    This occurs for every matching value and following block found."
    [throw]
    value "Value to search for."
    cases [block!] "Block of cases to search."
    /default case [block!] "Default case if no others are found."
    /local rule
][
	rule: [
		1 1 () ; <-- value

  to block! set case block! (case: do case) ; <- re-use the 'case variable, 
  twice...
		| [skip to ()] ; <-- type? value
		| skip
	]
	rule/3: value
	rule/11/3: type? value
	any [
		all [
			parse cases [some rule]
			case
		]
		do case
	]
]}

;test
repeat n 10 [
	print [
		n

  switch2/default n [2 4 6 ['even] 1 3 5 ['odd]] [mold "--default--"]
	]
]
switch2 1 []
switch2/default 1 [] [probe "--default, ok--"]
switch2 1 [1 [probe "ok"]]
switch2 2 [1 [probe "bad"]]
switch2 1 [1 2 [probe "ok"]]
switch2 2 [1 2 [probe "ok"]]
switch2 3 [1 2 [probe "bad"]]

; multiple action blocks
switch2 1 [1 2 [probe "ok"] 1 3 4 [probe "ok#2"]] ; <-- 
switch2 2 [1 2 [probe "ok"] 1 3 4 [probe "bad"]]
switch2 3 [1 2 [probe "bad"] 1 3 4 [probe "ok"]]
switch2 4 [1 2 [probe "bad"] 1 3 4 [probe "ok"]]
switch2 5 [1 2 [probe "bad"] 1 3 4 [probe "bad"]]


switch2/default 5 [1 2 [probe "bad"] 1 3 4 [probe "bad"]] [probe 
"--default, ok--"]
[unknown: 9]:
1-Nov-2006
Ah, I get it.  I really want to make a bunch of jokes about printing 
bibles, but will skip it.
Reichart:
31-Oct-2008
Also, what are the best tools to rip a DVD to an AVI file on Windows. 

The trick here is (well, a) Windows), but more importantly, that 
the AVI will have proper keyframes, which seems to be the problem. 
 All the systems we have played with produce AVIs you CAN'T skip 
through.
BrianH:
9-Jan-2009
Or 'skip.
BrianH:
9-Jan-2009
You are passing a parameter there - it's not the same thing. If we 
allow a none parameter (which we shouldn't), it should mean 'skip.
Group: View ... discuss view related issues [web-public]
Anton:
22-Aug-2005
use SKIP not AT, I think. Let me test...
Geomol:
22-Aug-2005
Using skip here seems to work aswell:

change at image1 5x5 copy/part skip image2 10x10 20x20
Geomol:
22-Aug-2005
Makes me wonder about the difference between 'at' and 'skip'. Both 
are actions.
Geomol:
2-Sep-2005
I can't skip "show canvas" on key-presses, because then you might 
not see the change (e.g. the brush getting larger).
Pekr:
15-Sep-2005
hmm, I would like to know Mike, what actually were you doing? Because 
- in old DBF x-Base days it worked like that - you simply had "cursor" 
at some db position and you moved by using 'skip command .... of 
course even then, it was wise to use indices and to limit the scope 
of data you work with ...
BrianH:
18-Jan-2006
You may notice that Carl doesn't tend to skip the vowels in those 
names either (rebcode notwithstanding).
Geomol:
2-May-2006
>> copy/part skip mold get first [help.gif] 13 5
== "48x48"
(Only works for sizes taking up 5 chars, but it's a start.)
Graham:
3-Jun-2006
this doesn't look at all like it should

translate-draw: func [
	height [integer!]
	blk [block!]
	/local dr p
][

 parse blk [some ['draw set dr block! (parse dr [some [p: pair! (p/1: 
 as-pair p/1/x height - p/1/y) | skip]]) | skip]]
	blk
]

view layout [
	origin 0
	bx: box 400x400 black effect translate-draw 400 [
		draw [
			pen red
			line 50x50 350x50
			pen blue
			line 50x50 50x350
			pen yellow
			line 50x50 100x200 200x150 300x250 350x225
			pen white
			text aliased 10x350 "Y axis"
			text aliased 320x40 "X axis"
		]
	]
]
Group: I'm new ... Ask any question, and a helpful person will try to answer. [web-public]
mhinson:
14-May-2009
so I will add a comma to the end, then parse data [any [ some digit 
#"/" copy result #"," (insert results result) | skip]]
Ladislav:
14-May-2009
not-comma: complement charset ","
copy result any [not-comma | skip]
PeterWood:
14-May-2009
Let's start with 2/ and see how we get on 


>> parse/all inp [ any [copy range "2/" some digit  (print range) 
| skip ]]
2/

2/

2/
PeterWood:
14-May-2009
Let's change the parse rule so that I capture more than just the 
2/:


>> parse/all inp [ any [copy range ["2/" some digit]  (print range) 
| skip ]]
2/2
2/4
2/33

== true
PeterWood:
14-May-2009
You don't need to worry about the commas. skip will take care of 
them.
PeterWood:
14-May-2009
So now I'm capturing the first number after the 2/ but not the range. 
So let's add a little more to the parse rule to capture that:


>> parse/all inp [ any [copy range ["2/" some [digit | "-"]]  (print 
range) | skip ]]                                                 
                         
2/2
2/4-6
2/33-37

== true
PeterWood:
14-May-2009
Now we can change the parse rule to work with 3/. 4 and  /12:


> parse/all inp [ any [copy range [["2/" | "3/" | "4/" | "12/"]  
some digit]  (print range) | skip ]]                             
              
2/2
2/4
2/33
== true
PeterWood:
14-May-2009
This is the amended rule:

>> parse/all inp [ any [copy range [[digit opt digit "/"]  some digit] 
 (print range) | skip ]]                                         
                       
2/2
2/4

2/33

== true
PeterWood:
14-May-2009
Oops I've lost the range again:


>> parse/all inp [ any [copy range [[digit opt digit "/"]  [some 
digit "-" some digit]]  (print range) | skip ]]                  
                             
2/4-6
2/33-37

== true
PeterWood:
14-May-2009
Here's the big rule now fixed :


>> parse/all inp [ any [copy range [[digit opt digit "/"]  [some 
digit opt ["-" some digit]]]  (print range) | skip ]]            
                             
2/2
2/4-6
2/33-37
== true
Steeve:
14-May-2009
rewrote Peter's with named sub-rules

prefix: [digit opt digit]
sufix: [some digit opt ["-" some digit]]
target: [prefix #"/" sufix]

parse/all inp [any [copy range target (print range) | skip]]
PeterWood:
14-May-2009
So now we can capture all the ranges:

>> all-ranges: copy []

== []

 >> parse/all inp [any [copy range target (insert tail all-ranges 
 range) | skip]]

== true
>> all-ranges
== ["2/2" "2/4-6" "2/33-37"]
Steeve:
14-May-2009
digit: charset "0123456789"
alpha: charset [#"a" - #"z" #"A" - #"Z"]

prefix: [1 2 digit]
sufix: [some digit opt ["-" some digit]]
range: [copy range! [prefix #"/" sufix] (prin ["range:" range!])]

rand: [copy rand! [1 4 digit | some alpha] (prin [newline "random:" 
rand!])] 

target: [rand range any [#"," range]]

parse/all inp [some [target | skip]]

is that ok ?
mhinson:
14-May-2009
parse {aaa} any [[here: "a" (print here)] | [skip] ]  does not work 
for how I imagine.. I expect it to return aaa aa a
Maxim:
14-May-2009
note: above should be...

parse "aaa" [any [[here: "a" (print here)] | [skip] ]]
Maxim:
14-May-2009
>> parse "aaa" [any [[here: "a" (print here)] | [skip] ]]
aaa
aa
a
== true
Maxim:
14-May-2009
>> parse "zaz" [any [[here: "a" (print here)] | [skip] ]]
az
== true
Maxim:
14-May-2009
>> parse "zzz" [any [[here: "a" (print here)] | [skip] ]]
== true
mhinson:
14-May-2009
that seems logica, but this does not
 parse {aaa}  [any[here: "a" (print here)] | [skip] ]
aaa
aa
a
mhinson:
14-May-2009
why does it skip in my example?
Maxim:
14-May-2009
in your example, you have two rules, the any only applies to the 
first rule.


 the | skip basically will never be used, cause any will never fail.
Maxim:
14-May-2009
so the any actually didn't fail, and thus the skip never go to do 
its stuff.
Maxim:
14-May-2009
other examples.

 >> parse "aza" [any [here: "a" (print here)] | skip]
aza
== false

>> parse "aza" [any [here: "a" (print here)]  skip skip]
aza
== true
mhinson:
14-May-2009
so why did the parse return false?
>> parse {zzz}  [any[here: "a" (print here)] | [skip] ]
== false
mhinson:
14-May-2009
is it because the skip never get called so the parse is stuck on 
the first position or match & parse needs to move to the tail to 
return true?
Maxim:
14-May-2009
yep.  it hit the "z" stopped (but didn't "fail") so the skip isn't 
reached.
Maxim:
14-May-2009
the second example, both skip ARE evaluated, thus it returns true.
mhinson:
29-May-2009
Hi, I have been trying for the last hour or two to get this code 
to behave in the way I want. 
data: {
thing toy
 owner child
thing house
 owner adult
}

thing: copy []
owner: copy []
StructuredData: copy []

parse/all data [ 
	any [

  ["thing " copy thing to newline (append StructuredData reduce[to-word 
  thing[]])]

  |[" owner " copy owner to newline (append StructuredData/(to-word 
  thing) compose/deep [owner[(owner)]])]
		| skip
	]
]
probe StructuredData

[toy [owner ["child"] owner ["adult"]] house [owner ["child"] owner 
["adult"]]]


My problem is that the toy & the house are owned by the child & the 
adult. It seems the things are linked to each other in a way I dont 
follow.  If I assign the values directly, rather than using the parse, 
then the StructuredData contains what I expect.
[toy [owner ["child"]] house [ owner ["adult"]]]
mhinson:
17-Jun-2009
I have been working on my Parse understanding and came up with this:
parse/all {aX--baX~~a--aX~~} [some
  [
    "a" h: some[ 
      [ 
        ["--" :h copy result to "--" (print result) thru "a" h:]
        |["~~" :h copy result to "~~" (print result) thru "a" h:]
      ] |[skip]
    ]
  ]
]
I am extracting the text between "a" and either "--" or "~~" 

Is my method a reasonable aproach or is there a simpler or more readable 
way to do this sort of thing please?
Ladislav:
17-Jun-2009
here is my way:
parse/all {aX--baX~~a--aX~~} [
	"a"
	some [
	    s:
		any [
		    t: ["--" | "~~"] (result: copy/part s t print result) break
			| skip
		]
		thru "a"
	]
	to end
]
Izkata:
17-Jun-2009
If the empty one doesn't need to be recorded as empty:
parse/all {aX--baX~~a--aX~~} [                             
   some [

      ["a" some ["--" break | "~~" break | X: (print X/1) skip] | skip]
   ]
]
Izkata:
18-Jun-2009
Righto, here's my updated one - good practice for me, too, I rarely 
use parse like this:

parse/all {aX--baX~~a--aX~~aXX~~} [                              
          

   some [                                                           
             

      ["a" S: some [E: ["--" | "~~"] (print copy/part S E) break | skip] 
      | skip] 
   ]
]
Izkata:
21-Jun-2009
The main thing I do is, at some point that happens a lot in the code, 
display the data.  Makes it easier to step through the code and do 
- in your head - what the code is doing.  If it suddenly doesn't 
match up, the loic somewhere was wrong.  For example, when working 
on the last one, I had to debug part of it and did this:

parse/all {aX--baX~~a--aX~~aXX~~} [                              
          

   some [                                                           
             

      ["a" S: (? S) some [E: ["--" | "~~"] (print copy/part S E) break 
      | skip] | skip] 
   ]
]
mhinson:
23-Jun-2009
I seem to be going backwards with learning this. Perhaps I think 
I know the grammer, but don't.

I am trying to write out long hand what I want to do, then convert 
it to a parse, but I dont have any words to describe how parse skips 
back to a previous point, so I cant write what I want to do long 
hand either..  e.g. gather the x in pairs from {fd doixx s x x x 
oie    x }

test for "x" or skip  then when x is found do the same thing but 
escape to the outside loop.   

If I could write the above in a format that made more sense I think 
I would have a better chance of then converting it to a parse.

test for "x" or skip seems to be   ["x" | skip]

doing it twice to get the x in pairs would seem like  ["x" | skip] 
["x" | skip] 

but that dosnt work because it lacks the loop control so I add that 
by a bit of guess work because I dont understand it properly.
parse/all data [some[["x" | skip] ["x" | skip]]]

but this is just completly wrong & I think the reason it is wrong 
is because I have completely misunderstood some or skip or | or where 
the point in the string the parse pointer gets to after each step.... 
 I have tried using OPT & break in the second section but just get 
more muddled.
PeterWood:
23-Jun-2009
Skip tells parse to move to the next item:

>> parse "abcdefghi" ["abcdefgh" skip]
== true   ;; because the skip took us to the end
PeterWood:
23-Jun-2009
We can specify that a sub-rule should be repeated:


>> parse "abcdefghi" ["abcde" 4 skip] 

== true
sqlab:
23-Jun-2009
Maybe these are some variations of what you are looking for


parse/all "fd doixx s x x x oie    x } " [some [copy d   "x" (print 
d) | skip]]


parse/all "fd doixx s x x x oie    x } " [some [copy d 1 2  "x" (print 
d) | skip]]


parse/all "fd doixx s x x x oie    x } " [some [copy d  2  "x" (print 
d) | skip]]


parse/all "fd doixx s x x x oie    x } " [some [copy d   "xx" (print 
d) | skip]]


parse/all "fd doixx s x x x oie    x } " [some [[copy d  "x"  copy 
e  "x" (print [e d]) ] | skip]]


parse/all "fd doixx s x x x oie    x } " [some [ (g: copy "" ) 2 
[copy d  "x"  (append g d)  ]  (print g )  | skip]]
sqlab:
23-Jun-2009
or you are looking for the pairs

 parse/all "fd doixx s x x x oie    x } "  [ some [  [ (g: copy "" 
 ) 2 [ copy d "x"  (append g d ) any notx  | skip  ] (if not empty? 
 g [print g]) ]  ] ]
sqlab:
23-Jun-2009
I forgot notx

notx: complement charset "x"

parse/all "fd doixx s x x x oie    x } "  [ some   [ (g: copy "" 
) 2 [ copy d "x"  (append g d ) any notx  | skip  ] (if not empty? 
g [print g]) ]  ]
mhinson:
23-Jun-2009
this is what I dont expect.

parse/all "fd doixx s x x x oie    x } " [some [copy d   "x" (print 
d) | skip]]
mhinson:
23-Jun-2009
Thanks BrianH, I was sort of guessing it must be like a variation 
of copy thru "x" that does not skip like thru...  I think I get that 
now. Thanks.
mhinson:
23-Jun-2009
This is my nemisis. I can't understand how this prints XXXX then 
XX , not XX  three times.  It seems to have a will of its own.

parse/all { X X  XX X X} [some[[copy x "X" (prin x) [copy y "X" (print 
y) | skip] | skip]]]    
I have been stuck on this (in various forms) for over a week now
BrianH:
23-Jun-2009
parse/all { X X  XX X X} [some [copy x "X" (prin x) [copy y "X" (print 
y) | skip] | skip]]

Character at a time:
- the outer skip
- copy x "X" (prin x)
- the inner skip
- copy x "X" (prin x)
- the inner skip
- the outer skip
- copy x "X" (prin x)
- copy y "X" (print y)
- the outer skip
- copy x "X" (prin x)
- the inner skip
- copy x "X" (prin x)
- the outer skip

Try this:

>> parse/all { X X  XX X X} [some [copy x "X" (prin x) [copy y "X" 
(print y) | skip (prin "i")] | skip (prin "o")]]
oXiXioXX
oXiXo== true
BrianH:
23-Jun-2009
Now that last outer skip seems to me that it should be an inner skip, 
but I am clearly wrong :(
mhinson:
23-Jun-2009
Ah. that is a good trick to print i & o with the skips, this will 
help a lot, thanks.

Isee from your analysis that my error is to expect the inner skip 
to skip back to the beginning of that loop...  not sure why I expected 
that, but it is clearly wrong. I dont know if there is a way to make 
the inner loop behave like that, at an earlier point I did hve OPT 
in front of it...  I will be able to make progress with my experiments 
now armed with the new trick you have taught me, but for now I have 
to go & get some sleep I am afraid.  Thanks again.
BrianH:
23-Jun-2009
>> parse/all { X X  XX X X} [(prin 'a) some [(prin 'b) "X" (prin 
'c) [(prin 'd) "X" (print 'e) | (prin 'f) skip (prin 'g)] (prin 'h) 
| (prin 'i) skip (prin 'j)] (prin 'k)]
abijbcdfghbcdfghbijbcde
hbijbcdfghbcdfijbik== true
sqlab:
24-Jun-2009
regarding 

parse/all "fd doixx s x x x oie    x } " [some [copy d   "x" (print 
d) | skip]]
what did you expect?

If you know what you are looking for you can extend it to


parse/all "fd doixx s x x x oie    x } " [some [copy d   ["x"   | 
"y" | "z" ]    (print d) | skip]]
and you will get your searched values.

But maybe I just don't understand the problem.
mhinson:
24-Jun-2009
I have been reminded that   |skip   is a word  | skip   is OR skip. 
 it is so easy to miss the space between | & skip
mhinson:
24-Jun-2009
Right, I would say that the following snippit is the most educational 
thing I have done with PARSE.  It shows me a lot of things about 
what is happening & validates the construction and use of charsets 
& whatever the 'address block is called.     Thanks everyone for 
your help.

digit: charset [#"0" - #"9"]
address: [1 3 digit "." 1 3 digit "." 1 3 digit "." 1 3 digit]

a: does [prin 'a] b: does [prin 'b] c: does [prin 'c] d: does [prin 
'd] e: does [prin 'e] f: does [prin 'f]
parse/all {1 23 4.5.6.12 222.1.1.1 7 8} [some[

 (a) copy x address (prin x) some[ (b) copy y address break | skip 
 (c)] (print y) | skip (d)
]]
adadadadada4.5.6.12bcb222.1.1.1
Henrik:
8-Oct-2011
so, todun, the general mechanism is that you can store a new index 
of a series, by simply by first move the index and storing the series 
under the same word again:

a: at a 4

This works for BACK, NEXT, AT, SKIP, HEAD, TAIL.

The series will not be modified or copied.


Note that when you COPY, COPY will only copy from the current index 
and forward.


If your index is not at head, HEAD is useful to temporarily reference 
the series from the head, like if you use AT several times in a loop 
or something:

at head a 4
todun:
10-Oct-2011
I tried move/to ; move/skip and even tried backtracking with back 
at every button press, without luck
Group: Parse ... Discussion of PARSE dialect [web-public]
Fork:
28-Dec-2009
>> parse [a b c] [?? copy value thru 1 skip to end]              
            
coo:: [a b c]
== true
Ladislav:
29-Dec-2009
Re the THRU problem: you can use


    parse [1 2 3] [?? while [integer! block! accept | skip | reject] 
    ?? integer!]
Ladislav:
29-Dec-2009
I overlooked, that you used the STRING! datatype:


    parse [1 2 3] [?? while [integer! string! accept | skip | reject] 
    ?? integer!]
Ladislav:
29-Dec-2009
e.g. 

    parse [a b c] [?? copy value thru 1 skip to end]   

should have preferably been

    parse [a b c] [?? copy value 1 skip to end]
Steeve:
31-Dec-2009
any [and skip copy tmp to end]
any [copy tmp [skip to end]]
etc...
Steeve:
31-Dec-2009
I see your point, but what if the ANY block contains production rules 
?

parse "" [any [and skip copy tmp to end break | insert "1" and insert 
"2"]]

(i know, stupid example)
BrianH:
30-Jul-2010
Last block... OPEN/seek perhaps, then SKIP ?
JoshF:
1-Sep-2010
Hi! Quick question about parsing REBOL code itself... I'm putting 
together an entry for a contest which is line-constrained (no more 
than 250 SLOC), so I want to crush my code down as much as possible 
while still having something that actually looks like code (I know 
about using the compression, but I want something that looks like 
a program).


I'm starting with Carl's REBOL parser from the cookbook, but it seems 
to skip the colons for initializers ("x: x + 1" -> [x x + 1]). Here's 
my current hack of his parser:

tokens: copy []
parse read %contest-entry.r blk-rule: [
    some [
        str:
        newline |

        #";" [thru newline | to end] new: (probe copy/part str new) |
        [#"[" | #"("] (append tokens str/1) blk-rule |
        [#"]" | #")"] (append tokens str/1) break |

        skip (set [value new] load/next str  append tokens :value) :new
    ]
]


Any ideas why it might be skipping the vital ":" character? Thanks 
very much!
JoshF:
1-Sep-2010
Hi! Thanks for taking a look at the code. 


I went over it again, it seems that part of the problem was in the 
fact that the parsed objects weren't transliterated into strings 
as I had expected. I.e. if you look at the output of the code snippet 
above, it seems OK, but examination of the types of the data in the 
tokens array turn up things that don't convert to strings too well 
without help. I've puzzled over Carl's pretty printer, and I _think_ 
I understand why now... 


Either way, I was able to modify it to give me the kind of output 
I wanted. To repay you for your kind attention, I will post my code 
here, but in crushed form, so it doesn't take up too much space... 
; - )


REBOL [ Title: "REBOL Compressor" ] emit-space: func [ pos ] [ append 
out pick

[ #" " "" ] found? not any [ find "[(" last out find ")]" first pos 
] ] emit:

func [ from to ] [ emit-space from word: copy/part from to long: 
( length? out )

+ length? word if 80 < long [ append lines out out: copy "" ] append 
out
copy/part from to ] lines: copy [ ] clean-script: func [
Returns new script text with standard spacing.
 script "Original Script text"

/local str new ] [ out: append clear copy script newline parse script 
blk-rule:

[ some [ str: some [ newline ] ( ) | #";" [ thru newline | to end 
] new: ( ) | [

#"[" | #"(" ] ( emit str 1 ) blk-rule | [ #"]" | #")" ] ( emit str 
1 ) break |

skip ( set [ value new ] load/next str emit str new ) :new ] ] append 
lines out

remove lines/1 print [ length? lines "lines." ] lines ] write/lines 
%crushed.r
clean-script read %c.r print read %crushed.r

Thanks!
Gregg:
13-Sep-2010
set 'use-rule func [

    "Create a recursion and thread-safe parse rule with local variables. 
    R2/R3 compatible."
    words [block!] "Local word(s) to the parse rule"
    rule  [block!] "Parse rule"
] [
    make object! [

        ; Create a new function context. 'Inner-body refers to a function 

        ; with access to CONTEXT-FN's context without being influenced 
        ; directly by the context.
        spec: copy [/local]
        append spec words
        inner-body: func ['word] [inner-inner-body word]
        context-fn: func spec reduce [:inner-body first words]
        

        ; Bind the rule the caller gave us to the new context we just created.
        inner-inner-body: func [word] [bind/copy rule word]
        bound-rule: context-fn
        

        ; Now define the use rule. Because this is an "active" rule,
        ; with state we need to include some state variables used
        ; by the internal PARSE call ('pos and 'success).
        pos: none
        success: none
        inner-inner-body: func [word] [

            ; If the parse of the rule succeeds, we set the parse position

            ; to the where the rule match ended, otherwise we don't change

            ; the parse position and use [end skip] to return a false 
            ; result (for R2 compatibility).
            success: either parse pos [bound-rule pos: to end] [
                [:pos]
            ] [
                [end skip]
            ]
        ]
        set 'rule copy/deep [pos: (context-fn) success]
    ]
    rule
]
Gregg:
13-Sep-2010
set 'use-rule func [

    "Create a recursion and thread-safe parse rule with local variables. 
    R2/R3 compatible."
    words [block!] "Local word(s) to the parse rule"
    rule  [block!] "Parse rule"
] [
    make object! [

        ; Create a new function context. 'Inner-body refers to a function 

        ; with access to CONTEXT-FN's context without being influenced 
        ; directly by the context.
        spec: copy [/local]
        append spec words
        inner-body: func ['word] [inner-inner-body word]
        context-fn: func spec reduce [:inner-body first words]
        

        ; Bind the rule the caller gave us to the new context we just created.
        inner-inner-body: func [word] [bind/copy rule word]
        bound-rule: context-fn
        

        ; Now define the use rule. Because this is an "active" rule,
        ; with state we need to include some state variables used

        ; by the internal PARSE call ('pos and 'success). They are used to 
        ; "transfer" the inner parse state to the "outer parse".
        pos: none
        success: none
        inner-inner-body: func [word] [

            ; If the parse of the rule succeeds, we set the parse position

            ; to the where the rule match ended, otherwise we don't change

            ; the parse position and use [end skip] to return a false 
            ; result (for R2 compatibility).
            success: either parse pos [bound-rule pos: to end] [
                [:pos]
            ] [
                [end skip]
            ]
        ]
        set 'rule copy/deep [pos: (context-fn) success]
    ]
    rule
]
Gregg:
13-Sep-2010
set 'use-rule func [

    "Create a recursion and thread-safe parse rule with local variables. 
    R2/R3 compatible."
    words [block!] "Local word(s) to the parse rule"
    rule  [block!] "Parse rule"
] [
    make object! [

        ; Create a new function context. 'Inner-body refers to a function 

        ; with access to CONTEXT-FN's context without being influenced 
        ; directly by the context.
        spec: copy [/local]
        append spec words
        inner-body: func ['word] [inner-inner-body word]
        context-fn: func spec reduce [:inner-body first words]
        

        ; Bind the rule the caller gave us to the new context we just created.
        inner-inner-body: func [word] [bind/copy rule word]
        bound-rule: context-fn
        

        ; Now define the use rule. Because this is an "active" rule,

        ; with state, we need to include some state variables used

        ; by the internal PARSE call ('pos and 'success). They are used to 
        ; "transfer" the inner parse state to the "outer parse".
        pos: none
        success: none
        inner-inner-body: func [word] [

            ; If the parse of the rule succeeds, we set the parse position

            ; to the point where the rule match ended, otherwise we don't 

            ; change the parse position and use [end skip] to return a false 
            ; result (for R2 compatibility).
            success: either parse pos [bound-rule pos: to end] [
                [:pos]
            ] [
                [end skip]
            ]
        ]
        set 'rule copy/deep [pos: (context-fn) success]
    ]
    rule
]
Ladislav:
15-Sep-2010
if you call 'temp a "rebol level variable" in the above example expression, 
how would you call it in the expression below?

(temp: either 1 > 0 [none] [[end skip]]) temp
Steeve:
20-Sep-2010
Much easier with R3.
assuming, 
>> src: {Number : 10017
Name       : Disable Message Partner
Application: MXS
Severity   : Info
Type       : Alarm Event
Date-Time  : 20/09/10 12:39:43
GMT        : Mon Sep 20 10:39:43 2010}

then, 


>> construct parse copy src [return while[and[some #" " #":"] remove[some 
#" "]| skip]]
== make object! [
    Number: "10017"
    Name: "Disable Message Partner"
    Application: "MXS"
    Severity: "Info"
    Type: "Alarm Event"
    Date-Time: "20/09/10 12:39:43"
    GMT: "Mon Sep 20 10:39:43 2010"
]
Gabriele:
5-Nov-2010
basically, as long as you skip over [, (, ), and ] you can just use 
load/next. I'm also skipping over #[ because I want to preserve literal 
values while formatting (that is, preserve what the user typed)
Ladislav:
1-Dec-2010
>> parse [a b "123" c] [2 word! into [3 skip] word!]
== true
Ladislav:
1-Dec-2010
For comparison, a similar rule can be written as follows:

some [
	thru {<h2><a} thru ">" copy name to {<}
	copy doc any [
		and {^/ </div>} break
		| thru {<pre class="code">} copy code to {</pre} (
	          	probe name
	      		probe code
	       	)
			any [
	            thru {<h5>} copy arg to {<}
	            thru {<ol><p>} copy arg-desc to {</p></ol>}
	            (printf ["  * " 10 " - "] reduce [arg arg-desc])
	  		]
  		| skip
	]
]
Oldes:
1-Dec-2010
That's not correct.. there is a reason for the temp parse and that's 
here because thru "<h5" would skip out of the div.
Group: !RebGUI ... A lightweight alternative to VID [web-public]
Pekr:
2-Jan-2006
anton, what is the problem with checksum? It depends on syncing strategy, 
but you have those files on both side (client, server) anyway. afaik, 
the problem with checksum could be its speed. But since we have open/seek, 
we could do checksumming defined,e.g. 3 parts of files, first xy 
bytes, last xy bytes and defined skip somewhere to the middle of 
the file ... dunno if it would work though :-)
Volker:
3-Jan-2006
in read-thru:
        if all [expand find/match data "rebpress"] [

            if error? try [data: decompress skip data 8] [return none]
        ]
Graham:
2-May-2006
down [
								pf: face/parent-face
								either all [ found? pf pf/data <> face/data ][
									;	deflag old
									old: pf/data
									if old [
										clear skip pf/pane/:old/effect/draw 7
										show pf/pane/:old
									]
									;	flag new
									pf/data: face/data

         insert tail face/effect/draw compose [pen (colors/true) fill-pen 
         (colors/true) circle (as-pair sizes/cell * 1.5 sizes/cell * 2.5) 
         (sizes/cell - 1)]
									show face
									pf/action pf
								][ ;; GC

          insert tail face/effect/draw [pen leaf fill-pen leaf circle (as-pair 
          sizes/cell * 1.5 sizes/cell * 2.5) (sizes/cell * 1.5)]
										show face
										face/action face
								]
Graham:
22-Jun-2006
>> display "" [ rg: radio-group data [ "M" "F" ] do [ rg/select-item 
2]]
** Script Error: Cannot use path on none! value
** Where: switch

** Near: if pf/picked <> face/data [old: pf/picked if old [clear 
skip pf/pane/:old/effect/draw 7 show pf/pane/:old] pf/picked
: fa...
Claude:
13-Sep-2006
;BEG propose en new func by Claude 
	remove-all-rows: func[][
		remove/part skip data (length? data) cols
		redraw
	]
	;END
Graham:
8-Dec-2006
just tried it with other words . it causes the locale to skip the 
following word
Group: Rebol School ... Rebol School [web-public]
Gregg:
24-Feb-2009
add-seps: func [
        "Insert group separators"
        str [any-string!]
        /with sep [string! char!]
        /reb "Use REBOL group separator"
    ][
        sep: any [sep all [reb #"'"] #","]
        str: skip any [find str "."  tail str] -3
        while [not head? str] [
            insert str sep
            str: skip str -3
        ]
        str
    ]
Ashley:
6-Aug-2009
Here's a QAD I use:

>> i: 1
== 1
>> join skip "0000" length? form i i
== "0001"
Davide:
12-Mar-2010
I need a small function "my-compose" that takes a blocks, deep search 
tag! values and change it with the value of the word into the tag.
For example, if I have a test function like this:

x: 1
test: func [y /local z] [
	z: 3
	my-compose [ 
		print [ <x> + (<y> + <z>)]
	]
]

Calling:

test 2 

should return:

>> [print 1 + (2 + 3)]

My problem is to do the right bind in the parse:

my-compose: function [code [block!]] [elem rule pos] [
	rule: [any [

  pos: set elem tag! (change/only pos **magical-bind-here** to word! 
  to string! elem ) |		    	
		pos: any-block! :pos into rule |
		skip
	]]
	parse code rule
]
Davide:
12-Mar-2010
Now I'm using this function: 


my-compose: function [code [block!] params [block!]] [elem rule pos 
temp] [
	rule: [any [

  pos: set elem tag! (temp: select params to word! to string! elem 
  if not none? temp [change/only pos temp]) |		    	
		pos: any-block! :pos into rule |
		skip
	]]
	parse code rule    
]

And I call it using:

my-compose [print <x> + (<y> + <z>)] reduce ['x x 'y y 'z z]


It works but the second block is redundant and I would eliminate 
it.
Steeve:
12-Mar-2010
you need to pass the values to map because the formula block only 
contains tag! which basically are strings (tags have no context, 
nor values).
if instead you use get-words as tags, you don't need to.

my-compose: func [code [block!] /local pos][
	parse code rule: [
		any [
			  to get-word! pos: (pos/1: get pos/1) skip 		    	
			| to any-block! into rule
		]
	]
	code
]

>>x: 1
>>y: 2
>>z: 3
>>my-compose [print :x + (:y + :z)]
==[print 1 + (2 + 3)]
Steeve:
12-Mar-2010
Correction:

my-compose: func [code [block!] /local pos][
	parse code rule: [
		any [
			  pos: get-word! (pos/1: get pos/1)
			| into rule
			| skip
		]
	]
	code
]
Claude:
1-Jun-2010
REBOL[]


send: func [
	"Send a message to an address (or block of addresses)"
	;Note - will also be used with REBOL protocol later.
	address [email! block!] "An address or block of addresses"
	message "Text of message. First line is subject."
	/only   "Send only one message to multiple addresses"
	/header "Supply your own custom header"
	header-obj [object!] "The header to use"
	/attach "Attach file, files, or [.. [filename data]]"
	files [file! block!] "The files to attach to the message"
	/subject "Set the subject of the message"
	subj "The subject line"
	/show "Show all recipients in the TO field"
	/local smtp-port boundary make-boundary tmp from
][
	make-boundary: does []

	if file? files [files: reduce [files]] ; make it a block
	if email? address [address: reduce [address]] ; make it a block
	message: either string? message [copy message] [mold message]

	if not header [                 ; Clone system default header
		header-obj: make system/standard/email [

   subject: any [subj copy/part message any [find message newline 50]]
		]
	]
	if subject [header-obj/subject: subj]
	either none? header-obj/from [

  if none? header-obj/from: from: system/user/email [net-error "Email 
  header not set: no from address"]
		if all [string? system/user/name not empty? system/user/name][
			header-obj/from: rejoin [system/user/name " <" from ">"]
		]
	][
		from: header-obj/from
	]
	if none? header-obj/to [
		header-obj/to: tmp: make string! 20
		if show [
			foreach email address [repend tmp [email ", "]]
			clear back back tail tmp
		]
	]
	if none? header-obj/date [header-obj/date: to-idate now]

	if attach [

  boundary: rejoin ["--__REBOL--" system/product "--" system/version 
  "--" checksum form now/precise "__"]
		header-obj/MIME-Version: "1.0"

  header-obj/content-type: join "multipart/mixed; boundary=" [{"} skip 
  boundary 2 {"}]
		message: build-attach-body message files boundary
	]

	;-- Send as an SMTP batch or individually addressed:
	smtp-port: open [scheme: 'esmtp]
	either only [ ; Only one message to multiple addrs
		address: copy address
		; remove non-email values
		remove-each value address [not email? :value]

  message: head insert insert tail net-utils/export header-obj newline 
  message
		insert smtp-port reduce [from address message]
	] [
		foreach addr address [
			if email? addr [
				if not show [insert clear header-obj/to addr]

    tmp: head insert insert tail net-utils/export header-obj newline 
    message
				insert smtp-port reduce [from reduce [addr] tmp]
			]
		]
	]
	close smtp-port
]

resend: func [
	"Relay a message"
	to from message /local smtp-port
][
	smtp-port: open [scheme: 'esmtp]
	insert smtp-port reduce [from reduce [to] message]
	close smtp-port
]

build-attach-body: function [
	{Return an email body with attached files.}
	body [string!] {The message body}

 files [block!] {List of files to send [%file1.r [%file2.r "data"]]}
	boundary [string!] {The boundary divider}
][
	make-mime-header
	break-lines
	file
	val
][
	make-mime-header: func [file] [
		net-utils/export context [

   Content-Type: join {application/octet-stream; name="} [file {"}]
			Content-Transfer-Encoding: "base64"

   Content-Disposition: join {attachment; filename="} [file {"^/}]
		]
	]
	break-lines: func [mesg data /at num] [
		num: any [num 72]
		while [not tail? data] [
			append mesg join copy/part data num #"^/"
			data: skip data num
		]
		mesg
	]
	if not empty? files [
		insert body reduce [boundary "^/Content-type: text/html^/^/"]
		append body "^/^/"
		if not parse files [
			some [
				(file: none)
				[
					set file file! (val: read/binary file)
					| into [
						set file file!
						set val skip ;anything allowed
						to end
					]
				] (
					if file [
						repend body [
							boundary "^/"
							make-mime-header any [find/last/tail file #"/" file]
						]
						val: either any-string? val [val] [mold :val]
						break-lines body enbase val
					]
				)
			]
		] [net-error "Cannot parse file list."]
		append body join boundary "--^/"
	]
	body
]
Andreas:
12-Jul-2011
Henrik, I think here's your "internals" documentation:


http://en.wikipedia.org/wiki/Parsing_expression_grammar#Definition


(Esp. skip ahead to the "Operational interpretation of parsing expressions" 
section.) It's linked to from the "Parse" documentation Ladislav 
gave above.
Sunanda:
11-Aug-2011
That may not always give you what you'd expect  if the strings have 
embedded spaces:

    replace/all reform ["id" "last name" "address" "city"] " " ","
    == "id,last,name,address,city"

This may work better in that situation:

    skip head remove back tail remove back tail  replace/all mold ["id" 
    "last name" "address" "city"]  {" "} ","  2
Gregg:
11-Aug-2011
; A dialected version of this could be very flexible; allowing more
    ; than just fixed size groupings.

    ; This could also be done by adding a /SKIP refinement to INSERT.
    delimit: func [
        ;[throw catch]
        "Insert a delimiter between series values."
        series [series!] "Series to delimit. Will be modified."
        value            "The delimiter to insert between items."

        /skip   ;<-- be sure to use system/words/skip in this func

            size [integer!] "The number of items between delimiters. Default 
            is 1."
    ][

        ; Hmmm, I wonder if we could extend the function spec dialect

        ; to include constraints like this declaratively? And should

        ; we trap the arg like this, or just use MAX to make sure we

        ; have a positive value? I think I'll do the latter for now,
        ; but leave this here as a comment.
        ;if all [size not positive? size] [
        ;    throw make error! join [script invalid-arg] size
        ;]
        ; By default, delimiters go between each item.
        ; MAX catches zero and negative sizes.
        size: max 1 any [size 1]

        ; If we aren't going to insert any delimiters, just return the series.

        ; This check means FORSKIP should always give us a series result,
        ; rather than NONE, so we can safely inline HEAD with it.
        if size + 1 > length? series [return series]
        ; We don't want a delimiter at the beginning.
        series: system/words/skip series size

        ; Use size+n because we're inserting a delimiter on each pass,

        ; and need to skip over that as well. If we're inserting a

        ; series into a string, we have to skip the length of that

        ; series. i.e. the delimiter value is more than a single item
        ; we need to skip.
        size: size + any [

            all [list? series  0] ; lists behave differently; no need to skip 
            dlm.

            all [any-string? series  series? value  length? value]
            all [any-string? series  length? form value]
            1
        ]
        head forskip series size [insert/only series value]
    ]
GrahamC:
5-Oct-2011
You should be able to open/direct, skip to the end and write a space 
or null to the end
601 / 1228123456[7] 8910111213