Abstract. In this elucidative program we make a bookmark browser. The program demonstrates
LAML programming in practice, on a small scale, but not in the style
of a pure toy program. As a motivation we can observe that it is not pratical to bind one's bookmarks to a single machine, nor to a single browser. I use several different machines, on both the Unix and the Windows platform. Therefore I maintain my bookmarks as a datastructure, from which I generate a HTML presentation of the bookmarks. Let us assume that each bookmark is of the form (bookmark "title" "category" "comment"). Thus, a bookmark is a four tuple of a symbol, a bookmark category string and a comment. The collection of bookmarks, which we represent in a file, is a list of bookmark entries. Given such a list, we will here make a bookmark browser, such as this one. |
![]() ![]() ![]() 1 The frameset page We first care about the overall frameset page. |
1.1 The frameset page |
![]() ![]() ![]() 1.1 The frameset page |
We first define the variable frame-width-list
which defines the widths of the browsers 'column' frames. Next in frameset-page we generate
the frameset page. This is a page with head (
We see that we make empty frame pages using make-empty-page!. These empty pages
will later in the program be overwritten by more useful frame pages. ), title (
), and two frames (
).
Both the head, title, and the frame forms are applications of HTML mirror functions. Frames are named
(for mutual reference purposes)
and sourced (in order to bring up other WWW pages in the frames).
Notice the use of frame-width-list (at
): we use the function list-to-string
to create a comma separated 'cols value. The resulting frameset is written
to a HTML file of the same name as the source LAML file (
). Thus, if the source
document is located in index.laml, the frameset will be written to index.html.
![]() ![]() ![]() 2 The left frame We now describe the left frame which list all bookmark catetories. But first we will draw the attention to bookmark selectors and constructors. |
2.1 Boomark selectors and constructor 2.2 The left frame |
![]() ![]() ![]() 2.1 Boomark selectors and constructor |
![]() ![]() ![]() 2.2 The left frame |
The function takes a bookmark list, bml, as parameter. The value of the variable bookmarks is
passed as actual parameter to this function. The bookmarks as such come from a file, such as bookmark-list, as it
appears in the definition of bookmarks.
Let us now take a closer look at the function present-categories. It first extract
all bookmark categories by mapping the selector function bookmark-category-of
on the bookmark list bml (
In the body of present-categories we render anchors to the bookmark file (as they are presented in the right frame).
This is done my mapping (
At the outer level of present-categories ( ). This will typically create a list with a lot of duplicates,
because each category of bookmarks, in general, will contain many individual bookmarks.
Therefore we remove the duplicates from the category list (
).
) a specially made, simple lambda function on the sorted and
downcased category list, cat-list-unique. The lambda function returns targeted hyper references.
Notices that we rely on anchor names (in terms of the categories), which we assume will be found in the bookmarks.html file.
As such it will probably be a requirement that the category names of the bookmarks are without spaces or
other kinds of white space.
) we transform the list to a break-separated string.
![]() ![]() ![]() 3 The right frame Finally, we describe the right hand frame, which holds the bookmarks as such. |
3.1 The right frame |
![]() ![]() ![]() 3.1 The right frame |
cat1 bookmark-1 bookmark-2 bookmark-3 cat2 bookmark-4 bookmark-5 bookmark-6The first task is to order the bookmarks according to their categories. This is done in the 'top level function' present-bookmarks. The ordering is done by the Scheme/LAML sort-list function (
Now present-bookmarks-1 takes over the rest of the presentation work.
The main challenge i present-bookmarks-1 is to present the bookmark category
in front of only the first bookmark in a given category. This is somewhat tricky.
Our functional solution is the following. In the last two lines of present-bookmarks
we use two list: the sorted bookmarks () and a right shifted copy of it (
).
If we assume that (b1 b2 b3 b4 b5) is the list of sorted bookmarks, the
right shifted copy is (x b1 b2 b3 b4). X is a special sentinel-bookmark.
Now given these two lists
(b1 b2 b3 b4 b5) (x b1 b2 b3 b4)as bml and prev-bml in present-bookmarks-1, we emit a category header if the category of bm is not equal to the cateory of bm-pre (
The presentation of a single bookmark is simple; It is done by present-a-bookmark. Notice how the bookmark comment is used as the title attribute of the anchor tag.
The right frame is written in the program section right-frame-page.
![]() ![]() ![]() 4 Application Let us conclude with a few words about a potential application of the the program. |
4.1 Application |
![]() ![]() ![]() 4.1 Application |
This solution is not entirely ideal, but it is reasonable when we always have an running Emacs in operation. The editor command may prompt us for category and other needed information.