A Bookmark Browser

Kurt Nørmark ©    normark@cs.auc.dk    Department of Computer Science, Aalborg University, Denmark    

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.

 

  The left frame frameset-section
1  The frameset page
We first care about the overall frameset page.
1.1  The frameset page
 

The frameset page   frameset
1.1  The frameset page
The browser will be constructed as a frameset of two frames. Thus, there are three programming tasks involved: The frameset, the left hand frame, and the right hand frame. Here we describe the frameset task, which is the more simple one. In the two next sections we describe the programming of the two frames.

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 (A link to a program source marker in frameset-page), title (A link to a program source marker in frameset-page), and two frames (A link to a program source marker in frameset-page). 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 A link to a program source marker in frameset-page): 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 (A link to a program source marker in frameset-page). Thus, if the source document is located in index.laml, the frameset will be written to index.html.

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. 

 

 The frameset page The right frame left-frame-section
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
 

The left frame  The left frame sel-constr
2.1  Boomark selectors and constructor
It is always a good idea to access data in an abstract fashion. In this way we do not bind our program to a concret data representation. As a consequence, we define four bookmark selector functions:

In addtion, we construct a bookmark by means of the constructor function make-bookmark

 

The left frame Boomark selectors and constructor  left-frame
2.2  The left frame
The left frame is produced by the function
present-categories which is called in the program section left-frame-page.

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 (A link to a program source marker in 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 link to a program source marker in present-categories).

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 (A link to a program source marker in present-categories) 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.

At the outer level of present-categories (A link to a program source marker in present-categories) we transform the list to a break-separated string. 

 

 The left frame Application right-frame-section
3  The right frame
Finally, we describe the right hand frame, which holds the bookmarks as such.
3.1  The right frame
 

The right frame   right-frame
3.1  The right frame
The right frame contains the bookmarks as such. We decide that it will hold a the bookmarks as subitems to their categories. Thus, we go for a bookmark page of the form:

cat1
  bookmark-1
  bookmark-2
  bookmark-3
cat2
  bookmark-4
  bookmark-5
  bookmark-6
The 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 (A link to a program source marker in present-bookmarks). The crucial parameter in the call of sort-list is the comparision function, which is given two bookmarks bm1 and bm2 to compare. Bookmark bm1 is less than bm2 if bm1's downcased category is less than bm2's downcased category.

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 (A link to a program source marker in present-bookmarks) and a right shifted copy of it (A link to a program source marker in present-bookmarks). 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 (A link to a program source marker in present-bookmarks-1). This can be done by mapping a function over the two lists. As it should be clear, the sentinel bookmark is of a different category than b1, thus causing the first category to appear in front of the very first bookmark.

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

 

 The right frame  application-section
4  Application
Let us conclude with a few words about a potential application of the the program.
4.1  Application
 

Application   application
4.1  Application
Bookmarks a most easily captured in a browser. It is quite tedious to insert a bookmark entry in a bookmark list in a special file. We use a compromise in between them. Given a URL, which we hold in our hand using the copy area of the operating system (Windows), we use an Emacs editor command to insert an entry in the bookmark list. Other tools may be used as well or instead to do the job. When the bookmark has been inserted, the editor activates the LAML processing of the bookmark program, which we have developed here.

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.