[REBOL] Re: Antwort: Switch! (LONG)
From: brett::codeconscious::com at: 21-Nov-2000 1:50
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