This history will not be accurate; it will not be complete. Lynx was developed in a dynamic environment involving frequent collaboration, as well as independent work, and identifying who did exactly what and when is very difficult. Thomas Kuhn, the well known philospher of science comments in "The Historical Structure of Scientific Discovery:"
If the study of discovery has a surprise to offer, it is only that, despite the immense energy and ingenuity expended upon it, neither polemic nor painstaking scholarship has often succeeded in pinpointing the time and place at which a given discovery could properly be said to have "been made".
Lynx was developed primarily by Michael Grobe, Charles Rezac and Lou Montulli, and members of the "Internet community" by an iterative process of exploration, interaction, hacking and evaluating.
Prior to becoming a Web browser Lynx was a distributed hypertext browser based on the client/server model with its own intermachine and intradocument link tags. In addition, to support remote database applications, Lynx could serve as a kind of text-based X Window display server.
This document includes excerpts from early Lynx documentation, usually from 1992. Early documentation is presented in blue font, and surrounded by text markers for Lynx users, of course.
I was not excited by this idea to start with. It's utility seemed limited. In my view Herb wanted a CWIS mostly because "everyone else had one", and we needed to "keep up." Of course, these days "everyone" DOES have one though we had not the wildest expectation of such ubiquity.
Charles Rezac made a second try exploring Gopher, etc. and working on a PC client for Gopher. Charles ran into the Web project during this time, and he knew it did something similar to what we wanted, but he didn't follow up on it since he understood it to be limited to the Next platform. Much later, we encoutered the CERN linemode browser and found it too "ungraceful" to pursue, compared with Lynx's screen-oriented hypertext.
We advertised for a student programmer to develop a UN*X- based, menu-oriented system. A young EECS student named Lou Montulli applied, and the rest is . . ., well, . . . not quite history. We hired another student, Vijay Kolli, instead.
And we developed a simple menu-based system while Lou worked for another group within User Services and moonlighted with us.
So we made a few changes and began to use Earl's code as a simple hypertext display tool. The earliest versions of Lynx employed their own link (tag) syntax, and simple URL scheme, assumed all documents were preformatted text (though we considered using ROFF source). Lynx also had an "owner tag", developed to identify the document creator (a forerunner to the mailto: URL), as implemented in the UNICORN CWIS system developed by Neal Erdwien of Kansas State University.
Here is a simple example document taken from 1992 documentation:
[Original Lynx documentation from 1992 begins here.]
[Original Lynx documentation from 1992 ends here.]
This is roughly equivalent to the following HTML:
[Original Lynx documentation from 1992 begins here.]
The file itself is considered to be "owned" by a user named Michael Grobe, whose
electronic mail address is grobe@kuhub.cc.ukans.edu. Users may mail messages
to the file owner within Lynx and Lynx itself may mail messages to the owner in
response to certain error conditions, such as a link within the file proving to be
inaccessible.
When Lynx displays the file, the link pointers will not be displayed. Instead, the
screen will look something like:
[Original Lynx documentation from 1992 ends here.]
CS 200 Introduction to Computer Science MWF 3:30
104 Strong Hall A Lovelace
CS 600 Introduction to Data Structures TR 2:30
210 Snow Hall A Turing
Meantime, Gopher was growing in popularity and we discussed ways to use both tools to meet our needs. Finally, one day in 1992 I had the idea of grafting the Gopher client net management routines onto Lynx to merge the two tools. Lou and Charles thanked me for finally catching on, pointing out that they had been suggesting just that for a week.
So Lou grafted and by July of 1992 we had what I took to calling a "distributed hypertext" system, and we immediately began presenting the system locally and at Midnet conferences. For a while we billed ourselves as "Mike and Lou's Asphalt Resurfacing Company". We used Gopher servers to house our Lynx-style hypertext documents. Lynx also became the best text-based Gopher client as a side-effect.
Here is a diagram of the distributed hypertext idea:
Here is an example showing the format of the early Lynx resource
pointer (analogous to a URL):
[Original Lynx documentation from 1992 begins here.]
The following version of the timetable file shown above, directs Lynx to take
course catalog information from a Gopher server running on a system whose
Internet address is ukanaix.cc.ukans.edu:
The general syntax for the name of a file held in a Gopher server is, then
where the pathname is appended to the PATH variable to obtain the path to a
file relative to the base Gopher directory on the remote server. port_number is
the TCP/IP port on which the Gopher server is listening. The default port
number for Lynx links of this format is 70 (which is also the default Gopher
server port).
[Original Lynx documentation from 1992 ends here.]
Aside from specifying files to be displayed, links can also specify
the number of characters following the link to be highlighted.
In addition, they can include a target string that determines which
portion of the designated (target) file to display first.
For example the link
specifies that the the first 41 characters following the link
should be highlighted, and instructs Lynx to search for the
string "CS 200" in the target file.
[Original Lynx documentation from 1992 ends here.]
This is roughly equivalent to:
[Original Lynx documentation from 1992 begins here.]
The courses file being used with this timetable file might look like:
[Original Lynx documentation from 1992 ends here.]
Lynx can start programs when links are activated. For example, the link
would start man on the local system if activated. man would operate as usual
and control would return to Lynx when man terminated.
In a similar approach the program is executed and all program output is placed
in a temporary file. (On UN*X systems this file is created in /tmp with a unique
name based on the PID of the executing program). The temporary file is treated
as a normal Lynx hypertext file, and may be searched for targets specified in the
link. For example, a link like:
instructs Lynx to execute the command
and capture the resulting output in a temporary file. Lynx will then display the
file beginning with the first segment containing the string "print" and underline
every occurrence of that string. The temporary file will be deleted when Lynx
exits.
The ability to execute some local commands is so useful, however, that Lynx
provides several standard local file execution links. These standard links include
support for telnet, tn3270 and rlogin, and are defined by specifying one of the
strings "TELNET", "TN3270", or "RLOGIN" as a program_path argument in the
local execution link syntax presented above. Such links should look something
like:
where the square brackets([]) indicate that an argument is optional. For
example, the port_number arguments are not necessary (and the square
brackets never actually appear in a link).
[Original Lynx documentation from 1992 ends here.]
[Original Lynx documentation from 1992 begins here.]
Lynx utilizes Gopher servers primarily to support distributed hypertext file
access. In addition, Lynx can function as a Gopher client itself when it
encounters links that specify gopher file types. For example, the link
appearing in a hypertext file allows a user to begin a Gopher session with the
Gopher server at gopher.micro.umn.edu. The Lynx interface to Gopher presents
Gopher files as Lynx hypertext documents. For example, users can select a file
from a Gopher directory by using the usual interactive arrow key sequences to
highlight the desired file.
[Original Lynx documentation from 1992 ends here.]
[Original Lynx documentation from 1992 begins here.]
Lynx employs two standard approaches to remote program execution. First, Lynx
supports standard TCP/IP socket communications techniques to start and
exchange information with remote servers. Each server listens on a defined port
on a server system until it receives a request to establish a connection from a
Lynx client process. Lynx can open connections to programs listening on specific
TCP/IP ports when processing links like:
When such a link is activated, Lynx makes a connection to the specified port and
assumes that any text sent through the connection is intended for a VT100
display. If Lynx can determine that the user is using a VT100 display device, the
VT100 commands are simply passed on to the user. Otherwise, Lynx converts
VT100 screen control commands to commands suitable for the display device
actually being used by the user (via calls to the UN*X curses library).
For example, the file below gives users access to a collection of event calendars
spread across a number of servers:
Activating the General Campus Events link would then invoke a screen that
provided campus events info, displayed by the event server running on
ukanaix.cc.ukans.edu. The user may choose a new date range, or a subset of the
event categories supported. When the user leaves this program, by typing a "q",
control is returned to Lynx. (The Lynx history list is unavailable while the the
event program is executing.)
This process is diagramed in the following image:
[Original Lynx documentation from 1992 ends here.]
During July of 1993, Lou and I attended what I like to call the Oth
World-Wide World Wide Web conference in Cambridge, MA
organized by Dale Dougherty of O'Reilley and Associates (who also
provided some financial assistance for our Lynx and DosLynx
projects). There we encountered 30-some Web developers, including
Berners-Lee then at CERN, Hardin, Andreesen, Totic, Mittelhauser,
etc. from NCSA, Tom Bruce (author of Cello) from Cornell Law School,
among others.
Since Lou was doing the coding, you can guess how this worked out.
Lou implemented a set of form tags for this database, making it one
of the first, if not THE first, form implementations. As Charles puts it,
Lou's approach got done, mine is becomming common via Java, etc.,
and his is the way of the future.
There was some consideration of taking Lynx commercial, and there
were several offers (by 3 letter companies) to license Lynx.
Unfortunately there were numerous contributors (We counted some
18 during one search through the code.) during the early history of
Lynx, making "Statement of Originality" a nightmare.
I moved to put the KU portions of Lynx into the public domain in
1996, but the lynx-dev group preferred GNU status, so Lynx was
declared to be under GNU General Public License in 1996?
Besides that, good authority assured me that it was impossible to
make money on a client. (They apparently didn't consider making
money on the hope engendered by a client.)
Lou went on to give the world the amazing fish cam and the BLINK
tag from within Netscape, to enjoy the American dream of working for
"god's gift to startups,"
and, one day in a galaxy far, far away, he will finally be
awarded his undergraduate degree.
Charles built the KU CWIS, which we named KUfacts, using the old
Lynx hypertext format, modified it to HTML as we moved to the
Web, and it remained pretty much the same until September 1996
when it was finally replaced with a fancier graphics-oriented
version. Charles has since moved on to the KU Medical Center, where
he designed their OWIE, known as Pulse, and is "currently
entertaining job offers and marriage proposals."
I lingered on at the Computer Center, as Manager of Distributed
Computing support and (now ex-) Director of our statewide network
(KANREN), encouraging the use of Internet technology.
In the short term, I would like to participate in building
the "real web", a network of communicating document databases,
so we can stop using file systems as document databases, and Intenet 2.
Tim balanced what was useful with what was do-able in an
incredibly elegant way. To me the Web is the "big 3": URL syntax,
HTML (choosing a "markup approach"), and HTTP in the context of
the Client/Server model.
I note that each of these
We also did anchors with targets, as in:
[Original Lynx documentation from 1992 begins here.]
We could execute commands locally from Lynx:
[Original Lynx documentation from 1992 begins here.]
Lynx: an animal that eats Gophers
More better solution: Integrating databases
Throughout this project we "discussed" ways of integrating databases
with our system. Our University Relations group had an event
calendar for the University that we set up to allow event catagory
and date searches, and used that for proof-of-concept. There were
several approaches to this database over the years. For example, we
developed telnet, rlogin, and tn3270 hyperlinks to get to it, and we
added the ability to act as a display server for screen-oriented text
sent by a process running on another system. This is basically th X
Windows of the text world. I liked to call it V-Windows, though
"streaming text" would have been good. (Vijay Kolli actually wrote
the first version of this display server code within Lynx.)
Grafting wwwlib
Wes Hubert, manager of another User Services group attended
INTEROP in October of 1992, where he attended a BOF on the Web.
He heard about wwwlib and upon his return suggested Lou add it to
Lynx. Lou had been interested in doing this for some time for a variety
of reasons, and came to me for corroboration. I advised it would "just
kludge up the code." (Several readers have suggested to me after the
fact that it might have already been too late :- ) He returned a week later,
having done the deed, and we began a wild ride on the Web.
The biggest challenge
Integrating databases engendered the most "passionate" discussions
throughout the project. Each of us had a favorite solution beyond the
V Windows approach. Lou wanted to build a "forms" interface
capability. I thought that was too restrictive and favored moving
small programs written in an interpreted language down to the client
to execute and return queries to database servers. (We considered
Perl, Tcl, and SafeTcl, but we expected to create desktop clients
somewhere down the road, and weren't aware of PC environments
for these languages.) Charles wanted to move complete objects
around; move the data with methods to display it locally.)
The Problem with Success
Lou left for Netscape in 1994, Garrett Blythe, who authored our
DosLynx system took over, but left soon after to join Lou at Netscape.
Charles left for greener pastures (but not quite AS green), and Jeff
Porter took over as Lynx developer. Jeff had hoped to rewrite Lynx
to get rid of that "hacked" look, but was unsuccessful and returned to
graduate school just as a campus-wide hiring freeze hit leaving Lynx
unsupported except for the community of users organized around
lynx-dev and led by Foteos Macrides of Worcester Foundation for
Experimental Biology.
Where are they now?
Lynx development continues organized around lynx-dev@sig.net.
What did we actually accomplish?
I like to say that we "invented a Web." Rather than the Web,
of course.
It seems to me that Tim Berners-Lee defined a much better version than
ours, and conversion was comparatively easy, since we had already developed
similar ideas.
April 10, 1997