Active Text for Structuring and Understanding Source Code - CiteSeerX

116 downloads 78323 Views 112KB Size Report
... Tampere, Finland. Phone: +358-31-2156784, Fax: +358-31-2156070, Email: [email protected] ..... It is good programming practice to comment the declarations of names. .... horizontal arrow from the sender to the receiver. The time .... their work and do not have to bother about a bulk of unnecessary features. Oberon's.
1

Active Text for Structuring and Understanding Source Code HANSPETER MÖSSENBÖCK University of Linz, Institute of Computer Science, A-4040 Linz, Austria Phone: +43-732-2468 9700, Fax: +43-732-651086, Email: [email protected] KAI KOSKIMIES University of Tampere, Department of Computer Science, FIN-33101 Tampere, Finland Phone: +358-31-2156784, Fax: +358-31-2156070, Email: [email protected]

2 SUMMARY Programs are not read sequentially like a book but rather selectively like an encyclopedia. Instead of linear text we therefore suggest non-linear active text as a medium for structuring and browsing source code. While common program editors are mainly character based we believe that non-textual information such as pictures, links, folds, and annotations can improve the readability of programs. In this paper we show how a text editor can be extended to include active text elements and give examples for how to apply these facilities to source code. Our approach is different from that of syntax-oriented editors in that our structuring is not based on the syntax of the edited texts. The implementation was done in the Oberon system which offers powerful mechanisms for extending software in an objectoriented way.

KEY WORDS Active Text Hypertext Documentation Program editor Event trace diagrams

MOTIVATION For centuries text was exclusively stored on paper. It was passive information that could be read or written, but nothing else. With the advent of electronic text processors operations such as inserting, deleting, and searching were introduced. But still text was passive in nature. Now that high-speed computers, graphical user interfaces, and multimedia become common, one starts to break with the passive paper metaphor and begins to consider text as an active medium. Active text contains not only textual information but also sensitive areas for user interaction. It may, for example, contain buttons that can be clicked to view the information in various formats or in different order. It is possible to present information in various levels of detail and let the user decide which level is appropriate by "zooming" in and out. Active also means that the text need not be motionless but may contain animation and even sound. In fact, active text can perform any commands and can serve as a new kind of user interface1. A special form of active text is hypertext 2 . Its basic idea is to connect related pieces of information and let the user follow these links by clicking on buttons that are embedded in a text. This allows an information base to be browsed selectively like an encyclopedia. We argue that active text—and in particular hypertext—is especially useful for structuring and understanding source code. Programs are usually not read sequentially (like a book) but rather selectively (like an encyclopedia). One zooms in at some point of interest and moves along to other locations according to the flow of control or other semantic relationships. In spite of that, most program editors provide a mere sequential view with the only navigational operations being scrolling forwards and backwards. Most editors also restrict the contents of a document to pure text, although pictures of data structures, class hierarchies, or event traces could be most helpful if they were embedded directly in the source code. In this paper we describe an implementation of active text and show how it can be applied to make source code better readable. Our work was done in the Oberon

3 environment 3-5—an object-oriented system that allows users to easily add their own active objects to a text. Oberon offers a framework for active texts that is described in Szyperski 6 . We have adapted this framework by developing text elements that support the structuring of source code. Most of these elements have been in use for several years and have proved useful for programming and teaching. Currently our system offers the following features: • Folding. A piece of text can be folded (collapsed) and unfolded (expanded) on demand. • Linking. Links can be established between arbitrary locations in texts and graphics. A link can be followed on demand like a reference in an encyclopedia. • Bookmarking. Locations of interest can be marked for finding and inspecting them quickly. • Annotating. Names can be associated with comments and pictures. These annotations can be made visible on demand at any place where such a name appears in the text. • Version management. Multiple versions of a document can be kept in the same file allowing the user to switch between these versions. • Error marking. Compilation errors can be marked and searched for in a program text. • Keywords. A list of keywords can be specified for a program file and can be searched for globally. • Time stamping. The date of the most recent modification of a text can be made visible within the text. • Command execution. Popup menus can be inserted in a text. They can be used to offer a selection of links or to execute arbitrary commands directly from the editor. Although these facilities are applied to source code here they are language independent and can also be used in other kinds of documents. In fact, some of them have been used for outlining papers, structuring manuals, or keeping address files.

A FRAMEWORK FOR ACTIVE TEXT This section lays the foundations for understanding the rest of the paper. It describes a framework for active text that can be extended by new embedded text elements. It also explains some important concepts of Oberon such as commands and run-time loading that help to bring the new elements into the game conveniently. An extensive description of Oberon's text framework can be found in Szyperski6. Text is a central data structure in Oberon. It provides basic operations to insert and delete pieces of text and to maintain fonts and styles. However, the most remarkable feature is the ability to allow arbitrary objects—so called elements—to be inserted and to float with the characters while the text is edited (Figure 1). Elements can be pictures, tables, formulas, popup buttons, hypertext objects, or anything else. They are treated as special characters with a certain width and height but with unspecified contents. This is similar to Microsoft's OLE (object linking and embedding) architecture7. Elements are not passive objects which are just displayed – they can be active, i.e., they can react to mouse clicks. For example, when the user clicks on a graphic element, it makes itself editable, when he clicks on a popup element, a menu pops up from which the user can select a command, etc.

4 The text editor treats the elements as black boxes which it can ask to perform certain operations such as displaying or copying themselves. Texts and elements are implemented in an object-oriented style. They form a framework which can be extended by new element kinds. Figure 2 shows the structure of this framework using the OMT notation8, 9. Elem is an abstract class which defines the common interface for subclasses such as GraphicElem, TableElem, PopupElem, etc. There is a small set of messages which are understood by all elements: Display

displays an element on the screen

Print

outputs an element on the printer

Load

reads the contents of an element from a file

Store

writes the contents of an element to a file

Copy

returns a copy of an element

Track

reacts to mouse clicks

The advantage of using the object-oriented approach is that any programmer can derive his own classes from Elem. Objects of these custom-specific classes can be handled by the text editor as if they had been part of the system from the beginning. Elements are normally used for one of the following purposes: • for adding non-textual information (pictures, tables, formulas, etc.) to text documents; • for adding new functionality (folding, linking, annotating, etc.) to the text editor. Since elements are active, this means that the editor is extended by new ways of interaction; • for marking text positions. Since elements float with the text while it is edited they retain their relative positions. Elements are implemented as special characters with attributes that contain a pointer to the element object. When a text with elements is compiled the element characters are ignored by the compiler. This makes it possible to include pictures and other elements in the source code. Oberon programs may provide commands. These are parameterless exported procedures that can be invoked by clicking on their names in the user interface. Commands therefore behave like textual buttons. When a command GraphicElems.Insert (command Insert from module GraphicElems) is clicked, the following happens: (1) Module GraphicElems is dynamically loaded and added to the system (unless it is already in memory). (2) Procedure Insert is executed. In our example, this procedure creates a graphic element and inserts it into the text at the current insert position. The text reacts to this modification by broadcasting an update message to all of its views which in turn send the new element a Display message. Thus the editor can work with the new element although it does not know its class. (3) When Insert returns, module GraphicElems stays loaded and its commands are ready to be invoked again.

5 Hence it is possible to specify and add new kinds of elements without modifying the editor and even without disrupting the edit session. This dynamic extensibility makes Oberon essentially more powerful than most other compiled object-oriented languages. It might also be worth mentioning that elements can not only be added to a text interactively but also by other programs. The following sections show how special elements can be designed to make active texts suitable for structuring and reading source code.

FOLDING One of the features that we found most useful in program texts is folding. The idea of folding is that a piece of text can be collapsed and possibly replaced with some other (usually shorter) text. The user can switch between the two texts with the mouse. Folds can be used e.g. for abstracting, commenting, structuring, and program development. A foldable text is surrounded by a pair of fold elements which are displayed as small triangles (Figure 3). Fold elements are either collapsed, in which case they are filled (

), or expanded, in which case they are hollow (

). A mouse click on one of the

elements exchanges the texts and switches the representation from hollow to filled or vice versa. Fold elements can be inserted by selecting the text to be folded and invoking the command FoldElems.Insert. They can be deleted like ordinary characters (the user has to make sure that they are deleted pairwise). Folding can be used in many ways for structuring programs. One possibility is to use fold elements for abstracting. Figure 4a shows a code fragment where certain details were folded away and replaced by a simpler pseudocode statement. If the user wants to see the details, she can "zoom in" and get the expanded view (Figure 4b). She can switch between the two views with a mouse click on the elements. Note that folds can also be nested: the detailed view in Figure 4b again contains a collapsed piece of code. Folding can save many extra comments. Instead of writing a comment next to some code fragment it can replace this fragment. This makes programs more compact and better shows where comments really refer to. Another use of folding is to hide lengthy comments. Comments help when a program is read for the first time. But when the reader gets familiar with the code, comments can become a nuisance. They can pollute the code and bury the actual statements (Figure 5). It may be useful to hide them in order to make the structure of the program better visible. Note that the collapsed text of a fold element can be empty. In the same way as in this example we have used fold elements also for hiding instrumentation code. If all procedures are collapsed to their headings the result is a program skeleton like the one that is shown in Figure 6. The user gets a nice overview of the program (a table of contents) and can selectively zoom into those procedures that he is interested in. Instead of structuring a finished program by hiding details one can use fold elements also reversely, namely to develop a new program according to the method of stepwise refinement. The first version of the program is written in pseudocode where every pseudocode action is a collapsed piece of text. Then, one pseudocode action after the other is refined and replaced by real code or more detailed pseudocode actions (Figure 7). The advantage compared to stepwise refinement on paper is that all the intermediate steps are still available in the final program. The user can go back and view the program at any level of detail, understanding the decomposition made by the

6 designer. The triangles of the fold elements can be toggled on and off, i.e., they can be made invisible so that they don't bother the reader. When a program containing fold elements is compiled the text is temporarily unfolded so that the compiler always sees the expanded view of the text. The actual elements are ignored by the compiler.

LINKING The idea of hypertext is to link related pieces of information. This is in analogy to an encyclopedia where a user can look up a term and find links to other terms which he can follow, if he is interested in them. A link has a starting point and an end point. It is mainly followed in one direction, namely from the starting point to the end point, but if necessary it should also be possible to follow it in the opposite direction in order to return to the starting point. Both points of a link must be unaffected by editing operations. If a link leads to the beginning of a procedure, it must do so even if text is inserted or deleted in front of that procedure. Therefore it is natural to use elements for both points of a link. Elements float with the text and retain their positions even if the text around them is edited. In our system, the starting point of a link is represented by a link element ( ) and the end point by a mark element ( ). Multiple links may lead to the same mark element. When the user clicks on a link element the text around the corresponding mark element is shown in a new window. When the user clicks on a mark element the link element that was most recently used to get to this mark element is shown. Link elements and mark elements may be in the same document or in different documents. It is even possible to go from a link element to a graphics document in which case a figure object is used as the end point instead of a mark element (this is not further explained here) or vice versa. Figure 8 shows an example where the use of a variable is linked to the statement where the value of this particular use was assigned. This may be helpful if there are multiple assignments to the variable and if the respective assignment is far apart from the use. Other examples include the linking of code to its documentation, to its specification, or to test data. We also found linking to be useful for preparing cookbooks for libraries and frameworks. A cookbook is a collection of examples that show the recommended use of a system. For example, it can show how to extend a given class or explain which objects must be plugged together in order to turn a framework into a running system. A cookbook can be structured as an explanatory text with links to sample code pieces. Finally, links can be used for maintaining a list of bookmarks. This is explained in the next section. In principle, link elements could also be used to link every use of a variable or procedure to its declaration. However, inserting such links would be laborious and flood the code with elements. It is better to resolve such links automatically in a languagedependent way. The Oberon system already contains commands for that. For example, if the source code contains the name of a variable v imported from a module M, the name M.v can be selected in the source code and the command Edit.Show can be invoked. This will open a new window showing the declaration of v in module M. Note that this technique is language-dependent. It assumes that M is the name of an Oberon module and v the name of an object declared in this module. Link elements, on the other side, are

7 completely language independent.

BOOKMARKING In large programs one usually works only at a few spots at a time. These spots must be revisited frequently. Instead of manually opening the necessary source files and scrolling to the desired locations one can use mark elements to set bookmarks at these locations and link elements to retrieve them quickly. The link elements leading to the bookmarks can be collected in a text which serves as a road map for finding the points of interest (Figure 9). Note that this text can be created with the ordinary text editor and stored as a text document. When loaded into a window the links can be used to get to the bookmarks. The road map can also be stored in one or several popup menus. We also implemented a facility which automatically generates a list of links to all mark elements in a text. This facility is again implemented as a text element, more specifically as a special popup element that can be embedded in a window's menu text. When this popup element is clicked, it automatically searches the text of the corresponding window for mark elements, creates links to them, and displays these links in the popup menu. The first word following the respective mark element is attached to every link so that one can see where the links lead to. Figure 10 shows an example: If all procedure names are preceded by mark elements in their declarations, the generated list of links is a module's table of contents allowing the user to quickly go to any procedure of that module. This is again a kind of bookmarking. As soon as a new mark element is placed in the text, a corresponding link to it appears in the link menu.

ANNOTATING It is good programming practice to comment the declarations of names. Such comments, however, are not available at the points where these names are used in the program text. It would be nice to click on a name wherever it appears in a program and to get its associated comment in a popup window. This is sometimes called balloon help. How can it be implemented? When the user clicks on a name, the name could be looked up in a dictionary and the corresponding annotation could be displayed. The question is how to intercept clicks and how to implement the dictionary. The Oberon system allows the installation of a custom message handler in a text frame (the window part that displays the text and handles user input). This handler can intercept clicks and do the dictionary look up. If the name is not found, the click is forwarded to the default message handler and handled in some standard way. There must be one dictionary per module so that the same name can be used in different modules and get different annotations. One possibility is to extend the text class to include the dictionary. This would be unsatisfactory, however, because the editor would then also have to be modified in order to use the extended text instead of the standard text. A better solution is to implement the dictionary as a text element. Such a balloon element contains a dictionary text which is a list of pairs . The name is written as a string and the comment consists of all characters up to the next string or to the end of the text. Figure 11 is an example of a dictionary's contents. Note that a dictionary may also contain pictures.

8 Figure 12 shows what happens when the user clicks on the name Insert in a program text containing a balloon element with the above contents. A popup window with the corresponding annotation is displayed until the user releases the mouse button. In order to minimize the number of necessary entries in a dictionary the look up is performed in three steps: 1. A balloon element is searched in the text into which the user clicked. If such an element is found the clicked name is looked up there. 2. If the name is not found and if it is of the form M.name, a balloon element is searched in the source text of module M and the name is looked up there. 3. If the name is still not found it is looked up in a global dictionary named Balloon.Text.

VERSION MANAGEMENT Sometimes there are different versions of a module for different computers or operating systems. These versions often differ only in small parts while most of the text is the same. For example, the source code of a module might be identical on a Windows PC and on a Macintosh except for the declaration of the break key which has the Ascii value 172 on a Windows PC and 185 on a Macintosh. This problem is usually solved by storing the versions in different files (introducing unpleasant redundancy) or by storing all versions in the same file using conditional compilation such as #ifdef Windows CONST break = CHR(172); #endif #ifdef Mac CONST break = CHR(185); #endif

This is not only difficult to read but also requires a preprocessor. A much nicer solution can be obtained with version elements. Version elements occur in pairs and are represented by the symbols < and >. They store a list of exchangeable text pieces, one for every version, as shown by the following table: version name

version text piece

Windows

CONST break = CHR(172);

Mac

CONST break = CHR(185);

The text of the current version (the Windows version, say) is shown between the version elements (Figure 13). When the user clicks on a version element a menu pops up showing all version names. Selecting a name from the menu exchanges the text between the version elements with the text piece of that version. If a document contains several pairs of version elements, all pairs are switched to the selected version consistently. Version elements avoid preprocessor commands and make a multi-version program better readable. Again, this feature is language independent.

9 MISCELLANEOUS There is a potentially unlimited number of possibilities for inventing new element kinds that extend the functionality of the text editor. Many Oberon users developed such extensions and made them available to others. Some of them which are also useful for program texts are mentioned below. Stamp elements. A program text usually contains the date of its latest modification as a comment. Unfortunately programmers often forget to update this comment when they modify the program. A stamp element eliminates this danger. It automatically remembers the date of the last store operation for the text in which the element is embedded (Figure 14). When a text is stored on a file, all elements get a store message. Stamp elements react to it by updating their date. Stamp elements were developed by C. Szyperski. Error elements. The Oberon compiler generates an error text of the form: pos 58 err 39 pos 151 err 127 … This text can be processed by another Oberon command and elements can be inserted at the error positions (Figure 15). The elements retain their relative positions even if the text around them is edited. An error element displays the respective error number but when it is clicked, it displays the full error message. Error elements were developed by C. Szyperski. Info elements. Info elements serve to store and retrieve information about programs. They contain attributes of the program in which the element is embedded. Attributes can be the name of the author, a list of keywords, a modification history, or a short description of the program's functionality. There is an Oberon command that searches a set of source files for those whose attributes match a given pattern. Info elements were developed by C. Steindl.

USING ACTIVE TEXT IN A PROGRAM VISUALIZER TOOL Text elements are useful not only as extensions of the basic text editor, but they can be effectively applied to form the user interface of higher level tools1 . In this case the elements are created by the tool rather than by a person using the editor. Creating text elements in a program is easy: each element module provides a simple programming interface in addition to the command interface. As an example of a tool that uses text elements as its user interface, we will consider Scene, a system for visualizing the event flow in an object-oriented Oberon program. Scene includes an instrumenter which augments the source code of a program to be visualized so that the program creates an event list while being executed. The event list can be examined afterwards with Scene in a graphical form, and browsed by the user in various ways. A particularly useful property of Scene is its support for inspecting those parts of the source code that are relevant for the example run represented by the event

flow. A more detailed discussion of Scene can be found in a separate paper10.

10

The event flow is represented graphically as a scenario diagram. This is a notation originating from event flow diagrams used in OMT8 , but extended with some new features. In a scenario diagram, the objects (or modules) taking part in the scenario are shown by vertical lines. A message sent from one object to another is shown with a horizontal arrow from the sender to the receiver. The time flows from top to bottom. In our notation, returns from method invocations are indicated with dashed arrows, and collapsed calls (call and return in the same arrow) are shown with double-lined arrows. The instrumenter parses the source text and augments method bodies with additional code. All the additional code fragments are hidden inside fold elements. This is desirable, since the same source text will be shown to the user by request, and the instrumentation code would corrupt the comprehensibility of the source. Further, the instrumenter inserts mark elements for all method definitions and method calls, serving as targets for links from the scenario diagrams to the source text. A scenario diagram, as produced by Scene, is shown in Figure 16. In spite of its graphical look, the whole diagram is a normal text: it can, for example, be edited like any other text (although this would hardly be necessary). For every horizontal arrow there is a separate line. This line consists of text elements only; there are no actual characters in the lines. The elements are either passive icon elements (space elements, vertical line fragments, etc.) or active command elements. Usually each element type provides its own specialized display method. For instance, an arrow is an active element derived from a popup element: clicking on a call (or return) arrow yields the execution of a command which highlights the corresponding return (or call) arrow. Most of the functionality of a scenario diagram is accessible through variants of a popup element, differing only in their appearance and in the contents of the menu list. Popup elements were originally developed by M. Franz but we modified them in order to make them better extensible. In general, a popup element allows arbitrary text in its menu list. If a menu list item is a command, and this item is selected, the command is executed. If an item begins with a link element, selecting the item causes the target to appear. If an item is neither a command nor a link, selecting the item causes no activity. For example, a method name in a call arrow is actually a popup element whose menu list contains commands (e.g. Scene.Collapse), hyperlinks (e.g.

Call in source), and

information (e.g. Time: 1132). Such a popup element is opened in Figure 16. Other popup elements are the names of the objects appearing above the scenario diagram; the corresponding menu items contain, for example, links to the interface specification of the class of the object, to the OMT state diagram containing the class, and to the module containing the implementation of the class. Further popup elements are the small buttons appearing in vertical object bars; when opened, these elements show information about the object at that point of the execution. Implementing the scenario diagram on the basis of the text framework was remarkably easy and fast: the central building blocks were the general-purpose text elements which could be employed as such or with slight modifications. The first version of Scene containing all the essential features was developed by a person having no deep knowledge about Oberon in less than two months.

RELATED WORK Several authors have described the idea of objects floating in a text11, 6. A special form

11 of such documents are active cookbooks12 that store recipes for adapting frameworks. Such cookbooks contain buttons that lead to examples, invoke special tools, and generate customized code making use of a knowledge base. English et al.13 introduce the term active documents for structured documents, which contain objects that can be acted upon and can themselves act upon other objects. Their system is implemented in Lisp which allows the user to add new objects to a document at run time. This is similar to Oberon although Oberon is not an interpreted but a compiled language. An interesting form of active documents has been described for the Grif editor14, 15. Grif documents can be composed from user-defined elements (texts, numbers, icons, etc.) for which a certain screen representation has to be defined. Editing such elements generates events for which the user can specify the actions that should be triggered in the application. Thus the document's reaction to editing operations (e.g., mouse clicks, keyboard input) can be customized. The difference between Grif and our approach is that Grif documents always confom to a certain structure while our elements can be embedded in any text. In Grif, a document's structure, its representation, and behaviour is defined in a specification file using some meta language. We do not use a specification file but define new behaviour by subclassing the text framework. The Oberon system allows a user to add new functionality at run time, which is not possible in Grif. Most active text implementations focus on hypertext. There are numerous hypertext systems around. The major differences between these system and our text elements are the following: • Most hypertext editors are dedicated tools while the Oberon text editor is a general purpose editor with added hypertext features. • Most hypertext systems offer some fixed functionality while the Oberon text editor is extensible and offers a potentially unlimited functionality. • Hypertext systems usually produce texts that cannot be compiled. Therefore they cannot be used for editing programs. Oberon texts with elements can be fed to a compiler. • Hypertext systems usually concentrate on linking while we also explored folding, annotating, bookmarking, etc. In fact, we found folding to be the most useful structuring feature in programs. Folding is a kind of structured hypertext that eliminates the danger of "getting lost in hyperspace"2. Some ideas of this paper were already described in Mössenböck 16 . However, that system was a dedicated editor and its implementation was not based on text elements. Thus it was not as easily extensible. The Guide system17 is a general-purpose hypertext system that offers folding, linking, and annotating (although not via text elements). Guide is a dedicated system producing documents that cannot be compiled. It is not extensible. Ince18 describes a tool for structuring programs in a top-down fashion. A program is manually divided into sections and subsections which can be collapsed and viewed at various abstraction levels. The resulting documents can be compiled. Linking or annotating are not supported and the system is not extensible. Syntax-directed editors 19-21 also structure a program hierarchically but they do that automatically based on the program's grammar. These systems can collapse procedure bodies or statement sequences within compound statements but it is usually not possible to replace the collapsed texts with pseudocode. In all systems known to us the

12 collapsed text must be a syntactic unit (e.g. a statement sequence). It is usually not possible to divide a sequence of statements or declarations into several folds according to user-specific criteria. Syntax-directed editors are language-dependent by definition: the same editor cannot be used for different programming languages, although there are systems which are able to create a language-specific editor from a language specification. Our editor is not syntax-directed and therefore not language dependent. Special hypertext systems for programs have been described, for example, by Nørmark and Østerbye 22 and by Salminen 23 . These systems infer links from the syntactical structure of the program automati cally. Links are often typed (e.g., isDefinedAs, isUsedIn, affects, etc.) and can be generated on demand. These tools are inherently language dependent since they have to know the underlying grammar. The ability to automatically set links is very convenient but we also find it useful to be able to set links according to semantic relationships that are not reflected in the grammar. This is also pointed out by Welsh and Han24. A kind of folding is also offered by outline editors 25 which allow a text to be structured hierarchically into sections and subsections. All subsections of a section can be collapsed (hidden) or expanded. The difference to fold elements is that fold elements are not restricted to subsections but can appear anywhere in the text and that collapsing does not just mean hiding a text but replacing it with another text. Furthermore, the text produced by outline editors cannot be fed to a compiler. Finally, the Web system26 and its literate programming approach allows designing and describing a program hierarchically according to the method of stepwise refinement. A program can be described using pseudocode actions which are refined later in the text. However, a literate program is the exact opposite of hypertext. It is intended to be read sequentially like a book while hypertext allows and encourages selective browsing.

SUMMARY Active text supports interactive reading of documents. It is a step beyond the passive paper metaphor and effectively exploits the capabilities of modern computers. Active text is best known as—but not restricted to—hypertext which is an old and useful idea. Hypertext has been around for centuries in the form of encyclopedias and was adopted by computer scientists in the sixties27, 28. We found that active text is especially useful for structuring and reading programs, since they are usually not read sequentially but selectively. In summary, we tried to convey the following messages: • Hypertext facilities such as folding, linking, and annotating can be very useful to programmers. In numerous examples we showed how hypertext can be applied for abstracting, commenting, structuring, and viewing code. We also argue that program texts should make better use of fonts, styles and pictures as it is common in other text documents. Our suggestions have been tried out for years and found to be useful not only in the authors' daily work but also in teaching. • We have shown how the proposed functionality can be implemented as a set of text elements handled by an ordinary text editor. This approach seems interesting because new functionality can be added without modifying, recompiling, or relinking the editor. Any user can invent new kinds of elements thus extending the capabilities of the editor.

13 • We believe that language-independent hypertext facilities are more flexible than language-dependent ones. Our facilities cannot only be applied to Oberon programs but also to C or Lisp programs. In fact, they are also useful in ordinary texts. We have used fold elements for outlining papers, for maintaining address files, and for structuring data shown by a debugger. • Oberon supports the development of extensible software in a simple and flexible way. Commands allow adding new functionality to a program and invoking it directly without writing invocation code. New functionality can be added at run time without disrupting the work of users. Users load just the functionality that they need for their work and do not have to bother about a bulk of unnecessary features. Oberon's extensibility comes from the fact that it is an open system. Any program can access the exported data and operations of other programs. There is a single shared address space. Memory integrity is guaranteed by strong type checking and the use of a garbage collector. • We argue that Oberon's text framework is successful because it is simple. There is just one "hot spot" which the user can parameterize, namely the elements slot into which he can plug custom-made elements. In spite of its simplicity the framework is so many-facetted that people have found it useful for doing things that the original authors did not even think of (e.g. the scenario browser described above). Our experience is that only if a framework is simple enough, people will find it worthwhile to extend it. The Oberon system is available via ftp for all major platforms (ftp.inf.ethz.ch, /pub/Oberon). The source code of the text elements described in this paper can be obtained from ftp.ssw.uni-linz.ac.at, /pub/Oberon/Sources/Miscellaneous or from http://www.ssw.uni-linz.ac.at /Public.html.

ACKNOWLEDGEMENTS Many people have contributed to our work. N. Wirth and J. Gutknecht designed the Oberon system with its powerful extension mechanisms. C. Szyperski designed the active text framework stimulating others to invent new text elements. Many of our colleagues have provided us with ideas and feedback. We would like to thank them as well as the anonymous referees who pointed us to some shortcomings in the first version of this paper. Our work was supported by the Austrian "Fonds zur Fö rderung der wissenschaftlichen Forschung" under the project number P10271-TEC and by the Finnish Academy of Sciences.

REFERENCES 1.

E. A. Bier and A. Goodisman, 'Documents as User Interfaces', Proceedings of the International Conference on Electronic Publishing, Document Manipulation & Typography, Cambridge University Press, 249-262 (1990).

2.

J. Conklin, 'Hypertext: An Introduction and Survey', IEEE Computer, 20, 17-41 (1987).

3.

N. Wirth and J. Gutknecht, 'The Oberon System', Software—Practice and Experience, 19, 857-893 (1989).

4.

M. Reiser, The Oberon System—User Guide and Programmer's Manual, Addison Wesley, 1991.

5.

H. Mössenböck and N. Wirth, 'The Programming Language Oberon-2', Structured Pro gramming, 12,

14 179-195 (1991). 6.

C. A. Szyperski, 'Write-ing Applications: Designing an Extensible Text Editor as an Application Framework', Proceedings of the TOOLS'92 conference, Dortmund, 1992.

7.

K. Brockschmidt, Inside OLE 2, Microsoft Press, 1994.

8.

J. Rumbaugh et al, Object-Oriented Modelling and Design, Prentice Hall, 1991.

9.

E. Gamma, R. Helm, R. Johnson, and J. Vlissides, Design Patterns—Elements of Reusable ObjectOriented Software, Addison-Wesley, 1994.

10.

K. Koskimies and H. Mössenböck, 'Scene: Using Scenario Diagrams and Active Text for Illustrating Object-Oriented Programs', Accepted for the International Conference on Software Engineering (ICSE'96), Berlin, (1996).

11.

A. Weinand, E. Gamma, and R. Marty, 'ET++—an Object-Oriented Application Framework in C++', Proceedings of the OOPSLA'88 conference, SIGPLAN Notices, 23, 46-57 (1988).

12.

W. Pree, G. Pomberger, A. Schappert, and P. Sommerlad, 'Active Guidance of Framework Development', Software—Concepts and Tools, 16, (1995).

13.

P. M. English et al., 'An Extensible, Object-Oriented System for Active Documents', Proceedings of the International Conference on Electronic Publishing, Document Manipulation & Typography, Cambridge University Press, 263-276 (1990).

14.

V. Quint and I. Vatton, 'Combining Hypertext and Structured Documents in Grif', Proceedings of the ACM conference on hypertext ECHT'92, ACM Press, 1992, 23-32.

15.

V. Quint and I. Vatton, 'Making Structured Documents Active', Electronic Publishing, 7, 55-74 (1994).

16.

H. Mössenböck, 'Ein Programmeditor mit Hypertext-Fä higkeiten', in Informatik-Fachberichte 249, Springer-Verlag, 1990.

17.

P. J. Brown, 'Interactive Documentation', Software—Practice and Experience, 16, 291-299 (1986).

18.

D. C. Ince, 'A Software-Tool for Top-down Programming', Software—Practice and Experience, 13, 687-695 (1983).

19.

A. N. Habermann and D. Notkin, 'Gandalf: Software development environments', IEEE Transactions on Software Engineering, 12, 1117-1127 (1986).

20.

J. Welsh, B. Broom, and D. Kiong, 'A Design Rationale for a Language Based Editor', Software– Practice and Experience, 21, 923-948 (1991).

21.

M. V. Zelkowitz, 'A Small Contribution to Editing with a Syntax-Directed Editor', SIGPLAN Notices, 15, 1-6 (1984).

22.

K. Nørmark and K. Østerbye, 'Representing Programs as Hypertext', Proceedings of the Nordic Workshop on Programming Environments Research, Lund, June 1994, Report LU-CS-TR: 94-127.

23.

A. Salminen, J. Koskinen, and J. Paakki, 'HyperSoft: An Environment for Hypertextual Software Maintenance', Proceedings of the Nordic Workshop on Programming Environments Research, Lund, June 1994, Report LU-CS-TR: 94-127.

24.

J. Welsh and J. Han, 'Software Documents: Concepts and Tools', Software–Concepts and Tools, 15, 12-25 (1994).

25.

W. Hershey, 'Idea Processors', BYTE, 337-350 (1985).

26.

D. E. Knuth, 'Literate Programming', The Computer Journal, 27, 97-111 (1984).

27.

D. C. Engelbart, A Conceptual Framework for the Augmentation of Man's Intellect, in Vistas in Information Handling, vol. 1, Spartan Books, London, 1963.

28.

T. H. Nelson, 'Getting it out of our System', in Information Retrieval: A Critical Review (G. Schlechter, ed.), Thompson Books, Washington, 1967.

15

Figures

Figure 1. Elements floating in a text Figure 2. Text framework with embedded elements Figure 3. Fold elements in expanded and collapsed mode Figure 4. Abstracting from details: a) abstract view; b) detailed view Figure 5. Hiding lengthy comments Figure 6. Collapsing a program to its skeleton Figure 7. Stepwise refinement Figure 8. A link between two related pieces of code Figure 9. Text with links to currently set bookmarks Figure 10. Automatically generated list of links to all mark elements in a text Figure 11. A sample dictionary text Figure 12. An annotation displayed as a popup window Figure 13. Switching a text piece from the Windows version to the Mac version Figure 14.

A stamp element showing the date of the last modification

Figure 15 . Error elements mark error positions in a compiled text Figure 16. A scenario diagram in Scene

16

Figure 1. Elements floating in a text

17 Text

Elem

elem

Insert Delete …

Display Print Load Store Copy Track

GraphicElem

TableElem

PopupElem

Display Print …

Display Print …

Display Print …

Figure 2. Text framework with embedded elements



18

Figure 3. Fold elements in expanded and collapsed mode

19

Figure 4. Abstracting from details: a) abstract view; b) detailed view

20

Figure 5. Hiding lengthy comments

21

Figure 6. Collapsing a program to its skeleton

22 first refinement

second refinement

Figure 7. Stepwise refinement

third refinement

23

Figure 8. A link between two related pieces of code

24

Figure 9. Text with links to currently set bookmarks

25

Figure 10. Automatically generated list of links to all mark elements in a text

26 "Node" Node of a binary tree containing strings. "Insert" Inserts a name in the tree. The name is always inserted as a leaf.

father new "Delete" …

Figure 11. A sample dictionary text

27

Figure 12. An annotation displayed as a popup window

28

Figure 13. Switching a text piece from the Windows version to the Mac version

29

Figure 14.

A stamp element showing the date of the last modification

30

Figure 15 . Error elements mark error positions in a compiled text

31

Figure 16. A scenario diagram in Scene

Suggest Documents