## 7.3 Example: A ToyText Browser

In the following we discuss a tiny ToyText browser that supports following of links in the text and going back to previously displayed pages. A ToyText hypertext is a record, where the features are the links and the fields describe pages. For an example, see *. A page consists out of head and body, where the body is a list of elements. An element is either a virtual string or a record `a(ref:``R``` `Es``)`, where `R` is a feature of the record and `Es` is a list of elements.

Figure 7.3 shows the main routine to display a ToyText page in a text widget `T`. The procedure `Display` takes a list of references `Rs` as input, and displays the page that is referred to by its first element.

<Definition of Display>=
  `proc {Display Rs}
  case Rs of nil then skip
  [] R|Rr then
  {T tk(delete p(0 0) 'end')}
  {Head ToyText.R.head Rr} {Body ToyText.R.body Rs}
  end
  end`

Figure 7.3: Displaying a ToyText page.

Figure 7.4 shows how the head of a ToyText page is displayed, where `E` is the virtual string to be displayed and `Rs` is the list of current references without its first element. The tag `HT` is configured such that clicking it displays the previous page.

<Definition of Head>=
  `local
  HF={New Tk.font tkInit(family:helvetica size:18 weight:bold)}
  HT={New Tk.textTag tkInit(parent:T font:HF foreground:orange)}
  in
  proc {Head E Rs}
  {T tk(insert p(0 0) E#'\n' HT)}
  {HT tkBind(event: '<1>'
  action: proc {$} {Display Rs} end)}
  end
  end`

Figure 7.4: Displaying the head of a ToyText page.

Figure 7.5 shows how the body of a ToyText page is displayed, where `Es` is the list of elements, `CT` is the current tag to which inserted text is added, and `Rs` are the current references, including a reference to the page currently under display as first element. To display a reference element, a new tag `RT` is created that carries as action a procedure that displays the referred page.

<Definition of Body>=
  `local
  BF={New Tk.font tkInit(family:helvetica size:12 weight:normal)}
  BT={New Tk.textTag tkInit(parent:T font:BF)}
  proc {Do Es CT Rs}
  case Es of nil then skip
  [] E|Er then
  case E
  of a(ref:R Es) then
  RT={New Tk.textTag tkInit(parent:T font:BF
  foreground:blue underline:true)}
  in
  {RT tkBind(event: '<1>'
  action: proc {$} {Display R|Rs} end)}
  {Do Es RT Rs}
  else
  {T tk(insert 'end' E CT)}
  end
  {Do Er CT Rs}
  end
  end
  in
  proc {Body Es Rs}
  {Do Es BT Rs}
  end
  end`

Figure 7.5: Displaying the body of a ToyText page.

Figure 7.6 shows the complete ToyText browser and how it looks when displaying pages.

  `proc {ToyBrowse ToyText Root}
  W={New Tk.toplevel tkInit}
  T={New Tk.text tkInit(parent:W width:40 height:8 bg:white wrap:word)}
  ` < Definition of Head >`
  ` < Definition of Body >`
  ` < Definition of Display >`
  in
  {Tk.send pack(T)}
  {Display [Root]}
  end
  {ToyBrowse` < Sample ToyText >`canvas}`

Figure 7.6: A ToyText browser.