next up previous contents index
Next: 12. Attributes Up: II. Widget Commands Previous: 10. Index commands   Contents   Index

11. Elements

Elements are the key concepts used in the sgml widget: Most operations affect elements and the element widget command is the most powerful SGML related command of the sgml widget.

11.1 Element names and element handles

Making elements in an SGML document accessible for Tcl commands presents a difficulty in the possible semantics of these commands: Sometimes, it is necessary to refer to all elements of a specific element type at once. For example, the user may want to set the text properties of a heading to a specify font family or a specific font weight such as bold. Most of the time, the user will want to set all headings (of a particular type) to this font family and weight; therefore, the user wants to refer to the element type.

Sometimes, however, the user may want to refer to a single element in the document instance. For example, the user may want to extract the contents of a specific element and therefore has to refer to that individual element inside the document. Of course, the user does not want to extract the content of all elements of a certain type, but the contents of a single individual element. Therefore, the user wants to refer to an element instance.

The sgml widget solves this problem by providing two ways to access SGML elements: element names and element handles. Element names and element handles can not be used interchangeably; some of the widget commands (or subcommands of widget commands) expect element handles as parameters; some expect element names. It should be clear from the semantics of the command which type of parameter is expected; if you find that you want to use a command that expects an element handle, but you want to provide an element name, the command is not appropriate for achieving the desired effects.

11.1.1 Element names

Element names refer to elements that are defined in the DTD by using the same name for referring to the element that has been used in the <!ELEMENT...> statement in the DTD.

\epsfbox{images/attn.eps} Widget commands that take element names as parameters affect all elements with that name in the document instance.

11.1.2 Element handles

An element handle is a Tcl-token that refers to a single element in the document instance. The primary purpose is to identify a specific element in the document instance and to select this element for operations.

Element handles are created by the sgml widget on demand and remain valid as long as the element referred to exists. Element handles may be obtained in three ways:

Widget commands that take element handles as parameters affect only one element in the document instance (and possible the children of this element), regardless of whether there are any other element with the same name in the document.

11.2 The element widget command



The element command


element allowed index ?index2?
  returns a list of elements allowed at index.
element at index
  returns the sgml element at index.
element attlist element
  returns information about the attributes for an element.
element bind element ?sequence? ?script?
  sets or queries the event bindings for an element.
element cget element option
  returns the value of an element configuration option.
element check handle
  performs a quick check of an element.
element configure ?specs?
  configures element
element content handle
  returns the element content.
element declare name
  declares a new element type.
element defined ?name?
  returns information about defined element types.
element delete handle
  deletes element.
element exclusions name
  returns the exclusion list for an element.
element flags handle ?? ?value?
  sets or returns the application defined flags for an element.
element inclusions name
  returns the inclusion list for an element.
element index handle ?end?
  returns the index for element
element insert element index ?index2?
  inserts a new element at index. If index2 is supplied, all data between index and index2 is enclosed in the new element.
element instanceconfigure handle ?specs?
  configures a specific element.
element name handle
  returns the name of a specific element
element next handle
  returns the first element following a specific element.
element omittag handle
  returns the tag omission status of an element.
element parent handle
  returns the parent of an element.
element position handle
  returns the numerical position of an element within it's parent.
element previous handle
  returns the first element preceeding a specific element.
element remove handle
  removes the element, but keeps the element contents.
element rename handle ?name?
  if name is provided, the element is renamed to name. If name is omitted, the command returns a list of names to which the element can be renamed.
element search name index ?index2?
  searches for an element name starting an index and returns a handle for the first matching element. If index2 is provided, the start tag of the element must not occur later that this position. The command returns an empty string if no element with the specified name is found in the search range.
element split index
  splits the element containing index into two elements of the same type. All data to the right of index is moved into the second element.
element undeclare name
  removes the declaration of an element type.
element valid handle
  returns a boolena value indicating whether a given element is valid or not.


11.2.1 Using the element command

11.2.1.1 Finding an element at a given position

The command element at can be used to determine which element contains a given position in the document. Most of the time, the element containing the insertion cursor will be retrieved with:

  .s element at insert

A slightly more complex example is given below. This script traces the location of the mouse cursor and sets the title of the Tk application window to the name containing the element.

{}
  proc motion_proc { x y } {
    set ref [ .s element at @$x,$y ]
    if { $ref != "" } {
     wm title . [ .s element name $ref ]
    }
  }	
  bind .s <Motion> {motion_proc %x %y}
Please note that you should not take this example too seriously. In a real-world application, you would probably not want to set the title of the the application window, especially if you are concerned about performance issues. Configuring the text of a Tk label widget is usually much faster than setting the window title which involves the overhead of the ICCCM protocol to communicate with the window manager.

11.2.1.2 Finding the parent element

An element handle for the parent element of an element can be retrieved by the element parent command which takes one parameter, the handle for the element for which the parent is requested. The element parent command returns a handle for the parent element of the element:

  .s element at insert
$\Rightarrow$ E420a12c
  .s element name E420a12c
$\Rightarrow$ SECTION
  .s element parent [ .s element at insert ]
$\Rightarrow$ E4644072
  .s element name E4644072
$\Rightarrow$ CHAPTER

The element parent command returns an empty string if a handle for the top-level element has been used:

  .s element parent [ .s document element ]
$\Rightarrow$ ""


11.2.1.3 Accessing the element content

The element content command makes it possible to access the contents of an element. Like the element parent command, it takes an element handle to refer to a specific element in the document instance. The content of the element is returned in a special format. This format is a list of specifier-content pairs that represents the contents of the element in the order in which they appear in the document text.

Each element of the list returned by the element content command is a pair that has a specifier character as its first element. The specifier character is used to distinguish different kinds of element content. The element content appears as the second element of each pair.

Figure:
\begin{figure}\begin{center}
\leavevmode\epsfbox{images/example4.eps}\end{center}\end{figure}

For example, the contents of the EXAMPLE2 element in figure [*] would be returned as the following list:

 
{{D {Line 1}} {E E8561c80} {D {Line 2}}}

This list has three elements, each element being a list itself. Each of these embedded lists contains a specifier character that gives information about the content type of the embedded list and the content itself (formatted in such a way that it can be retrieved with Tcl list command, e.g. with lindex).

The first pair in this list consists of the two elements D as th specifier character and {Line 1} as the content. The specifier D states the the second element of the pair contains data. The second pair in the list contains the specifier E, denoting an element handle as the second pair element.

The following table lists the content specifiers that are returned by the sgml widget together with the content type they denote:

D PCDATA formatted as a proper list element
E An element handle for a subordinated element
N An entity name
R A record end character

These commands can be used to implement rudimentary document traversal. For example, the following script would traverse the document tree and print an indented structural representation of the document in the sgml widget .s

11.2.1.4 Finding the location of an element

Many of the examples above have used an index for retrieving an element handle, but sometimes it is necessary to determine the location of an element in the SGML document. The sgml widget provides the element index command for this purposes.

This command expects an element handle as a parameter an returns an index string that can be used in sucessive Tcl commands. If used with only one parameter ref, the command returns the location of the start tag of the element referenced by ref. The location returned is the position immediately to the left of the element tag, i.e. it is outside of the element:

  set ref [.s document element]
$\Rightarrow$ E8644200
  .s element index $ref
$\Rightarrow$ 1.0

In a second form, the element index command accepts the additional keyword parameter end after the element handle parameter and returns the location of the end tag of the element.

Again, the location returned is the position immediately to the left of the element tag, i.e. it is inside the element:

  set ref [.s document element]
$\Rightarrow$ E8644200
  .s element index $ref end
$\Rightarrow$ 13.24

The element index command can be used for several interesting purposes. For example, it is possibe to make an element responsive to mouse clicks as demonstrated in the following script:

  proc show_name { x y } {
    set ref [ .s element at @$x,$y ]
    if { $ref != "" } {
      puts "Element [ .s element name $ref ] selected"
    }
  }	

  set eref [ .s element at insert ]
  set idx_start [ .s element index $eref ]
  set idx_end [ .s element index $eref end ]
  .s tag add myTag $idx_start $idx_end
  .s tag bind myTag <ButtonRelease> { show_name %x %y }
  
This script makes use of the tag command. The tags inserted by the tag command are essentially text widget tags and the command name tag has been retained for compatibility with the text widget. It is important not to confuse these text widget tags with element tags that relate to the element strucutre of the SGML document. More details on text widget tags can be found in the documentation for the Tk text widget.

11.2.1.5 Inserting elements

New elements are inserted into the sgml widget using the element insert widget command. The element insert command is a subcommand of the element widget command that is used to perform most element-specific operations on the document instance. An overview of the element command is presented in table [*], but most of the command options are explained in detail in the following chapters.

The element insert command takes two parameters to specify what type of element to insert and where to insert this element. The following command would insert a new element P before the three characters before the end of the document.

  .s element insert P end-3c
$\Rightarrow$ E3514a42

The first parameter for the element insert command is the name of an element as it has been defined in the DTD. (The current implementation of the sgml widget requires the correct case for element names.)

The second parameter denotes the location where the element should be inserted into the document. Locations are specified as indices in the same way as text widget indices.

The element insert command verifies that the element can be inserted at the specified location and refuses to insert the element if the DTD does not allow an element of the specified kind to appear at that location.

Inserting an element that is not specified in the DTD is an error:

  .s element insert BLA insert+2c
$\oslash$ Element "BLA" not found in dtd

The element insert command returns a handle for the new element if the element insertion was successful. If the DTD does not allow the insertion of this element at index, an error is signalled.

It is possible to determine which elements can be inserted at a location in the document by using the element allowed command. This command uses exactly the same mechanisms as element insert command, but it returns a list of insertable elements instead of inserting an element. The following command can be used to determine the elements that could be inserted at the current location of the insertion cursor:

  .s element allowed insert

The element allowed command return a Tcl list with element names. Each of these names could be used as a parameter to the element insert command. The element insert command, in turn, is guaranteed to return a new element handle for any element of the list returned by the element allowed command (provided, of course, that both commands refer to the same absolute position in the document and that the element structure has not been changed between the invocations of the two commands. Therefore, the following sequence of commands will never fail:

  set l [ .s element allowed insert ]
  if { [ llenght $l ] > 0 } {
  .s element insert [ lindex $l 0 ] insert }
$\Rightarrow$ E8641e80

11.2.1.6 Enclosing data in new elements

It is possible to enclose data already present in a new element by providing a second index to the element insert command. If a second index is provided, all data in the range from the first to the second index becomes the content of the new element.

The sgml widget will not insert an enclosing element if any of the following conditions are met:

When enclosing exisiting data in a new element, the sgml widget does not verify that the enclosed data is compatible with the elements content model (apart from checking that the element has not been declared as an empty element). Adding further markup may be necessary in order to make the element valid.

A convenient way to turn a portion of the document into a new element is to use the selection for these purposes. When the user selects a region of the text with the mouse, the two indices sel.first and sel.last can be used to refer to the boundaries of the selected text. The following command encloses the currently selected text with the element em:

  .s element insert EM sel.first sel.last
$\Rightarrow$ E8641e80

Hint: If you implement this approach in an X11 environment and provide a listbox for the user to choose an element, make sure to prevent the listbox from exporting the selection by using the option -exportselection 0 when creating the listbox. If you do not inhibit the selection export for the listbox, the listbox will steal the selection from the sgml widget when the user selects an entry in the list. This will result in the sgml widget failing to enclose the selected data because the selection has been removed and the index specifications have become invalid.

Please refer to the documentation of the Tk text widget for any details about the selection mechanism.

Attempts to enclose data in a new element results in an error message if the range specified for enclosure is invalid with respect to any of the conditions mentioned above.

11.2.1.7 Splitting elements

An element can be split into two elements of the same type by using the pathname element split command. The element split command takes one argument: the index at which the enclosing element should be split. It terminates the enclosing element by creating a new end tag for the element at the position specified by index and starts a new element of the same type by creating a new start tag immeditely behind the ent tag at index. All data in the old element that was located behind index is moved into the new element.

11.2.1.8 Renaming elements

An sgml element can be renamed if this operation is allowed by the DTD. To rename an element, the command


pathName element rename handle ?name?

can be used. If the argument name is omitted, the command returns a list of element names to which the element identified by handle can be renamed. If handle can not be renamed to another element, this list will be empty.

If the name argument is provided, the element type of the element identified by handle will be changed to name. If handle can not be renamed to name, the command generates an error.

When an element is renamed, the current attributes of the element will be retained if they are compatible with the attribute definitions of the new element type. Attributes are considered to be compatible if they have the same name, the same declared value, and the same defaullt value type. Incompatible attributes will be dropped when an element is renamed.

11.2.1.9 Deleting elements

Individual elements in the document instance can be deleted by using the element delete command. The command can be used to delete any element in the document instance other than the document element:

  .s element delete [.s document element]
$\oslash$ Can't delete top-level element

Deleting an element destroys the element and all of its child elements including their data content. Any handles to the deleted element and its children become invalid when the element has been deleted:

  set ref [ .s element at insert ]
$\Rightarrow$ E8561c80
  set parent_ref [ .s element parent $ref ]
$\Rightarrow$ E85582a0
  .s element delete $parent_ref
  .s element name $parent_ref
$\oslash$ Invalid element handle "E85582a0"
  .s element name $ref
$\oslash$ Invalid element handle "E8561c80"

11.2.1.10 Removing element tags

To remove an element without destroying the element content, the element remove command can be used. This command removes the enclosing element tags and inserts the contents of the removed element into it's parent element at the postion of the removed element.

The element remove command can be used to remove any element in the document instance other than the document element:

  .s element remove [.s document element]
$\oslash$ Can't remove top-level element

As opposed to the element delete command, removing an element with the element remove command does not destroy any data but removes the markup around the data embedded into the removed element.

  set ref [ .s element at 3.17 ]
$\Rightarrow$ E8561c80
  .s element name $ref
$\Rightarrow$ P
  set parent_ref [ .s element parent $ref ]
$\Rightarrow$ E85582a0
  .s element remove $parent_ref
  .s element name $parent_ref
$\oslash$ Invalid element handle "E85582a0"
  .s element name $ref
$\Rightarrow$ P

Removing an element can be seen as the inversion of enclosing data in a new element.

11.2.1.11 Searching for elements

It is possible to search for elements with the pcrmelement search widget command. This command has has the following general form:


pathName element search name index ?index2?

The command searches for the first ocurrence of an element with a name that matches the name argument and returns a handle for this element or an empty string if no such element is found.

The search starts at the index1 and stops at the end of the document (or at index2 if provided). The following example shows a procedure that accepts an element name as argument and returns the number of elements with this name in the current document:

  proc countElement { name } {
    set idx "1.0"
    set count 0
    for { set handle [ .s element search $name $idx ] } \
        { $handle != ""} \
        { set handle [ .s element search $name $idx ] } {
          incr count
          set idx "[ .s element index $handle]+1c"
        }
    return $count
  }

11.2.1.12 Checking element status

Elements may become invalid during the editing process, e.g. because a required child element was deleted or a required attribute still needs to be specified. The current status of an element can be checked with the pcrmelement valid widget command. The command has has the following general form:


pathName element valid handle

The result of the command is a boolean value that indicates whether the element identified by handle is currently valid or not.

While the pcrmelement valid command returns only the current status of an element, the content of a single element can be checked with the pcrmelement check widget command.


pathName element check handle

The command performs a quick check of the element identified by handle and returns a list of error messages that describe the problems that have been found. If no problems were detected with the given element, the command returns an empty list.

  .s element check E8641e80
$\Rightarrow$ Missing required attribute "ID"

The pcrmelement check command performs only a quick test of the element structure, but it does not carry out an in-depth validation of the element content. Please refer to the description of the pcrmvalidate widget command in section [*] for more details.

11.3 Configuring elements

Elements can be configured to modify the text properties of their contents. There are two levels of element configuration: element type configuration and element insance configuration. When configuring an element type with the pathname element configure widget command, the configuration options apply to all elements of the specified type. The command

  .s element configure HEADING -bold 1

results in all elements of type heading being shown in bold face. Settings for the element type can be overridden by configuring element instances with the pathname element instanceconfigure widget command. The command

  .s element instanceconfigure E120ea45 -family times

results in a times-font being used for the specific element instance E120ea45, regardless of which font-family configuration options have been set for the corresponding element type.


11.3.1 Element configuration options


next up previous contents index
Next: 12. Attributes Up: II. Widget Commands Previous: 10. Index commands   Contents   Index
TkSGML Reference Manual