Switch!
[1/17] from: sharriff::aina::med-iq::de at: 19-Nov-2000 5:07
Hi REBOL-List!
given this code snippet::
titles: ["Akne" %basis14.htm " Alkoholischer Leberschaden" %basis15.htm "
Alzheimer" %basis16.htm ]
foreach [x y] titles [ switch second :x [
#"a" [either exists? %a.html [save %a.txt
test
][print "a.html exists!"]]
#"b" [ print "do that"]
#"c" []
#"d" [print "hoo" ]
#"e" [print "gotcha"]
#"f" []
#"g" []
#"h" []
#"i" []
#"j" []
#"k" []
#"l" []
#"m" []
#"n" [print "bogey"]
#"o" [print "stark"]
#"p" [Print "balloo"]
#"q" []
#"r" []
#"s" []
#"t" []
#"v" []
#"v" []
#"w" []
#"x" []
#"y" []
#"z" []]]
If the block "titles" is not too big (30-40 entries) the snippet runs fine,
but the actual list generates more than 180 enties, the script runs but I
get this error:
** Script Error: Out of range or past end.
** Where: switch second :x [
Can someone tell me what is wrong?
Sharriff Aina
med.iq information & quality in healthcare AG
[2/17] from: al:bri:xtra at: 19-Nov-2000 20:01
Sharriff wrote:
> If the block "titles" is not too big (30-40 entries) the snippet runs
fine, but the actual list generates more than 180 entries, the script runs
but I get this error:
> ** Script Error: Out of range or past end.
> ** Where: switch second :x [
>
> Can someone tell me what is wrong?
There's something wrong with your big block pointed to by 'titles. Perhaps
one of the titles only has one letter in it? After all, this statement:
second :x
uses the "second" letter of the strings, rather than the first. It
should really be:
first x
You also don't need the ":" on 'x as it looks like you're switching on
strings only. You've got some extra space in your strings, so 'trim it off.
Like:
first trim x
But that's in the wrong place. The code that generates the block should
have trimmed it off in the first place and done it's job correctly.
> #"z" []]]
Plus, there's an awfully lot of space in the above line! Wouldn't just one
tab or four spaces do?
Also, why use 'x and 'y as names? Why not 'heading and 'file? Or something
else more descriptive?
I hope that helps!
Andrew Martin
Being right for a change...
ICQ: 26227169
http://members.nbci.com/AndrewMartin/
-><-
[3/17] from: al:bri:xtra at: 19-Nov-2000 20:21
For why this:
> foreach [x y]
is bad, check out:
http://c2.com/cgi/wiki?MeaningfulNames
Andrew Martin
ICQ: 26227169
http://members.nbci.com/AndrewMartin/
[4/17] from: brett:codeconscious at: 20-Nov-2000 11:26
Hi Sharriff,
Maybe one of your titles is only one character is length or is empty?
Brett.
>> second "ab"
== #"b"
>> second "a"
** Script Error: Out of range or past end.
** Where: second "a"
Brett.
[5/17] from: sharriff:aina:med-iq at: 20-Nov-2000 7:25
Thanks Andrew!
Sharriff Aina
med.iq information & quality in healthcare AG
"Andrew
Martin" An: <[rebol-list--rebol--com]>
<[Al--Bri--xtra]. Kopie:
co.nz> Thema: [REBOL] Re: Switch!
Gesendet von:
rebol-bounce@
rebol.com
19.11.00
20:21
Bitte
antworten an
rebol-list
For why this:
> foreach [x y]
is bad, check out:
http://c2.com/cgi/wiki?MeaningfulNames
Andrew Martin
ICQ: 26227169
http://members.nbci.com/AndrewMartin/
[6/17] from: sharriff:aina:med-iq at: 20-Nov-2000 7:31
On the spot Brett, Andrew also hinted at this, I´ve corrected the code to
cater for this situation
Thanks!
Sharriff Aina
"Brett Handley"
<[brett--codecons] An: <[rebol-list--rebol--com]>
cious.com> Kopie:
Gesendet von: Thema: [REBOL] Re: Switch!
[rebol-bounce--re]
bol.com
20.11.00 00:26
Bitte antworten
an rebol-list
Hi Sharriff,
Maybe one of your titles is only one character is length or is empty?
Brett.
>> second "ab"
== #"b"
>> second "a"
** Script Error: Out of range or past end.
** Where: second "a"
Brett.
[7/17] from: sharriff:aina:med-iq at: 20-Nov-2000 7:52
I´m almost there Brett. Michael, Andrew
although I´ve solved the problem using some extensive code, I wonder if
there is a cleaner or shorter way to do this (see code below)
; creates subindexes from the first characters
foreach [title file] titles [
switch first title [
#"a" [clear sub-list
; temp-html: copy sub-toc-html-template
append sub-list rejoin [{<a href="} file {" target
="touchscreencontent"><img src="./images/round-button.jpg" border="0" />
}title {</a>}]
append temp-html newline
append temp-html sub-list
append temp-html sub-toc-html-stub
write/append %aa.html temp-html]
#"b" [clear sub-list
; temp-html: copy sub-toc-html-template
append sub-list rejoin [{<a href="} file {" target
="touchscreencontent"><img src="./images/round-button.jpg" border="0" />
}title {</a>}]
append temp-html newline
append temp-html sub-list
append temp-html sub-toc-html-stub
write/append %bb.html temp-html]
and so on and so forth.....to character Z
the links to the files and buttons are added correctly, but the tags of the
HTML template are added also too, so the files (%aa.html, %bb.html e.t.c)
end up having multiple <head>, <body> <title> e.tc. tags. How do code a
method to execute only once in this situation?
The way I´ve solved it atthe moment is to define alphabet blocks at the
moment with the top of the HTML template in them and upon an occuring
switch, the links get added to the respective alphabet blocks. The alphabet
blocks are then written one by one to disk.
I´m not sure if the script is economical with memory,( i´ve defined more
than 20 blocks!) I would like than one of you should look it over, but it
so large and I think it might be impolite to post it here.
Thanks in advance
Sharriff Aina
[8/17] from: al:bri:xtra at: 20-Nov-2000 22:02
This should be a function:
> ; temp-html: copy sub-toc-html-template
> append sub-list rejoin [{<a href="} file {" target
<<quoted lines omitted: 4>>
> append temp-html sub-toc-html-stub
> write/append %aa.html temp-html]
Repeat 26 times after me, "Write everything once and only once".
Letter: function [Text [string!] File [file!]] [Page][
Page: copy sub-toc-html-template
; your code here...
]
Andrew Martin
ICQ: 26227169
http://members.nbci.com/AndrewMartin/
[9/17] from: sharriff:aina:med-iq at: 20-Nov-2000 9:22
Thanks Andrew
I ´ll take a look at the Wiki in a short while. Excuse me for being slow,
but I don´t understand why I have to pass a file as an argument, and I dont
know how to cater for the case of multiple links? I´ve coded something like
this to break out of this problem
--------------------------------------------------
these lines at the beginning
; ----------- containers for the final sub HTML files
a: copy sub-toc-html-template
;creates subindexes from the first characters
foreach [title file] titles [
switch first title [
#"a" [clear sub-list
; temp-html: copy sub-toc-html-template
append sub-list rejoin [{<a href="} file {" target
="touchscreencontent"><img src="./images/round-button.jpg" border="0" />
}title {</a>}]
append a newline
append a sub-list]
and so on till #"z"
then these lines follow:
; ----------- code lines that creates the individual sub-TOC pages
append a sub-toc-html-stub
write %aa.html a
and so on for every letter
I´ve done it this way so that I can iterate for every occurence of a title
with with the same character. This is appended to a block (a: [] for
example) containing the the top of the template, the links are added to the
middle and the end of the template is appended and the file is then
written.
step 1: sub-toc-html-template
step 2: add all found tiltes and links
step 3: append sub-toc-html-stub
step 4: write to disk
could you show me how to implement your function to piece together the
links and HTML template together?
Much thanks
Sharriff Aina
"Andrew
Martin" An: <[rebol-list--rebol--com]>
<[Al--Bri--xtra]. Kopie:
co.nz> Thema: [REBOL] Re: Antwort: Switch!
Gesendet von:
rebol-bounce@
rebol.com
20.11.00
22:02
Bitte
antworten an
rebol-list
This should be a function:
> ; temp-html: copy sub-toc-html-template
> append sub-list rejoin [{<a href="} file {" target
<<quoted lines omitted: 4>>
> append temp-html sub-toc-html-stub
> write/append %aa.html temp-html]
Repeat 26 times after me, "Write everything once and only once".
Letter: function [Text [string!] File [file!]] [Page][
Page: copy sub-toc-html-template
; your code here...
]
Andrew Martin
ICQ: 26227169
http://members.nbci.com/AndrewMartin/
[10/17] from: al:bri:xtra at: 20-Nov-2000 21:56
> I´m almost there Brett. Michael, Andrew although I´ve solved the problem
using some extensive code, I wonder if there is a cleaner or shorter way to
do this (see code below)
See:
http://c2.com/cgi/wiki?OnceAndOnlyOnce
Andrew Martin
I shall say zis only once...
ICQ: 26227169
http://members.nbci.com/AndrewMartin/
[11/17] from: al:bri:xtra at: 20-Nov-2000 23:04
These lines:
> [clear sub-list
> ; temp-html: copy sub-toc-html-template
<<quoted lines omitted: 3>>
> append a newline
> append a sub-list]
are in a block. What's in a block can be put into a function. For
example:
A-function: func [][
clear sub-list
temp-html: copy sub-toc-html-template
append sub-list rejoin [
{<a href="} file {" target =" touchscreencontent">
<img src="./images/round-button.jpg" border="0" />
}title {</a>}
]
append a newline
append a sub-list
]
Repeat for a total of 26 times.
Notice that these 26 functions have duplicated words inside them. The parts
that are different about each function can be supplied as values for the
function. For example:
Michelle: func [a] [
append a reduce [
"." newline "This is on the end of a."
]
]
>> Michelle "I shall say zis only once"
== {I shall say zis only once.
This is on the end of a.}
Andrew Martin
It grows late...
ICQ: 26227169
http://members.nbci.com/AndrewMartin/
[12/17] from: brett::codeconscious::com at: 21-Nov-2000 1:50
Re: Antwort: Switch! (LONG)
Hi Sharriff,
First off, read Andrew's post that quotes Michelle "I shall say zis only
once", then come back to this post.
I assume that you do not have a deadline that you are about to get deaded by
:) If you do, mention it.
That said, lets break down your problem again. Here's how I see it:
you need to index your files by a character
you need to generate an html page for each index
So far your script tries to do both things at once, and I think this makes
it more complex. That is why you needed the switch statement and the /append
refinement to the write function.
Let's look at the second part of your problem - generating the pages. Here's
a contrived example
; A function that generates a single html page as a string.
generate-my-page: function [
page-number
some-pagerefs [block!]
][html-page][
html-page: copy {}
append html-page reduce [<h1> "This is page " page-number </h1>]
foreach pageref some-pagerefs [
append html-page <p>
append html-page build-tag reduce ['a 'href pageref]
append html-page pageref
append html-page [</a> </p>]
]
RETURN html-page
]
; A function that writes an single html page.
write-my-page: function [
page-number
some-pagerefs [block!]
][page-string][
page-string: GENERATE-MY-PAGE page-number 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-number %.html]) page-string
]
; Main script
write-my-page 1 ["test-page-2.html" "test-page-3.html"]
write-my-page 2 ["test-page-3.html"]
write-my-page 3 ["test-page-3.html" "test-page-2.html" "test-page-1.html"]
I could have had one function do what generate-my-page and write-my-page is
doing. But I wanted to demonstrate how powerful nested functions can be. In
this case write-my-page calls generate-my-page to make the body of each
page. write-my-page then adds the html and body tags around it and adds the
Generated by Rebol
message. It finally writes the page by calculating a
file name.
Ok next problem, indexing by the first character. The hardest part is
working out how to store your results so that you can use them with the
other function (above). To keep things straight forward I'll use two blocks.
The first block (index-block) will be the characters the second block
(data-block) is a block of blocks - one block for each character that will
store all the items. I'll create a function that will build these two blocks
from data given to it. But, before the function returns the result it will
make a single block of that interleaves the first two blocks. Why? - it
makes it easy to use a foreach [col1 col2] later.
Here is the function. Admittedly it looks intimidating to start with, but I
think it becomes clear with a little study. If not, yell :)
index-some-data: function [
data [series!]
] [
index-block data-block result-block
indexed-item index-number
] [
; Create the blocks
index-block: copy []
data-block: copy []
; Index all the items in the data.
foreach item data [
either indexed-item: find index-block first item [
; 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
] [
; It wasn't found - we'll have to add it and add new list
too.
; Note that it is critical that we add to both blocks in the
same order.
insert tail index-block first item
insert/only tail data-block reduce [item] ;item inside a new
block
]
]
; Well everything is indexed now.
; We will 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)
]
; Drum roll...
RETURN result-block
]
I can now use this function with the others to do something quite powerful.
foreach [char file-list] index-some-data read %. [
write-my-page char file-list
]
Which is probably fairly close to what you want to do.
How did we get here?
(1) Seperated the tasks we needed to do.
(2) Created functions for these tasks and a data structure that would
communicate effectively between the functions.
There was nothing wrong in with your solution of one script that chugs
through the data appending as it went to the appropriate file. Indeed that
might be an optimal solution for some applications. I wanted to show how a
more structured approach can help solve the problem by breaking it into
smaller (more achievable) pieces. The other interesting point is that my
index function is not only useful for this problem, but is quite possibly
useful for other problems too. Actually write-my-page might be handy
elsewhere as well. That is what functions are good at.
>> index-some-data ["here" "are" "some" "strings"]
== [#"h" ["here"] #"a" ["are"] #"s" ["some" "strings"]]
>> index-some-data [10-jun-2000 11-aug-2001 2-feb-2000 31-dec-2002]
== [2000 [10-Jun-2000 2-Feb-2000] 2001 [11-Aug-2001] 2002 [31-Dec-2002]]
Brett.
It's grown late here too :)
----- Original Message -----
From: <[Sharriff--Aina--med-iq--de]>
To: <[rebol-list--rebol--com]>
Sent: Monday, November 20, 2000 6:52 PM
Subject: [REBOL] Antwort: Switch!
I´m almost there Brett. Michael, Andrew
although I´ve solved the problem using some extensive code, I wonder if
there is a cleaner or shorter way to do this (see code below)
; creates subindexes from the first characters
foreach [title file] titles [
switch first title [
#"a" [clear sub-list
; temp-html: copy sub-toc-html-template
append sub-list rejoin [{<a href="} file {" target
="touchscreencontent"><img src="./images/round-button.jpg" border="0" />
}title {</a>}]
append temp-html newline
append temp-html sub-list
append temp-html sub-toc-html-stub
write/append %aa.html temp-html]
#"b" [clear sub-list
; temp-html: copy sub-toc-html-template
append sub-list rejoin [{<a href="} file {" target
="touchscreencontent"><img src="./images/round-button.jpg" border="0" />
}title {</a>}]
append temp-html newline
append temp-html sub-list
append temp-html sub-toc-html-stub
write/append %bb.html temp-html]
and so on and so forth.....to character Z
the links to the files and buttons are added correctly, but the tags of the
HTML template are added also too, so the files (%aa.html, %bb.html e.t.c)
end up having multiple <head>, <body> <title> e.tc. tags. How do code a
method to execute only once in this situation?
The way I´ve solved it atthe moment is to define alphabet blocks at the
moment with the top of the HTML template in them and upon an occuring
switch, the links get added to the respective alphabet blocks. The alphabet
blocks are then written one by one to disk.
I´m not sure if the script is economical with memory,( i´ve defined more
than 20 blocks!) I would like than one of you should look it over, but it
so large and I think it might be impolite to post it here.
Thanks in advance
Sharriff Aina
[13/17] from: sharriff:aina:med-iq at: 20-Nov-2000 15:34
Thanks Brett!
Speaking of a deadline, the indexer is supposed to produce index pages
tommorow!!! for an application thats going to be used in a exibition, my
boss was a little worried, but I finished coding this morning 3.00AM, I
would definately have to recode it after the exibition according to your
examples. I just went through your code (have to prepare a lot of things
for the exibition) and saw directly that your code would need thorough
study.
I apologise if this very big script has annoyed anyone, but I am curious to
see how way off I was with my code.
Thanks Brett and Andrew for the kick in the right direction.
The indexer, an index CGI utility for indexing HTML for a touchscreen
application
#!c:\rebol\rebol.exe -cs
REBOL []
Print "Content-Type: text/html ^/^/"
; code to decode the HTML form comes here!!
; ------------- initialize containers
toc-list: make block! 0
temp-block:make block! 0
title-list: make block! 0
file-list: make block! 0 ; contains the raw files
sorted-files: make block! 0 ; finally contains only HTML/HTM files
file-dir: make block! 0
sub-list: make block! 0 ; contains links to sublists
titles: make block! 0 ; contains Titles and file names
char-list: make block! 0
finished-links: make block! 0
temp-html: make block! 0
; ------------------------- individual sub list container blocks
a: make block! 0
b: make block! 0
c: make block! 0
; all the way to Z......
z: make block! 0
; ----------------------- sub TOC HTML template
sub-toc-html-template: {
<html>
<head>
<style type="text/css">
a {font-family: Verdana; font-size: 18pt}
h2 { font-family: Verdana; font-size: 12pt}
h3.c1 {font-family: Verdana}
p {font-family: Verdana,Tahoma,Arial,Helvetic; font-size: 15pt}
td {font-family: Verdana; font-size: 18pt}
body {background-color: #FFFFE0}
</style>
<title> Sub-TOC </title>
</head>
<body>
<table border="0 cellpadding="0" cellspacing="2" width="700">}
sub-toc-html-stub: {
</tr>
</table>
</body>
</html>}
; ----------- containers for the final sub HTML files
a: copy sub-toc-html-template
b: copy sub-toc-html-template
;...... all the way to Z, you must have guessed by now!
z: copy sub-toc-html-template
;----------------- Code begin --------------
;___________________________________________
;----------------- function for user directory selection
select-dir: func [ module-name ] [prefix: "../medintouch/modules/"
change-dir (to-file join prefix
user-dir)]
either exists? toc.html [ write %toc.html main-html-toc][print "ERROR! TOC
is missing"]
; read and store all files in "file-list"
file-list: read sort %./
; selects all HTML or HTM files and stores them in a separate list
foreach file file-list [either find/any file ".ht?" [append sorted-files
:file][save %non-html-files.txt :file]]
; parse the titles from the html and htm files and store the titles
;foreach file sorted-files [temp-file: read file
; parse temp-file [any [thru "<title>" copy
title-list to "</title>"] to end]
; append titles title-list
; append titles file]
; taking care of medintouch version bug (bad HTML)
foreach file sorted-files [temp-file: read file
parse temp-file [any [thru "<title>
Patienteninformierung zu" copy title-list to "</title>"] to end]
append titles title-list
append titles file]
; creates subindexes from the first characters
foreach [title file] titles [
switch second title [
#"a" [clear sub-list
; temp-html: copy sub-toc-html-template
append sub-list rejoin [{<tr><td>}{<a href="} file {" target
="touchscreencontent"><img src="./images/round-button.jpg" border="0" />
}title {</a>}{</td><td> </td>}]
append a newline
append a sub-list]
#"b" [clear sub-list
; temp-html: copy sub-toc-html-template
append sub-list rejoin [{<tr><td>}{<a href="} file {" target
="touchscreencontent"><img src="./images/round-button.jpg" border="0" />
}title {</a>}{</td><td> </td>}]
append b newline
append b sub-list]
#"c" [clear sub-list
; temp-html: copy sub-toc-html-template
append sub-list rejoin [{<tr><td>}{<a href="} file {" target
="touchscreencontent"><img src="./images/round-button.jpg" border="0" />
}title {</a>}{</td><td> </td>}]
append c newline
append c sub-list]
; all the way to Z.------------
#"z" [clear sub-list
; temp-html: copy sub-toc-html-template
append sub-list rejoin [{<tr><td>}{<a href="} file {" target
="touchscreencontent"><img src="./images/round-button.jpg" border="0" />
}title {</a>}{</td><td> </td>}]
append z newline
append z sub-list]]]
; ----------- code lines that creates the individual sub-TOC pages
append a sub-toc-html-stub
write %aa.html a
append b sub-toc-html-stub
write %bb.html b
; all the way to Z....
This script takes a directory of HTML pages, extracts the titles and
creates an index page of links for each alphabet.. The pages are used in
a touchscreen application.
Sharriff Aina
med.iq information & quality in healthcare AG
[14/17] from: brett:codeconscious at: 21-Nov-2000 22:16
> I just went through your code (have to prepare a lot of things
> for the exibition) and saw directly that your code would need thorough
> study.
...
> The indexer, an index CGI utility for indexing HTML for a touchscreen
> application
I didn't realise you were doing this for CGI. Accordingly, I'm not sure if
my example code has any issues that would be CGI unfriendly. I can't check
myself because I haven't had the experience yet between Rebol and CGI to
know for sure either way.
Brett.
[15/17] from: sharriff:aina:med-iq at: 21-Nov-2000 11:13
Hi Brett!
You said "Yell", well I´m yelling!
"result-block: make block! (multiply 2 length? index-block)!
could you tell me why you initialized the block in this form? I´ve noticed
that you pass references to blocks and words by copying, e.g
newblock: copy []
does it have an advantage over
newblock: make block! 0 ?
-----------------------------------------------------------------------------------------------------------------------------------------------
foreach [char file-list] index-some-data read %. [
write-my-page char file-list
]
I presume you "read" the directory in "index-some-data" but without the
colon? I expected something like this
foreach [char file-list] index-some-data: read %. [
write-my-page char file-list
]
-----------------------------------------------------------------------------------------------------------------------------------------------
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 ?
generate-my-page: function [
page-number
some-pagerefs [block!]
][html-page][
html-page: copy {}
append html-page reduce [<h1> "This is page " page-number </h1>]
foreach pageref some-pagerefs [
append html-page <p>
append html-page build-tag reduce ['a 'href pageref]
append html-page pageref
append html-page [</a> </p>]
_______________________________________________________________________________________
This is one of the parts that I like best
"either indexed-item: find index-block first item ["
I never thought that the left to right evaluation in REBOL could also be
passed as a expression to "either" or "for"
Thanks Brett for your help
Best regards
Sharriff Aina
[16/17] from: brett:codeconscious at: 21-Nov-2000 23:02
> You said "Yell", well I´m yelling!
:)
> result-block: make block! (multiply 2 length? index-block)
> could you tell me why you initialized the block in this form?
Only that I believe it pre-allocates memory for the new block to that size.
Everything between ( and ) just calculates how many elements I expect in the
final block. It is purely a performance tweak.
> I´ve noticed
> that you pass references to blocks and words by copying, e.g
> newblock: copy []
> does it have an advantage over
> newblock: make block! 0 ?
It is shorter. :)
And I'm a little nervous about passing in 0 as an argument to the make
function (programmers superstition?).
Other than that it is exactly the same. If I didn't use copy I would end up
changing my code - so all I'm doing is creating a new empty block that is a
copy of an existing empty block.
Brett.
> foreach [char file-list] index-some-data read %. [
> write-my-page char file-list
<<quoted lines omitted: 4>>
> write-my-page char file-list
> ]
Nope. index-some-data was a function I defined in my post. It takes a block
as an argument. "read %." produces a block as a result. So all I'm doing is
passing the list of files to my function index-some-data which it will then
chew on for a bit. When it finishes it will return a block that the foreach
will chew on for a bit.
> 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.
____________________________________________________________________________
___________
> This is one of the parts that I like best
> "either indexed-item: find index-block first item ["
> I never thought that the left to right evaluation in REBOL could also be
> passed as a expression to "either" or "for"
It gets better. Either and for return values too - the last value in their
blocks.
>> print either [equal? 1 1] ["yep"]["nup"]
yep
[17/17] 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
]
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted