Channels ▼
RSS

Web Development

Proposing a Standard Web API

Source Code Accompanies This Article. Download It Now.


FEB96: Proposing a Standard Web API

The authors are cofounders of Eolas Technologies Inc. and can be contacted at http://www.eolas.com.


The World Wide Web has matured from a relatively limited system for passive viewing of hypermedia-based documents into a robust framework for interactive application development and delivery. Much of this progress is due to the development of embedded executable content, also known as "inline Web applets," which allow Web pages to become full-blown, compound-document-based application environments. The first Web-based applets resulted from research begun in the late 1980s to find a low-cost way to provide widespread access for scientists and educators to remote, supercomputer-based visualization systems.

The Visible Human Project

In the late 1980s, the National Library of Medicine began a project to create a "standard" database of human anatomy. This "Visible Human Project" was to comprise over 30 GB of volume data on both male and female adult human anatomical structures. It was one of the original Grand Challenge projects in the federal High-Performance Computing and Communications initiative, the brainchild of then Senator Al Gore. As a member of the scientific advisory board for this project, one of us (Michael Doyle) became interested in the software issues involved in working with such a large database of the most detailed image information on human anatomical structure yet available. His group in the Biomedical Visualization Lab (BVL) at the University of Illinois at Chicago realized at the time that much research would have to be done to make such a vast resource both functional and accessible to scientists all around the world.

Until that time, medical visualization systems were designed to work on 3-D datasets in the 15-30 MB range, as produced by the typical CT or MRI scanner. High-end graphics workstations had adequate memory capacity and processor power to allow good interactive visualization and analysis of these routine datasets. The Visible Human data, however, presented an entirely different set of problems. To allow widespread access to an interactive visualization system based upon such a large body of data would require the combined computational power of several supercomputers, something not normally found in the typical biomedical scientist's lab budget.

Doyle's BVL group immediately began to work on solving the information-science problems related to both allowing interactive control of such data and distributing access to the system to scientists anywhere on the Internet. Our goal was to provide ubiquitous access to the system, allowing any user connected to the Internet to effectively use the system from inexpensive machines, regardless of platform or operating system.

The Promise of the Web

We saw Mosaic for the first time when Larry Smarr, director of the National Center for Supercomputing Applications, demonstrated it at an NSF site visit at BVL in early 1993. We became immediately intrigued with the potential for Mosaic to act as the front end to the online visualization resource we had been designing. Immediately after Michael Doyle left the University of Illinois to take the position of director of the academic computing center at the University of California, San Francisco, we began enhancing Mosaic to integrate it with our system. We designed and implemented an API for embedded inline applets that allowed a Web page to act as a "container" document for a fully interactive remote-visualization application, allowing real-time volume rendering and analysis of huge collections of 3-D biomedical volume data, where most of the computation was performed by powerful remote visualization engines. Using our enhanced version of Mosaic, later dubbed "WebRouser," a scientist using a low-end workstation could exploit computational power far beyond anything that could be found in one location.

This work was shown to several groups in 1993, including many that were later involved in projects to add APIs and applets to Web browsers at places such as NCSA, Netscape, and Sun. Realizing our group's work enabled the transformation of the Web into a robust platform for the development and deployment of any type of interactive application, in 1994 the University of California filed a U.S. patent application covering embedded program objects in distributed hypermedia documents. Eolas Technologies was then founded by the inventors to promote widespread commercialization and further development of the technology.

Enhancing the Web

Once the concept of the Web as an environment for interactive applications was initiated, the question was how to further develop it. Toward the end of 1993, we discussed the relative merits of building an interpreted language, such as Basic or Tcl, directly into the browser versus enhancing browsers through a "plug-in" API. We chose the API approach, believing that the best way to add language support would be by adding interpreters as external inline plug-in applets, which we called "Weblet applications." This would enable us to add a new language or other feature merely by developing a new Weblet application, without having to reengineer the browser itself.

Figure 1 is a Weblet-based version of the public-domain RASMOL visualization program that lets users view, analyze, and visualize a 3-D protein structure from within the Web page. A single programmer converted the original RASMOL source code into Weblet form in only ten hours.

Some time later, both limited API support, such as NCSA's CCI, and embedded-language support, such as Java, began to appear in various Web browsers; the <EMBED...> tag (which we first implemented in mid-1993) appeared in beta versions of Netscape's product by summer of 1995. Still, it wasn't until October of 1995 that the Netscape implementation began to approach the functionality of <EMBED...> used in WebRouser. The enormous effect of these developments in accelerating the commercialization of the Internet industry prompted us to release the first (free-for-noncommercial-use) distribution version of WebRouser for UNIX platforms in September 1995 (http://www.eolas.com/eolas/webrouse/).

The WebRouser Approach

Our general philosophy with WebRouser was to allow enhancement of the browser's functionality through object-oriented, modular application components that conform to a standard API, rather than turning the browser into a monolithic application with an ever-increasing code base. This encourages Web developers to take a document-centric approach to application development. The Web page itself becomes the mechanism for doing work, through collections of small, efficient Weblet building blocks, rather than the menagerie of top-heavy applications found on the common desktop PC.

The first release of WebRouser also included other enhancements aimed primarily at improving the interactivity of Web pages. These included client-side image maps, a document-driven button bar, and document-driven modification of the browser's menu tree.

Client-side image maps are supported through the Polymap format. Polymap files are essentially GIF files with polygon and URL information stored in the image's comment fields. To prevent complex polygon information from bloating the file, all of the comment fields are compressed and decompressed using the GIF LZW algorithm. Polymap files require no special treatment of the HTML code. WebRouser autodetects the presence of Polymap data when it reads inline GIFs. If a server-side (ISMAP) image map points to a Polymap GIF, then WebRouser will ignore the ISMAP data and give the Polymap data priority. Hotspots are decoded in real time and highlighted as the mouse moves over the image, and the associated URL is displayed at the bottom of the screen, providing users the same style of interactivity that hotwords have in HTML text. The Polymap format specification is open and freely available for use. You can find the spec at http://www.eolas.com/papers/Papers/Polymap/.

The <LINK...> and <GROUP...> tags allow Web pages to dynamically customize elements of the browser's GUI. The LINK tag allows the creation of a document-driven button bar implemented by placing tags in the document header, with the syntax <LINK ROLE="button label" HREF="http://...">. Several of these tags in sequence result in buttons below the URL window, similar to Navigator's What's New or What's Cool buttons, but they are dynamically defined by the page currently being viewed. Similarly, the GROUP tag allows the Web page to modify the browser's GUI; however, this tag differs by defining a hierarchical menu that reflects an entire tree of Web pages. In Example 1, a typical GROUP menu trigger, the text string "Click here to view the WebRouser slide show" appears as a conventional anchor on the Web page, but selecting it brings up the "slide_1.html" and activates the GROUPS menu option on WebRouser's menu bar. Slide Show is the first menu option, with a submenu whose options are Slide 1, Slide 2, and Slide 3. This allows the user to easily navigate through, for example, the "year, issue, article" hierarchy of online magazines.

The Web API

Of course, the key feature of WebRouser is the implementation of the <EMBED...> tag, through which inline plug-in Weblet applications are supported in Web pages. X Window applications that conform to the Eolas distributed hypermedia object embedding (DHOE) protocol can run--inline and fully interactive--within Web pages in the WebRouser window. WebRouser also supports the NCSA common client interface (CCI), which allows the Weblet to "drive" the browser application. DHOE and CCI collectively make up the Eolas Web API (WAPI) as supported in WebRouser.

WAPI is minimalist, combining the functionality of DHOE and CCI to exploit both the efficiency of X-events for communication of interaction events and graphic data and the flexibility of socket-based messaging for browser remote control and HTML rendering of Weblet-generated data. We are currently working on a cross-platform API, in the form of an OpenGL-style common-function library. The current minimalist WAPI specification will allow us greater flexibility in creating a cross-platform API, while maintaining compatibility with Weblets developed under the UNIX WAPI specification.

Eolas' primary objective with respect to the pending Web-applet patent is to facilitate the adoption of a standard API for interactive, Web-based application development, and then to develop innovative Weblet-based applications for the growing Internet software market. For an example of such a Weblet application, see the accompanying text box entitled "WebWish: Our Wish is Your Command." We intend to short circuit the API wars brewing between the major Web-browser competitors. In addition to creating a universal standard API, we are also instituting a mechanism for ensuring continued evolution of the WAPI spec on a regular timetable. Royalty-free licenses for browser-side implementation of Web applets under the pending patent have been offered to the major browser companies, and are in various degrees of negotiation. The primary condition of these licenses is that each licensee must conform to the WAPI protocol, and no other applet-integration protocol. A consortium of Eolas licensees is being formed to set the continuing WAPI specification and update it at regular intervals. The widespread acceptance of the developing WAPI standard will allow application developers to concentrate on the functionality of their applets without worrying which Web browser their customers will use.

Creating a WebRouser Weblet

WebRouser communicates with Weblet applications through a set of messages called the DHOE protocol. DHOE messages are relatively short character strings, which allow convenient, efficient use of existing interprocess-communications mechanisms on various platforms. We have implemented DHOE systems on several X Window platforms, including IRIX, SunOS, Solaris, OS/F 1, Sequent, and Linux. Implementations for both Microsoft Windows and Macintosh are planned for release by the end of the first quarter of 1996.

Listing One is a skeleton program for Weblet-based applications that can work with WebRouser. The current DHOE protocol defines a set of messages that synchronize the states on the DHOE clients and DHOE servers. The first four messages are used by the server to set up the DHOE system at startup, refresh/resize the client, and terminate the system on exit. The rest of the messages are sent by the browser client to the data server. They include messages about the client drawing-area visibility, and mouse and keyboard events.

Programming with DHOE involves initializing DHOE by installing a message-handling function, registering the DHOE client with the DHOE server, and registering various callbacks with their corresponding messages. The DHOE client and server may, at any time after client/server registration, send messages to each other. The messages (see Table 1) are character strings, and may be followed by different types of data. DHOE also supports buffer sharing (that is, bitmaps and pixmaps) between DHOE clients and servers.

Adding the DHOE mechanism into an existing data handler creates a DHOE server. The DHOE library kit consists of protocol_lib.h (the declaration file) and protocol_lib.c (the implementation file). To follow the Xt programming conventions, the DHOE strings are #defined with their Xt equivalents (DHOEkeyUp is mapped to XtNkeyUp, and so on). Messages from the DHOE server to the DHOE client (for example, external app-->hypermedia browser) are:

  • XtNrefreshNotify, server updating.
  • XtNpanelStartNotify, server ready.
  • XtNpanelExitNotify, server exiting.
Messages from the DHOE client to the DHOE server (for example, hypermedia browser-->external app) are:

  • XtNmapNotify, DHOE area shown.
  • XtNunmapNotify, DHOE area hidden.
  • XtNexitNotify, DHOE area destroyed.
  • XtNbuttonDown, DHOE area button down.
  • XtNbuttonUp, DHOE area button up.
  • XtNbuttonMove, DHOE area button move.
  • XtNkeyDown, DHOE area key down.
  • XtNkeyUp, DHOE area key up.
You can name these messages differently as long as the names are merely aliases of the original DHOE strings. These messages are defined in protocol_lib.h, which must be included in your program.

The following DHOE fundamental functions are provided in protocol_lib.c:

  • void handle_client_msg(Widget w, caddr_t client_data, XEvent *event), a function called back by XtAddEventHandler when it sees a message from the DHOE client (the hypermedia browser). To register this function with Xt, your program (DHOE server) should call XtAddEventHandler(Widget app_shell, NoEventMask, True, handle_client_msg, 102);. Here, handle_client_msg will be called with parameters w=app_shell, client_data=102, an event pointing to an X-event structure generated by Xt when it sees the message. The app_shell variable is usually the application shell returned by XtInitialize, XtAppInitialize, or XtVaAppInitialize.
  • void register_client(Widget w, Display *remote_display);, which registers your program with the DHOE client.
  • void register_client_msg_callback(char *msg, void (*function_ptr)());, which registers a function to be called back when Xt sees a string that matches msg. This function may appear anywhere in your program. You do not need to handle the XtNmapNotify/XtunmapNotify pair because DHOE servers deiconify/iconify when they receive these messages. You must specify a "quit" function to shut down your application gracefully on XtNexitNotify. Button- and key-message handling are optional. To obtain mouse coordinates, call get_mouse(int *x, int *y) for button-handling functions and get_keysym(KeySym *keysym) for key-handling functions. Keysym is defined by X11 (in keysymdef.h) for cross-platform compatibility.
  • void send_client_msg(char *msg, Display *remote_display, Window remote_window);, which sends a message with the value msg to the DHOE client at a display=remote_display and has an X window ID of remote_window. The remote_display and remote_window must be provided. This function may appear anywhere in the program after register_client.

A Weblet CAD-File Viewer

WT is an applet that allows interactive rotation and zooming of a 3-D CAD file stored in NASA's neutral file format (NFF). The source code for the sample Weblet application is available electronically (see "Availability," page 3) and at http://www .eolas.com/eolas/webrouse/wtsrc.tar.Z. What follows is a brief walk-through of the weblet-enhancing sections of the code (illustrated in the code listing just mentioned as a "simplified sample program outline").

    1. The outline starts with a typedef and some global declarations. The new type, ApplicationData, defines a structure common to all Xt Weblets. Together with the myResources and myOptions static variables, myAppData (which is of type ApplicationData) is used with XtGetApplicationResources in main() to extract the command-line arguments flagged with win, pixmap, pixmap_width, pixmap_height, and datafile. This is how Xt extracts command-line arguments and is unnecessary if the program has alternatives to decode command-line arguments. The aforementioned global variables and XtGetApplicationResources nicely store the information in a line such as wt -win 1234 -pixmap 5678 -pixmap_width 400 - pixmap_height 300 -datafile fname into myAppData.

    2. In main(), app_shell is first initialized the Xt way by using XtInitialize, which opens a connection to the X server and creates a top-level widget. XtGetApplicationResources gets the application resources as in step 1. The next section conveniently uses the myAppData.win variable to find out if the Weblet should run as a DHOE server or a stand-alone program. For a DHOE server, the program adds the handle_client_msg function from the DHOE implementation, protocol_lib.c, as the handler of the X client message event. The subsequent lines call three more DHOE functions: register_client, to initiate a handshake with the DHOE client; register_client_msg_callback, to register myQuit() as the callback function of the message XtNexitNotify; and send_client_msg, to send a XtNpanelStartNotify message, telling the DHOE client that the server is ready. The program then enters the conventional XtMainLoop().

    3. Two more functions must be modified. The drawing routine (myDraw) needs to copy the drawn picture (myPixmap in this case) onto myAppData.pixmap, the client's pixmap. The function then should send an XtNrefreshNotify message to the client, informing it of the change. The myQuit() function registered in main() needs to send an XtNpanelExitNotify message to the client, telling the client that the server is terminated.

This Weblet can be tested by putting it in your path and pointing your copy of WebRouser to http://www.eolas.com/eolas/ webrouse/office.htm.

The Eolas Web OS

In addition to the WebWish applet described in the text box, a Java interpreter Weblet application is planned for release by the end of March 1996. Java is a compiled language that produces binaries for a "virtual machine." The binaries are downloaded to the client and run on virtual-machine emulators that run on Macintosh, Windows, and UNIX platforms. Java applications tend to be smaller and more efficient than WebWish interpreted code, but they are far more difficult to develop. Eolas is developing a virtual operating system, the Web OS (planned for release late in 1996) that will allow far more robust, compact, and efficient compiled applets to be developed than is possible with Java. The Web OS is key to Eolas' long-term goal to transform the Web into a robust, document-centric, distributed-component application environment. It is a real-time, preemptive multitasking, multithreaded, object-oriented operating system that will run efficiently on low-end platforms, even on 80286-based systems and handheld PDAs.

The Web OS can run within Windows, Macintosh, and UNIX environments, or in stand-alone mode on machines with no pre-installed operating system. It supports dynamic memory management and linked libraries, and is both graphical and object oriented at the OS level. The OS kernel includes fully defined object classes, inheritance, and direct messaging. The OS includes several building-block objects that allow sophisticated applications--WYSIWYG word processors, spreadsheets, databases, e-mail systems, and the like--to be developed with a minimum of code. These applications are created primarily by subclassing and combining various Web OS component objects. Since new applications are created by defining differences and additions to the constituent objects, this results in tiny, robust, efficient binaries that optimize both bandwidth usage and server storage requirements. This platform is so efficient that a complete WYSIWYG word processor can be created in less than 5K of compiled code. Applications developed for the Web OS are likely to be smaller than most of the inline GIF images found on average Web pages today.

The operating system employs a single imaging model for screen, printer, fax, and other output devices; an installable file system, for both local and remote file access; direct TCP/IP and socket support; distributed objects; and security through public-key encryption and "ticket-based" authentication.

As the Internet pervades more of our work environments, the Web OS will allow the Web to become the preferred environment for new and innovative productivity, communications, and entertainment applications for all hardware platforms. The concept of a machine-specific operating system will become irrelevant, since any application will be available to the average user, regardless of hardware platform. Much of the computational load for applications will be pushed off to remotely networked computational engines, allowing low-cost Web terminals to act as ubiquitous doorways to potentially unlimited computational resources. The Web will be your operating system and the Internet will be your computer.

WebWish: Our Wish is Your Command

Sun's announcement of the adaptation of the Java language to the Web in 1995 was received enthusiastically by the entire Internet community as a welcome means for increasing the interactivity of Web-based content. Despite much of the publicity surrounding Java, which described it as an "interpreted" language, Java code must be compiled to a "virtual machine," which is then emulated on various platforms. A Web browser that supports the Java emulator is not enough to develop Java-based applications--the applet developer must purchase a compiler from Sun or its licensees at considerable cost.

Fully interpreted languages like Tcl/Tk or Basic are extremely useful, partly because they don't require a compiler for application development, just the language interpreter and any ASCII text editor. In choosing a programming language to adapt to the Web API, we decided early on that a fully interpreted programming language would be vital to quick, widespread Weblet implementation. We chose Tcl/Tk because of its robust capabilities and widespread use.

By the time you read this article, Eolas' WebWish Tcl/Tk interpreter should be available for both WebRouser under UNIX and Netscape Navigator 2.0 on Windows and Macintosh (see http://www.eolas.com/eolas/webrouse/tcl.htm). It supports Tcl 7.5 and Tk 4.1, as well as the Tcl-DP and EXPECT extensions. A new security feature has been added that exploits PGP-style digital signatures in order to authenticate scripts from trusted sources and to prevent unwanted execution of scripts from untrusted sources. This Weblet application turns WebRouser and Navigator into complete application-development environments, without the need for expensive compilers. All that is needed to develop a WebWish-based application is WebWish, a WAPI-compliant Web browser, and a good text editor. Developers can draw upon the vast existing resources of freely downloadable Tcl/Tk program source code, and the expertise of thousands of experienced programmers.

WebWish provides an easy-to-use rapid prototyping environment, with built-in support for socket-based communications, remote procedure calls (RPCs), and the ability to "remote control" existing text-based server systems without reengineering the server. WebWish can run either as a Weblet in a Web page, or in stand-alone mode on either the client or a server machine. WebWish running in a Web page can communicate directly with other copies of WebWish running on remote servers, either through sockets or RPCs. This allows WebWish to act as "middleware" for the Web, allowing Web-based interfaces to create state-aware graphical front ends to existing text-based legacy systems, without changing the operation of the legacy-server application.

Last November, Chicago's Rush Presbyterian St. Luke's Medical Center surgical department created both client and server WebWish applets for just such a purpose. The applets allowed physicians using WebRouser to interactively query and browse Rush's (Informix) SQL-based Surgical Information System, consisting of medical records on over 1.5 million patients. The entire project took one programmer exactly 12 hours from start to finish. Try that with Java!

--M.D., C.A., and D.M.

Figure 1: Typical Weblet application.

Example 1: Typical GROUP menu.

<GROUP ROLE="Slide Show">
   <LINK ROLE="Slide 1" HREF="slide_1.html">
   <LINK ROLE="Slide 2" HREF="slide_2.html">
   <LINK ROLE="Slide 3" HREF="slide_3.html">
   Click here to view the WebRouser slide show </GROUP>

Table 1: DHOE messages.

Message                  Description

DHOEserverUpdate         Tells a client to update data.
DHOEserverReady          Tells a client the server is ready.
DHOEserverExit           Tells a client the server is exiting.
DHOEserverConfigureWin   Tells a client to resize/reposition the DHOE window.
DHOEclientAreaShown      Tells the server the DHOE area is exposed.
DHOEclientAreaHidden     Tells the server the DHOE area is being hidden.
DHOEclientAreaDestroy    Tells the server the DHOE area is being destroyed.
DHOEbuttonDown           Sends mouse-pointer coordinates to the server on button down.
DHOEbuttonUp             Sends mouse-pointer coordinates to the server on button up.
DHOEbuttonMove           Sends mouse-pointer coordinates to the server on button move.
DHOEkeyDown              Sends the corresponding keysym to the server on key down.
DHOEkeyUp                Sends the corresponding keysym to the server on key up.

Listing One

#include "protocol_lib.h"
 ...
/* X-way to define resources and parse the cmdline args */
/* WebRouser 2.6-b2 gives the embedded window information through these args */
typedef struct{
        int     win;
        int     pixmap;
        int     pixmap_width;
        int     pixmap_height;
        char    *datafile;
} ApplicationData, *ApplicationDataPtr;
static XtResource myResources[] = {
        {"win", "Win", XtRInt, sizeof(int),
         XtOffset(ApplicationDataPtr, win), XtRImmediate, 0},
        {"pixmap", "Pixmap", XtRInt, sizeof(int),
         XtOffset(ApplicationDataPtr, pixmap), XtRImmediate, 0},
        {"pixmap_width", "Pixmap_width", XtRInt, sizeof(int),
         XtOffset(ApplicationDataPtr, pixmap_width), XtRImmediate, 400},
        {"pixmap_height", "Pixmap_height", XtRInt, sizeof(int),
         XtOffset(ApplicationDataPtr, pixmap_height), XtRImmediate, 400},
        {"datafile", "Datafile", XtRString, sizeof(char*),
         XtOffset(ApplicationDataPtr, datafile), XtRImmediate, NULL},
};
static XrmOptionDescRec myOptions[] = {
        {"-win", "*win", XrmoptionSepArg, 0},
        {"-pixmap", "*pixmap", XrmoptionSepArg, 0},
        {"-pixmap_width", "*pixmap_width", XrmoptionSepArg, 0},
        {"-pixmap_height", "*pixmap_height", XrmoptionSepArg, 0},
        {"-datafile", "*datafile", XrmoptionSepArg, NULL},
};
ApplicationData myAppData;
void myDraw()
{
    /* do your drawing... */
    ...
    /* if you draw into your own drawables (myPixmap in this case) */
    if (myAppData.win) {
        /* copy from myPixmap to the "shared" pixmap */
        XCopyArea(display, myPixmap, myAppData.pixmap, myGC, 0, 0, WIN_WIDTH,
                                                            WIN_HEIGHT, 0, 0);
        /* tell WebRouser to update the drawing window */
        send_client_msg(XtNrefreshNotify, display, myAppData.win);
    }
}
void myQuit()
{
        /* tell WebRouser you are exiting... */
        if (myAppData.win)
                send_client_msg(XtNpanelExitNotify, display, myAppData.win);
        /* Motif way of exiting */
        XtCloseDisplay(XtDisplay(any widget));
        exit(1);
}
 ...
main()
{
    Widget app_shell;
    ...
    /* XtInitialize does XOpenDisplay, as well as creates a toplevel widget */
    app_shell = XtInitialize("wt", "Wt", myOptions, XtNumber(myOptions), 
                                                                 &argc, argv);
    ...
    /* This func fill up myAppData with user specified values/default values */
    /* We get the embedded window's info this way */
    XtGetApplicationResources(app_shell, &myAppData, myResources,
    XtNumber(myResources), NULL, 0);
    ...
    /* if we have an external window to display the image... */
    if (myAppData.win) {
        XtAddEventHandler(app_shell,NoEventMask,True,handle_client_msg,NULL);
        register_client(app_shell, display);
        /* register the func to be called when WebRouser exits */
        register_client_msg_callback(XtNexitNotify, myQuit);
        /* tell WebRouser you have started fine */
        send_client_msg(XtNpanelStartNotify, display, myAppData.win);
    }
    ...
    XtMainLoop(); /* Motif's event loop */
}
/* End of program listing */


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 
Dr. Dobb's TV