;-- collect-based EXCERPT ----------------------------------
; Could also change EXTRACT to accept a block value for WIDTH
; (renamed to, e.g., SPEC).
; The dialect allows you to use commas in the block, but how they
; are interpreted is not how you might think. Coming after a number,
; they are a valid lexical form, but they denote a decimal! rather
; than being seen as a separator, which means you can't use them too
; flexibly.
excerpt: func [
{Returns the specified items and/or ranges from the series.}
series [series!]
offsets [block!] {Offsets of the items to extract; dialected.}
/only "return sub-block ranges as blocks"
/local
emit-range rules
from* to* index* ; parse vars
][
; always uses ONLY right now; it's a prototype.
collect/only val [
emit-range: func [start end] [
start: to integer! start
if number? end [end: to integer! end - start + 1]
val: either end = 'end [copy at series start][
copy/part at series start end
]
]
rules: [
some [
opt 'from set from* number! 'to set to* number! (
emit-range from* to*
)
| opt 'from set from* number! 'to 'end (emit-range from* 'end)
| 'to set to* number! (emit-range 1 to*)
| set index* number! (val: pick series index*)
| into rules
]
]
parse offsets rules
]
]
comment {
b: [1 2 3 4 5 6 7 8 9 10 11 12 13 14]
excerpt b [1 3 5]
excerpt b [1 3 to 6 8]
excerpt/only b [1, 3 to 6, 8]
excerpt b [1 [5 to 7] 8]
excerpt/only b [1 (from 5 to 7) 8]
excerpt b [(to 2) [4 to 6] 8, 10, from 12 to end]
excerpt/only b [to 2, 4 to 6, 8, 10, (12 to end)]
; Can't use a comma after 'end
excerpt/only b [to 2 to 6 8 10 to end 12 to end]
excerpt/only b [to 2, to 6, 8 [10 to end] 12 to end]
excerpt/only trim {
REBOL is my favorite language
} [
to 5, 10 to 11, 13, 14, 15, 22 to end
]
excerpt/only to binary! {REBOL is my favorite language} [
to 5, 10 to 11, 13, 14, 15, 22 to end
]
}
You need to create an account or log in to post comments to this site.