home *** CD-ROM | disk | FTP | other *** search
-
-
- Attribute Support
-
- Jason Crawford
- June 3, 1989
-
- Much talk has been going around the industry about hypertext. We do
- not want to enter into any heated discussion on the issue, but we believe
- that one of the basic ingredients of a hypertext system is the ability to
- bind metainformation into text. In its simplest forms this information
- might simply be a flag that indicates that a section of the text is to
- appear in a certain color or font when displayed. In an advanced form
- this information may refer to an action to take when the associated text
- is manipulated.
-
- In order to turn some the armchair hypertext programmers into real
- hypertext programmers, we have taken a first step by giving E macro pro-
- grammers the ability to imbed information within their text. We call
- this first step "attribute support."
-
- In this initial release of we allow a macro application to request a
- set of attribute "classes" to support its needs. How the requested
- attribute classes are used is determined by the application. That
- application need not worry about other applications using the same
- attribute classes for other purposes since other applications will be
- granted other attribute classes for their use.
-
- In this release of attribute support, only 256 attribute classes are
- allowed. Attribute class 0 is reserved for use as a wildcard or an error
- flag. Class 1 is now reserved for controling the displayed color of text.
- Classes 2..63 are reserved for future internally supported uses, and the
- remaining 192 attribute classes can be allocated to macro applications
- through the allocate_attr() function.
-
- Once an application has been allocated an attribute class, "attribute
- records" of that class can be inserted into the text of the document with
- the insert_attribute statement. The position of an attribute record is
- generally specified with four coordinates: fileid, line, column, and
- offset. The first three of these coordinates should already be well
- understood by macro programers, but the fourth coordinate is new. In this
- initial version of attribute support, no attribute record or character can
- occupy the exact same location, so the offset coordinate (which is either
- negative or positive; but never zero) indicates whether the attribute
- record is before or after the character of the specified column. If
- several attribute records exist at the same column, then the offset
- coordinate also specifies the relative position of those attribute
- records. For example, lets say that we have a line of text in our
- document as follows:
-
- This is my line of text.
-
- And let's say that there are three attribute records at the same
- column as the "m" in the word "my", as follows:
-
- [arA][arB]m[arC]
-
- If this is the case, then the location of attribute record A is column 9
- and offset -2. Attribute record B is at offset -1, and Attribute Record C
- is at column 9 offset +1.
-
- Each attribute record has a class field, a value field, and a support
- field. The class field (as described above) is a flag that indicates what
- kind of information the attribute record conveys. The value field can
- hold a value from 0..64k-1, and the meaning of the value field is defined
- by the application that is supporting the attribute class specified in the
- class field. The support field conveys information that the editor can
- use to provide internal support. For example, an attribute records with a
- class of COLOR, a value field of 30, and a support field of PUSH indicates
- that the text following this record should be colored ???? (which
- corresponds to a value of 30), and that that color should be used until a
- corresponding COLOR POP attribute record is encountered in the text.
-
- In general, these attributes will not be visible to the user,
- but they are accessable within the macro language [see "query_attribute"].
-
- An attribute class can follow one of many attribute models. An
- attribute model defines the extent of influence of each attribute record
- of each class using that attribute model. The simplest attribute model is
- the tag model. An attribute record that has a class that uses a tag model
- just denotes a position in a file. A typical usage would be to mark
- the location of footnotes or hidden text.
-
- A second attribute model is what I will call a "set-until-next-set"
- model. In this model, an attribute record rules over all the text
- following itself and preceding the next attribute record in the document
- that has the same class. For example, if one turns on font A
- just before column 2 and turns on font B just before column 32, then
- characters in columns 2..31 should have a font type of A, and characters
- after column 31 and characters after the present line should have a font
- type of B.
-
- The Color class is the first internally supported attribute class in
- E. Its purpose is to allow an application to control the color (foreground
- only on PS/55's) of the text when displayed by E. The Color class
- attributes use a push/pop attribute model. The basic concept behind this
- third model is that all text following an attribute that pushes a color
- will appear in that color until a color-pop attribute record occurs. Text
- following a color-pop attribute record will be displayed in the same color
- as the text that occured before the previous color-push attribute record.
- Using this model, an application can nest several levels of color by
- inserting several color-push attribute records in the text before a
- color-pop attribute record. If no color attributes appear in the text,
- then the whole text appears in the default background color. If, at a
- certain point in the file, the number of pops occuring earlier in the file
- is equal to (or higher than) the number of pushes, then the default color
- is used until the next color push occurs. If a color push attribute
- record lacks a corresponding color pop attribute record, then the pushed
- color will remain active until the end of the file. The included demo
- will attempt to clarify any confusion on the matter.
-
- As you play with push/pop modeled attribute classes, you will notice
- that the push/pop model does not use the value field of a pop attribute
- record. This is because the pop record indicates that the last push
- attribute record of the specified class should be popped (regardless of
- its value).
-
- We think the push/pop model is a good one. We encourage macro
- programers to use the push/pop model for attribute classes that they
- engineer because all support that we add for the color's push/pop model
- can be used by applications using a push/pop model.
-
- [assert: at this point reader understands colors and push/pop, and binding]
-
- We have built attribute support so that copying, moving, and deleting
- a character will take the same action on the attribute records bound to
- that character as is done to that character. To illustrate this, create a
- line with a variety of color attributes. Just begin editing the text.
- Notice that if you deleted a character that had a Push-Color attribute
- record with it, then the region after that character will revert to the
- previous color rather than the color that was pushed at that character.
- The same can be seen with moving, copying, and deleting marked regions,
- but that may be more difficult to see.
-
- Although the push/pop model of attribute support is fairly
- straightforward, we expect macro programmers to initially run into
- some complications.
-
- One of these complications is crossing of attribute pairs of the same
- class. The push/pop model only supports "imbedding" of regions within
- other regions. If one tries to specify two "overlapping" regions with
- attribute records of the same class, one will run into problems because the
- new and old attribute records will be interpretted by other applications
- as imbedded regions. If it becomes necessary to have overlapping regions
- of the same class, then an alternative attribute model should be designed.
- [Demo this one.]
-
- A second inconvenience that the macro programmer will face is the
- lack of support for attribute strings. This means that the insertline and
- replaceline statements only insert attributeless lines into a file, and
- the getline statement will only fetch the text of a line. The typical
- solution to this problem is to use copy, move, and delete actions on
- marked regions rather than insertline's, replaceline's, and getline's.
-
- A third dilemna is that attribute support is provides an API;
- but no user interface. We expect that macro programmers will be facing
- many dilemna. For example, "What should be done
- with attributes attached to a character that the user wants to remove or
- replace?" This is a user interface dilemna. Simply deleting the
- character and all its associated attribute records may not provide the
- best user interface because if the attribute records for a character were
- deleted, and one of those attributes had a color CLASS (using a push/pop
- model), then the color of almost all text from that character to the EOF
- will change. [See Demo ???] This is probably not what was the user intended,
- but deciding what was intended is not necessarily easy.
- This version of attribute support does not attempt to make such
- decisions. Instead, it leaves such decsions to macro programmers, so that
- the community of macro programmers can experiment with serveral user
- interfaces. In a few weeks we expect several UI's will emerge, and we
- will begin supporting them.
-
- This version of attribute support allows a maximum of 255 attributes
- per line. Any attempt to add more attributes than 255 attributes will
- result in a truncation error being flagged. Similarly, shifting any
- attribute beyond column 255 will result in a truncation error being
- flagged and the truncated attribute record being lost.
-
- This first version of attribute support does not provide any means for
- saving attributes in a file. Such functionality can be expected in
- upcoming versions of EPM when OS/2 1.2 becomes more readily available.
- Until that time, macro programmers can obtain (undocumented) macros from
- JASON at YKTVMV that support the loading and saving of files and their
- attributes under OS/2 1.1.
-
- Lastly, EPM is in a rapid state of flux. This is especially true of
- attribute support. Any documentation provided for attribute support is
- likely to become quickly outdated. Therefore macro programmers should
- monitor the EPM FORUM on the IBMPC conference disk to get the most
- up-to-date information.
-
- The Classes
-
- This version of attribute supports several predefined attribute
- classes to various extents:
-
- COLORCLASS
- This attribute class can be used to color regions of text. The color
- used is determined by the value field of attribute records of this
- class. The values should be the same as those used for CGA monitors
- except that "flashing" is not supported.
-
- HIDNCLASS
- Attribute records of this class act as tags that flag the location of
- text that is hidden. At the moment, hidden text is text that has been
- temporarily hidden. This is implmented by a set of macros that move
- the text to a hidden file. For further details, please refer to the
- macros provided with attribute support.
-
- This class is currently only experimental, so please feel to modify
- the supporting macros if you want to do some experimenting of your
- own. If you come up with something clever, please let the rest of us
- know.
-
- ASSOCCLASS
- Attribute records of this class flag the existance of an associated
- string. This class is helpful when implementing buttons within a
- document (see BUTTONCLASS), and it could be used by a spell checker
- for remembering alternate spellings or by a voice recognition system
- for remembering probable alternate interpretations. For further
- details, please refer to the macros provided with attribute support.
-
- BUTTONCLASS
- This attribute class delimits a region (with the push/pop model) that
- should be associated with a command. This attribute class works in
- conjuntion with the ASSOCCLASS attribute class. For further details
- see the BUTTONS.E file provided with this package.
-
-
- Attribute Statements
-
- The Attribute Support API consists of two macro language statements:
- attribute_action, insert_attribute, and query_attribute.
-
- Query_Attribute
- this statement allows a macro program to deterine what
- attribute record can be found at the specified location.
-
- var Class
- returns the class of the found attribute record. A value of
- zero is returned if no attribute was found. A value between
- 1 and 63 is returned if an internally supported attribute
- record was found. A value from 64 to 255 is returned if an
- application supported attribute record was found. The
- meaning of an application supported attribute record is not
- predictable at compile time. Some administrative macros
- will be provided for determining the meaning of a macro
- during runtime.
-
- var Value
- returns the value of the found attribute record. Its value
- is unchanged if no attribute record was found at the
- specified location.
-
- var IsPush
- returns the value of the support field of the found
- attribute. This parameters value is unchanged if no
- attribute record was found at the specified location.
-
- Offset
- The offset of the position being queried. Zero is an
- illegal offset. A negative value indicates a position
- before the specified character location, and a positive
- value indicates a value to the right of the specified
- character location.
-
- ...[ar-2][ar-1][char][ar+1]...
-
- Column
- The column number of the position being queried.
-
- Line
- The line number of the position being queried.
-
- ViewID (optional)
- The fileid of the position being queried. If unspecified,
- the current file will be assumed.
-
-
-
- Insert_Attribute
- this statement (non destructively) inserts an attribute
- record at the specified location.
-
- Class
- The class of the attribute record to be inserted.
-
- Value
- The value field of the attribute record to be inserted.
-
- IsPush
- The support field of the attribute to insert.
-
- Offset
- The offset of the position being queried. Zero is an
- illegal offset. A negative value indicates a position
- before the specified character location, and a positive
- value indicates a value to the right of the specified
- character location.
-
- ...[ar-2][ar-1][char][ar+1]...
-
- If an offset is specified that is greater than the largest
- offset of an attribute record at the specified column, then
- the attribute record is placed at an offset directly to the
- right of the attribute record with the greatest offset. The
- only exception to this rule is when there are no attribute
- records with positive offset at the specified column. In
- that case, the attribute record is placed at offset 1.
- Similarly, if a negative offset is specified that is less
- (more negative) than the smallest offset of an attribute
- record at the specified column, then the new attribute
- record is placed at an offset that is one less than the
- smallest offset.
-
- If an attribute record already exists at the specified
- offset, then the old attribute record (and any attribute
- records at an offset of larger magnitude) is shifted to an
- offset of greater magnitude to vacate the specified
- offset for the new attribute record.
-
-
- Column (optional)
- The column number where the new attribute record should be
- placed. If this parameter is omitted, the current column of
- the cursor is assumed.
-
- Line (optional)
- The line number where the new attribute record should be
- placed. If this parameter is omitted, the current line
- number of the cursor is assumed.
-
- ViewID (optional)
- The fileid of the file where the new attribute record
- should be placed. If this parameter is omitted, the active
- file is assumed.
-
-
- Attribute_Action
- this statement is actually several statements. The
- first parameter determines what action is executed. We put
- several actions on this statement in order to conserve
- opcodes. Each action will be described in turn.
-
- Attribute_Action FIND_NEXT_ATTR_SUBOP
- This action finds the next occurance (not including the
- specified location) of an attribute record of the specified
- class.
-
- var Class
- input
- This specifies the attribute class of the attribute
- records of interest. A value of ANY_CLASS (zero)
- indicates that the position of the next attribute record
- of any class should be returned.
- output
- The class of the found attribute. A class of zero
- indicates that no attribute record was found.
-
- var Offset, var Column, var Line
- input
- These parameters specify the location (non-inclusive)
- where the search is to begin.
- output
- These parameters specify the location of the found
- attribute record. If none was found, then none of these
- parameters will be modified.
-
- var FileId (optional)
- The fileid of the file where the search is to occur.
-
-
- Attribute_Action FIND_PREV_ATTR_SUBOP
- This action is just like the FIND_NEXT_ATTR_SUBOP except
- that it finds the previous occurance of an attribute record
- of the specified class rather than the next occurance.
-
- Attribute_Action FIND_MATCH_ATTR_SUBOP
- This action finds the (push/pop model) attribute record
- that matches the specified attribute record. For example,
- if a push attribute record was specified, the location of
- the corresponding pop attribute record is returned.
-
- var Class
- unused parameter.
-
- var Offset, var Column, var Line
- input
- These parameters specify the location (non-inclusive)
- where the search is to begin. An attribute record must
- exist at this location or an error code will be flagged.
-
- output
- These parameters specify the location of the found
- attribute record. If none was found, then none of these
- parameters will be modified.
-
- var FileId (optional)
- The fileid of the file where the search is to occur.
-
- Attribute_Action DELETE_ATTR_SUBOP
- Deletes the attribute record at the specified location. If
- attribute records exists at the specified character
- position having an offset of the same sign as the specified
- attribute record but of larger magnitude, then those
- attribute records will be shifted in (their offset will be
- incremented or decremented) to fill in the vacated
- location.
- var Class
- input
- unused input parameter.
- output
- The class of the deleted attribute record. Zero if no
- attribute record exists at the specified location.
-
- var Offset, var Column, var Line
- The location of the attribute record to be deleted.
-
- var FileId (optional)
- The fileid of the file where the specified attribute
- record is to be found.
-
-
-
- Demo
-
- Several "GeeWhiz" demos are provided with this package in order help
- people realize the capabilities of attribute support. (Tutorials are
- also provided for educational purposes.)
-
- Demo 1 - EPM Calc
- This demo simulates a reverse Polish notation calculator.
- It also provides good sample code of the use of buttons.
-
- Instructions
- 1) Compile BUTTONS.E, ATTR.E, EPMCALC.E, and HIDEIT.
- 2) Start EPM
- 3) Issue the command "LINK EPMCALC"
- 4) Wait a moment for a calculator to appear
- 5) To "press" the calculator's buttons, move the
- pointer over the button to be pressed, hold
- down the Alt key, and double click on the
- left mouse button.
-
- Advanced Instructions
- 6a)
- Do a block mark of the calculator. Now duplicate
- it. Notice that both calculators work
- independently. This is because each instances
- state information is stored in the file with it's
- graphic representation. (See EPMCALC.E)
- 6b)
- Do a block mark on a button. Duplicate it outside the
- calculator. Notice that the button still works. Now
- move (if you have done 6a) the button close to another
- calculator. Notice that it now acts upon this second
- calculator rather than its original calculator. This
- is because EPMCALC's buttons apply their action on the
- nearest calculator. (See EPMCALC.E)
- 6c)
- Color the calculator by block marking it,
-
-
- The Code
- FindCalc
-
- Demo 2 - Highlight Phrase
-
- Instructions
- 1) Compile ATTR.E.
- 2) Start EPM
- 3) Issue the command "LINK ATTR"
- 4) Edit an interesting file.
- 5) Highlight all occurances of a phrase. This
- can be done by invoking the HIGHLIGHT_PHRASE
- command with the word to be highlighted as
- the first argument.
- 6) The default color is 93. An alternate color
- can be selected by giving a second argument
- in the range of 0 to 255.
-
- Advanced Instructions
- 7)
- The HIGHLIGHT_IDENTIFIER command may be more
- useful when attempting to highlight all occurances
- of an identifier in a Pascal, C, or E program.
- 8)
- Highlight a many words in a paragraph using this
- method. Change the margins, and reflow the
- paragraph.
-
- Demo 3 - Hide C Blocks
-
- Instructions
- 1) Compile ATTR.E, CBLOCK.E and HIDEIT.E.
- 2) Start EPM
- 3) Issue the command "LINK CBLOCK"
- 4) Edit a .C file.
- 5) Place the pointer over a { character.
- 6) Ctrl-Right-DoubleClick
- 7) Notice that logical block that was delimited by
- by the clicked '{' (and it's matching '}') was
- compressed.
- 8) Place the pointer on the green '*'.
- 9) Alt-Right-DoubleClick.
- 10) Notice that the "hidden" block has reappeared.
-
- Advanced Instructions
- 11) Same as above, but try to imbed hidden regions.
- 12) For further details see CBLOCK.E.
-
- Tutorial 1 -
- Demo 2 is really simple. Just look at the code for
- HIGHLIGHT_PHRASE in ATTR.E.
-
- Tutorial 2 - Complications of attributes
- 1) Mark a region of a file. Preferably "CHAR" mark.
- 2) invoke "set_marked_region_to_color 43"
- 3) Unmark the region.
- 4) Notice that the formally marked region now
- appears a different color. (Color 43).
- 5) Continue doing step 4.
- 6) Experiment with insertion of characters, deletion,
- mark copies, mark moves, etc. of attributes.
-
- Tutorial 3 - Making a button
- 1) link in BUTTONS.EX
- 2) Block mark a large region.
- 3) Fill that region with spaces by invoking
- "FILL"
- 4) Draw a border in the mark by invoking
- "NICE_BOX"
- 5) Put the words "List files" in the button box
- 6) Block mark the button again.
- 7) Associate the "dir" command with the button by invoking
- "associate_phrase_with_mark 4 DIR"
- 8) Block mark the button region.
- 9) Color the button by invoking
- "set_marked_region_to_color 43"
- 10) Now we have a colored button with a border that
- should execute a "dir" command when it is
- pressed.
- 11) Enable the mouse for button depression by invoking
- "enable_attr_keys"
- 12) Move pointer over the button.
- 13) Alt-Left-DoubleClick
-