[REBOL] Re: Antwort: Re: Antwort: Switch! (LONG)
From: brett:codeconscious at: 22-Nov-2000 0:06
> > That means I just have to parse the <title> tag contents of all the
files
> > in a given directory and pass it as "some-pagerefs" items ?
> Hmm. Well if you did you would certainly get a page generated but the
hrefs
> would not be valid. I didn't actually cater for the titles and the
> corresponding files - sorry. I'll have a quick look and probably post
> something in a little while that does.
Well, I had a look. I decided to make a few changes.
(1) I'm going to change the structure of the data in the blocks that gets
sent to write-my-page function.
(2) In order to cope with this both generate-my-page will have to be changed
and index-some-data will have to be changed.
generate-my-page has two lines changed - the ones that refer to "pageref"
index-some-data has two new words added to it "indexing-value" and
indexing-function
. Compare the code with the original to see how the
changes.
I decided to allow the index-some-data function to accept a function as an
argument. This mean that I give it a new refniement that takes a custom
function as an argument. This custom function will determine how
index-some-data does its indexing. It sounds complicated but it isn't too
bad. Just understand that a function is also a value in Rebol. Why did I do
this? Because the data we pass to it will have a new structure. I quite
liked the functionality of the previous version of index-some-data so I
decided to handle both these cases. So now index-some-data is a little more
useful - it is not limited to indexing by the first character. I can define
a function that indexes by something else.
For example, now I can do this
; same result as before (first is my default indexing function)
>> index-some-data [9-jun-2000 10-jun-2000 13-feb-2001 27-feb-2003]
== [2000 [9-Jun-2000 10-Jun-2000] 2001 [13-Feb-2001] 2003 [27-Feb-2003]]
; now I define a function that returns a day given a date - and pass
this function as an argument
>> index-some-data/by [9-jun-2000 10-jun-2000 13-feb-2001 27-feb-2003]
(func[x][x/day])
== [9 [9-Jun-2000] 10 [10-Jun-2000] 13 [13-Feb-2001] 27 [27-Feb-2003]]
; now I define a function that returns a month given a date - and pass
this function as an argument
>> index-some-data/by [9-jun-2000 10-jun-2000 13-feb-2001 27-feb-2003]
(func[x][x/month])
== [6 [9-Jun-2000 10-Jun-2000] 2 [13-Feb-2001 27-Feb-2003]]
For your problem I'll create one that returns the first character of the
title. It reaches into the item block and gets it.
Ok here's the wash up.
REBOL [
Author: "Brett Handley"
Title: "Learning the value of functions :)"
Note: {This script has been developed for
illustrative purposes only. I leave it to
you to determine the fitness of this script
to any specific use you have.}
]
; A function that generates a single html page as a string.
generate-my-page: function [
page-reference
some-pagerefs [block!]
] [html-page] [
html-page: copy {}
append html-page reduce [<h1> "This is page " page-reference </h1>]
foreach pageref some-pagerefs [
append html-page <p>
append html-page build-tag reduce ['a 'href pageref/2]
append html-page pageref/1
append html-page [</a> </p>]
]
RETURN html-page
]
; A function that writes an single html page.
write-my-page: function [
page-reference
some-pagerefs [block!]
] [page-string] [
page-string: generate-my-page page-reference some-pagerefs
insert head page-string "<HTML><BODY>"
insert tail page-string "<p><b>Generated by Rebol</b></p></BODY></HTML>"
write (join %test-page- [page-reference %.html]) page-string
]
index-some-data: function [
data [series!]
/by indexing-function [function!]
"A function that returns the indexing data given a data item"
] [
index-block data-block result-block
indexed-item index-number
indexing-value
] [
; Set the default indexing function to the "first" function
if not by [
; Set the value of the word "indexing-function" to be that
; of the word "first".
indexing-function: :first
]
; Create the blocks
index-block: copy []
data-block: copy []
; Index all the items in the data.
foreach item data [
; Apply the indexing function to the item to get the value to index
by.
indexing-value: indexing-function item
either indexed-item: find index-block indexing-value [
; Yippe - there is an entry for this - just add it to the list
index-number: index? indexed-item
insert/only tail (pick data-block index-number) item
] [
; Not-found we'll have to add it and a new list.
insert tail index-block indexing-value
insert/only tail data-block reduce [item] ;item inside a new
block
]
]
; Now reformat to make a nice result.
; We just merge the two blocks in order.
result-block: make block! (multiply 2 length? index-block)
for index-number 1 length? index-block 1 [
append result-block (pick index-block index-number)
append/only result-block (pick data-block index-number)
]
; Drumroll...
RETURN result-block
]
; Main script
sample-data: [
["Episode1" %eps1.html ]
["Empire Strikes Back" %empire.html]
["True Lies" %truelies.html]
["Terminator 2" %termy2.html]
["Priscilla" %queen.html]
]
; Define a custom function to pick just the first character of the title.
Call the
; index-some-data function using the custom function as a parameter.
indexed-data: index-some-data/by sample-data (func[item][first item/1])
; Generate and write all the pages.
foreach [char list] indexed-data [
write-my-page char list
]