HTML Dialect Example
Author: Henrik Mikael Kristensen Date: 11-Aug-2010 Copyright: 2010 - HMK Design Version: 0.0.8
I'm going to build a small source code browser using the HTML dialect. What it will do, is take all *.r files in a directory and display it in an HTML table on a webpage. The example uses RSP in Cheyenne, but you can use it for any place you need to generate a web page.
First we create a source code file, code.rsp, which is where all our code for displaying the source directory will reside.
Second we define what source code to read. I will first settle for reading the directory I need and get information on each file and store that information in a source-code block:
For the sake of simplicity, let's say the source files we want to examine are stored in the current directory, and remove all files that are not ending with the .r extension:
files: read %. remove-each file files [%.r <> suffix? file]
The information returned from each file is an object, containing useful information like file size and modification date. Since the HTML dialect handles blocks of objects just fine for tables, we can just loop through the directory using the info? function:
foreach file files [ append source-code make info? file [file-name: file] ]
Next we create the page itself:
output-html [page "Code Browser" ]
Next we add the table inside the page block. The table specs are used to format the block to what we want to see for each row, or more accurately, for each object that is traversed in the input block, as the formatting is not limited to a single table row.
We describe three parts: The header, the format of the layout and then the files that need to be displayed. As the table renderer progresses, it can change the format as it moves along, every time it encounters a format or rows word. So the first row is going to be the header. The format changes the format of the following rows and the second rows provides the rest of the data.
table /file-list rows [row header "File Name" header "Time" header "File size"] format [row cell :file-name cell :date cell :size] rows :files
We can then add some more features, such as reading the header of each source file and scour it for information that can be displayed in the cell. This requires an extra column called "Notes":
rows [ row header "File Name" header "Time" header "File size" header "Notes" ]
For the format column, we add the notes column by reading the file given for the file name in the current object. This is wrapped in a little block for the cell. Some files may not have a proper file header, so we want to ignore those, by wrapping the load code in an attempt and providing an alternative text string to print for those cases:
format [ row cell [strong :file-name] cell :date cell align right [:size " bytes"] cell [ do [ any [ attempt [get in first load/header :file-name 'title] "No notes" ] ] ] ]
And that's it.
If we want to add a few bits more, such as right aligned size column and bold file name, we can add that in the format block. These changes are visible in the completed source code for the code.rsp page:
do %html.r source-code:  files: read %. remove-each file files [find/match file %.] foreach file files [ append source-code make info? file [file-name: file] ] print output-html [ page "Code Browser" [ table #file-list rows [ row header "File Name" header "Time" header "File size" header "Note" ] format [ row cell [strong :file-name] cell :date cell align right [:size " bytes"] cell [ do [ any [ attempt [get in first load/header :file-name 'title] "No notes" ] ] ] ] rows :source-code ] ]
To further change the appearance of the table, it's recommended to use CSS. As you might be able to see, the CSS class for the table is file-list.