Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search

[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! Im almost there Brett. Michael, Andrew although Ive 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" /> &nbsp;&nbsp;&nbsp;&nbsp;}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" /> &nbsp;&nbsp;&nbsp;&nbsp;}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 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> tags. How do code a method to execute only once in this situation? The way Ive 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. Im not sure if the script is economical with memory,( ive 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