A Forth HTML Generator

A useful tool for web development -- and written entirely in ANS Forth


December 23, 2008
URL:http://www.drdobbs.com/web-development/a-forth-html-generator/212501814

Craig A. Lindley is a degreed hardware engineer who, until recently, had been writing large scale Java applications. Craig has authored over 40 technical articles on various programming topics and has published five books dealing mostly with multimedia. He can be contacted via email at: [email protected].


It's been a long time since I've programmed in Forth but for my current project it seemed like the correct choice of programming language. My current project is the addition of Common Gateway Interface (CGI) like functionality to my <a href="http://www.ddj.com/embedded/211300170">Webster2 web server. Why Forth was chosen and how it was used in support of a CGI interface will be discussed in a future article. Here I would like to discuss a component of my current project that may be of interest to Dr. Dobb's readers -- an HTML generator written entirely in Forth.

If you're like me, you find manual coding of HTML pages a tedious and error-prone activity. Many times over the years I have written code similar to the following:


printf("<html><head><title>HTML Page Title</title></head><body>"
 ...
 ... other HTML content ...
 ....
printf"</body></html>"

The problems I have encountered manually coding HTML include: improper nesting of HTML tags, improper embedding of special characters in text strings, forgetting closing tags, bad format of tag attributes and, in general, the generation of bad HTML understood by some browsers and not by others.

For my current project I decided to build in HTML generator functionality so that the pages returned from my web server would be of constantly higher quality. The challenge was the HTML generator had to be written in Forth.

In the Java world, I have used numerous HTML generator programs. One of the simplest and easiest to use was written by Cyrille Artho and is the Java HTML Generator. I have ported the concepts of this program to Forth -- MinForth actually -- and made some extensions along the way. The Forth code for the HTML generator is available here.

The Forth HTML generator has the following features:

Table 1 shows the public API for the Forth HTML generator.

Forth Word

Stack Diagram

Comments

newtag

(addrn un -- addrt)

Create a new tag with the name given at address addrn with length un. The returned address points at the tag data structure in memory and can be thought of as the id of the tag for all subsequent operations. Tags created with this method have opening and closing structures.

newtagnoclose

(addrn un -- addrt)

Same as above except tag is self contained

newtexttag

(addrt ut -- addrt)

Special type of tag for text. Here address addrt points at the text and ut is the text length. The text is automatically parsed and any special characters found are replaced before storage.

addattribtotag

(addra ua addrt --)

Adds the attribute string specified by addra ua to the tag identified by addrt. The attribute string is parsed and properly formatted before storage.

newtag+attrib

(addra ua addrn un -- addrt)

 

Creates a new tag with the specified attribute string. addra ua identifes the attribute string, addrn un identify the tag name.

addtagtotag

(addrf addrt --)

Connects the from tag addrf to the to tag addrt nesting the from tag inside of the to tag.

renderpage

(addrt -- addrsb)

After the complete HTML tag network is created and linked together this method is called to render the HTML. addrt identifies the top level tag in the network. The rendered HTML is returned in a str (see text). After the HTML is used, the str should be freed.

free-tags

(addrt --)

After the tag network has been rendered into a str, the dynamic memory containing the tag data structures should be freed with this method.

Table 1: The Public API for the Forth HTML Generator.

Examples of How the Forth HTML Generator Is Used


{
Example 1 Test code for the Forth HTML Generator
Illustrates basic HTML page generation
Written by: Craig A. Lindley
}

requires htmlgen.f

0 value htmltag
0 value headtag
0 value bodytag
0 value divtag
0 value titletag
0 value text1tag
0 value text2tag

: html			\ ( -- htmlid) 

	\ Generate static tags
	s" html" newtag to htmltag
	s" head" newtag to headtag
	s" body" newtag to bodytag
	s" align=center" s" div" newtag+attrib to divtag
	s" title" newtag to titletag

	\ Generate static strings
	s" Example One Page" newtexttag to text1tag
	s" Example One Page Generated by Forth HTML Generator" newtexttag to text2tag
  
	\ Connect the tags
	text1tag titletag addtagtotag 
	titletag headtag addtagtotag
	headtag htmltag addtagtotag
	bodytag htmltag addtagtotag
	divtag bodytag addtagtotag
	text2tag divtag addtagtotag

	htmltag		\ ( -- htmlid)
;

: test html dup renderpage dup str-get type str-free free-tags ;
Example 1: Simple HTML page.

When the test method of Example 1 is executed, it outputs HTML code to standard out. Saving the code to a file and displaying with a browser results in Figure 1.

Figure 1: Page generated by Example 1.

Nothing much to get excited about. Example 2 is a bit more complex and shows how special characters in text are handled.


{
Example 2 Test code for the Forth HTML Generator
Illustrates special character replacement in text tags
Written by: Craig A. Lindley
}

requires htmlgen.f

0 value htmltag
0 value headtag
0 value bodytag
0 value divtag
0 value titletag
0 value breaktag
0 value h1tag
0 value text1tag
0 value text2tag
0 value text3tag
0 value text4tag
0 value text5tag


: html	\ ( -- htmlid) 
	\ Create static tags
	s" html" newtag to htmltag
	s" head" newtag to headtag
	s" body" newtag to bodytag
	s" align=center" s" div" newtag+attrib to divtag
	s" title" newtag to titletag
	s" br" newtagnoclose to breaktag

	\ Generate static strings
	s" Example Two Page" newtexttag to text1tag
	s" Craig & Heather" newtexttag to text2tag
	s" 10 < 20" newtexttag to text3tag
	s" 20 > 10" newtexttag to text4tag
	s" Example Two Page Generated by Forth HTML Generator" newtexttag to text5tag

	\ Connect the tags
	text1tag titletag addtagtotag 
	titletag headtag addtagtotag
	headtag htmltag addtagtotag
	bodytag htmltag addtagtotag
	divtag bodytag addtagtotag

	s" h1" newtag to h1tag
	text2tag h1tag addtagtotag
	h1tag divtag addtagtotag
	breaktag divtag addtagtotag

	s" h1" newtag to h1tag
	text3tag h1tag addtagtotag
	h1tag divtag addtagtotag
	breaktag divtag addtagtotag

	s" h1" newtag to h1tag
	text4tag h1tag addtagtotag
	h1tag divtag addtagtotag
	breaktag divtag addtagtotag
	breaktag divtag addtagtotag

	text5tag divtag addtagtotag

	htmltag
;

: test html dup renderpage dup str-get type str-free free-tags ;
Example 2: Treatment of Special Characters in Text.

The code in Example 2 results in the browser display in Figure 2.

Figure 2: Page generated by Example 2.

Example 3 shows a calendar for September 2008 generated by the Forth HTML generator. The code is too long to show here, but is available here for download. This example shows how various heading are used, how tables are generated and populated and how hypertext links are made. The rendered output is shown below:

Figure 3: Page generated by Forth HTML generator.

These three examples show the generation of static HTML pages but I hope you understand that the content of the generated pages can be as dynamic and dramatic as your application demands and your Forth programming skills allow.

How It Works

The Forth HTML generator is implemented using MinForth which is an ANS Standard Forth written in C. I chose MinForth because it was possible to port it to my Webster2 web server that doesn't have an operating system per se. I needed dynamic strings (like StringBuffer in Java) for my implementation in addition to the functionality provided by MinForth. For this I turned to the Forth Foundation Library (FFL) instead of reinventing the wheel. It was a small task to port str.fs and stc.fs to the MinForth environment which says something for the Forth standardization process. Dynamic memory words, which are part of ANS Forth, also came in handy.

Tags in the Forth HTML generator are implements as a data structure in dynamic memory which contains storage for a name, for an attribute string, for a series of links to other tags and some flags. Normal tags have a name and optionally an attribute string. Text tags are not named and have their text stored in the attribute portion of the tag structure. Flags in the data structure mark a tag as a normal tag or a text tag and whether or not the tag is closed. As tags are added to other tags, an entry is made in the containing tag for the tag being linked. An HTML document is a network of linked tags.

When a new tag is created, dynamic memory is allocated for the tag data structure, the name of the tag is copied into the structure along with an optional attribute string and the appropriate flags are set. All processing and formatting of attribute strings is performed before copying into the tag structure. The same is true for text strings.

An HTML document is defined by a hierarchical network of tags. The renderpage word is used to convert the network of tags into HTML statements. This is done by performing a depth first traverse of the tag network and rendering the tags along with way. Recursion is used in the code extensively for traversal of the tag network.

Using the Forth HTML Generator

The examples I've presented show how the HTML generator code is used, but a couple of cautions are in order. The HTML generator will always output a properly formed HTML document but whether it is the document you wanted or expected is another matter entirely. For this reason it is important to feed the generated HTML to a browser during the development process to be sure you are on the right path. During your development keep the following in mind:

Conclusions

It has been an interesting experience dusting off my old Forth skills and learning ANS Forth as well. Writing the Forth HTML generator got my chops back up and provided me with a useful tool for my on going web server development project.

In doing research into the state of Forth I have concluded that Forth is not a dying language as I first thought but is thriving in many areas. The availability of a standard language definition, foundation, and scientific libraries and a port for almost any processor/operating system you care to mention helps to insure that Forth will continue to have a place in modern system design.

Terms of Service | Privacy Statement | Copyright © 2024 UBM Tech, All rights reserved.