ATTRIBUTES OF TEXT

A text object is conceptually an instance of

classTEXTOBJ( SIZE, CONST);integerSIZE;booleanCONST;begincharacterarrayMAIN( 1:SIZE );end;

Any **text** value processed by the program is contained within a text frame,
i.e. a non-empty segment of the MAIN attribute of some TEXTOBJ instance, or it
is empty (i.e. **notext**). See 2.5.

A text variable is conceptually an instance of a composite structure

ref(TEXTOBJ) OBJ;integerSTART, LENGTH, POS;

It references (and has as its value the contents of) some text frame defined by the three first components. POS identifies the current character. See 3.1.2.

See also 3.3.3 and 3.3.6 (text relations), 3.7 (text expressions), 4.1.2 and 4.1.3 (text assignments).

This chapter defines all procedure attributes of any text variable. They may be accessed by remote identifiers of the form

simple-text-expression . procedure-identifier

The attributes are

booleanprocedureconstant; ........................ 8.1;integerprocedurestart; ........................... 8.1;integerprocedurelength; .......................... 8.1;textproceduremain; ............................... 8.1;integerprocedurepos; ............................. 8.2;proceduresetpos(i);integeri; .................... 8.2;booleanproceduremore; ............................ 8.2;characterproceduregetchar; ....................... 8.2;procedureputchar(c);characterc; ................. 8.2;textproceduresub(i,n);integeri,n; .............. 8.4;textprocedurestrip; .............................. 8.4;integerproceduregetint; .......................... 8.6;longrealproceduregetreal; ....................... 8.6;integerproceduregetfrac; ......................... 8.6;procedureputint(i);integeri; .................... 8.7;procedureputfix(i,n);integeri,n; ................ 8.7;procedureputreal(r,n);longrealr;integern; .... 8.7;procedureputfrac(i,n);integeri,n; ............... 8.7;

In the following "X" denotes a text variable unless otherwise specified.

CONSTANTThe following relations are true for any text variable X:booleanprocedureconstant; constant:= OBJ ==noneorelseOBJ.CONST; STARTintegerprocedurestart; start := START; LENGTHintegerprocedurelength; length := LENGTH; MAINtextproceduremain;ifOBJ =/=nonethenbegintextT; T.OBJ :- OBJ; T.START := 1; T.LENGTH := OBJ.SIZE; T.POS := 1; main :- T;endmain; "X.main" is a reference to the main frame which contains the frame referenced by X.

X.main.length >= X.length X.main.main == X.mainIn addition,

notext.main ==notext"ABC".main = "ABC" (but "ABC".main =/= "ABC")

**Examples**

booleanprocedureoverlapping(X,Y);textX,Y; overlapping := X.main == Y.mainandthen(ifX.start <= Y.startthenX.start + X.length > Y.startelseY.start + Y.length > X.start);

"overlapping(X,Y)" is true if and only if X and Y reference text frames which overlap each other.

booleanproceduresubtext(X,Y);textX,Y; subtext := X.main == Y.mainandthenX.start >= Y.startandthenX.start + X.length <= Y.start + Y.length;

"subtext(X,Y)" is true if and only if X references a subframe of Y, or
if both reference **notext**.

The characters of a text are accessible one at a time. Any text variable contains a "position indicator" POS, which identifies the currently accessible character, if any, of the referenced text frame. The position indicator of a given text variable X is an integer in the range (1,X.length+1).

The position indicator of a given text variable may be altered by the procedures "setpos", "getchar", and "putchar" of the text variable. Also any of the procedures defined in 8.6 and 8.7 may alter the position indicator of the text variable of which the procedure is an attribute.

Position indicators are ignored and left unaltered by text reference relations, text value relations and text value assignments.

The following procedures are facilities available for character accessing. They are oriented towards sequential access.

**Note**: The implicit modification of POS is lost immediately if "setpos",
"getchar" or "putchar" is successfully applied to a text expression
which is not a variable (see 3.7).

POSintegerprocedurepos; pos := POS; SETPOSproceduresetpos(i);integeri; POS :=ifi < 1ori > LENGTH + 1thenLENGTH + 1elsei; MOREbooleanproceduremore; more := POS <= LENGTH; GETCHARcharacterproceduregetchar;ifPOS > LENGTHthenerror("..." ! Pos out of range;)elsebegingetchar:= OBJ.MAIN(START + POS - 1); POS:= POS + 1endgetchar; PUTCHARprocedureputchar(c);characterc;ifOBJ ==noneorelseOBJ.CONSTorelsePOS>LENGTHthenerror("...")elsebeginOBJ.MAIN(START + POS - 1):= c; POS:= POS + 1endputchar;

The following standard procedures are available for text frame generation:

BLANKStextprocedureblanks(n);integern;ifn < 0thenerror("..." ! Parm. to blanks < 0;)elseifn > 0thenbegintextT; T.OBJ :-newTEXTOBJ(n,false); T.START := 1; T.LENGTH := n; T.POS := 1; T :=notext; ! blank-fill, see 4.1.2; blanks :- Tendblanks; "blanks(n)", with n > 0, references a new alterable main frame of length n, containing only blank characters. "blanks(0)" referencesnotext. COPYtextprocedurecopy(T);textT;ifT =/=notextthenbegintextU; U.OBJ :-newTEXTOBJ(T.LENGTH,false); U.START := 1; U.LENGTH := T.LENGTH; U.POS := 1; U := T; copy :- Uendcopy; "copy(T)", with T =/=notext, references a new alterable main frame which contains a text value identical to that of T.

Text frame generation is also performed by the text concatenation operator (see 3.7.1) and by the standard procedure "datetime" (see 9.10).

Two procedures are available for referencing subtexts (subframes).

SUBtextproceduresub(i,n);integeri,n;ifi < 0orn < 0ori + n > LENGTH + 1thenerror("..." ! Sub out of frame;)elseifn > 0thenbegintextT; T.OBJ :- OBJ; T.START := START + i - 1; T.LENGTH := n; T.POS := 1; sub :- Tend; If legal, "X.sub(i,n)" references that subframe of X whose first character is character number i of X, and which contains n consecutive characters. The POS attribute of the expression defines a local numbering of the characters within the subframe. If n = 0, the expression referencesnotext. If legal, the following Boolean expressions are true for any text variable X: X.sub(i,n).sub(j,m) == X.sub(i+j-1,m) n <> 0impX.main == X.sub(i,n).main X.main.sub(X.start,X.length) == X STRIPtextprocedurestrip; ... ; The expression "X.strip" is equivalent to "X.sub(1,n)", where n indicates the position of the last non-blank character in X. If X does not contain any non-blank character,notextis returned. Let X and Y be text variables. Then after the value assignment "X:=Y", if legal, the relation "X.strip = Y.strip" has the valuetrue, while "X = Y" istrueonly if X.length = Y.length.

The names of the syntactic units in this section are in upper case to indicate that these rules concern syntax for data and not for program text.

The syntax applies to sequences of characters, i.e. to text values.

NUMERIC-ITEM = REAL-ITEM | GROUPED-ITEM REAL-ITEM = DECIMAL-ITEM [ EXPONENT ] | SIGN-PART EXPONENT GROUPED-ITEM = SIGN-PART GROUPS [ DECIMAL-MARK GROUPS ] | SIGN-PART DECIMAL-MARK GROUPS DECIMAL-ITEM = INTEGER-ITEM [ FRACTION ] | SIGN-PART FRACTION INTEGER-ITEM = SIGN-PART DIGITS FRACTION = DECIMAL-MARK DIGITS SIGN-PART = BLANKS [ SIGN ] BLANKS EXPONENT = LOWTEN-CHARACTER INTEGER-ITEM GROUPS = DIGITS { BLANK DIGITS } SIGN = + | - DIGITS = DIGIT { DIGIT } DIGIT = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 LOWTEN-CHARACTER = & | ... DECIMAL-MARK = . | , BLANKS = { BLANK | TAB }

BLANK and TAB are the characters space and horisontal tabulation respectively.

The default representations of LOWTEN CHARACTER and DECIMAL MARK are & and ., respectively. These values may, however, be changed by appropriate procedure calls, see 9.2.

A numeric item is a character sequence which may be derived from NUMERIC ITEM. "Editing" and "de-editing" procedures are available for the conversion between arithmetic values and text values which are numeric items, and vice versa.

The editing and de-editing procedures are oriented towards "fixed field" text manipulation.

**Note**: Both the editing and the de-editing procedures are understood to
operate on text values represented in the internal character set.

A de-editing procedure of a given text variable X operates in the following way:

- The longest numeric item, if any, of a given form, which is contained by X and which contains the first character of X is located. (Note that leading blanks and tabs are accepted as part of any numeric item.)
- If no such numeric item is found, a run-time error occurs.
- Otherwise, the numeric item is interpreted as a number.
- If that number is outside a relevant implementation-defined range, a run-time error occurs.
- Otherwise, an arithmetic value is computed, which is equal to or approximates to that number.
- The position indicator of X is made one greater than the position of the last character of the numeric item. Note that this increment is lost immediately if X does not correspond to a variable (see 3.7).

The following de-editing procedures are available.

GETINTintegerproceduregetint; ... ; The procedure locates an INTEGER ITEM. The function value is equal to the corresponding integer. GETREALlongrealproceduregetreal; ... ; The procedure locates a REAL ITEM. The function value is equal to or approximates to the corresponding number. An INTEGER ITEM exceeding a certain implementation-defined range may lose precision when converted tolongreal.Note: No distinction is made betweenrealandlongrealitems. In order to preserve precision the procedure assumeslongrealprecision. GETFRACintegerproceduregetfrac; ... ; The procedure locates a GROUPED ITEM. The function value is equal to the resulting integer. The digits of a GROUPED ITEM may be interspersed with BLANKS and a single DECIMAL MARK which are ignored by the procedure.

Editing procedures of a given text variable X serve to convert arithmetic values to numeric items. After an editing operation, the numeric item obtained, if any, is right-adjusted in the text frame referenced by X and preceded by as many blanks as necessary to fill the text frame. The final value of the position indicator of X is X.length+1. Note that this increment is lost immediately if X does not correspond to a variable, (see 3.7).

A positive number is edited without a sign. A negative number is edited with a minus sign immediately preceding the most significant character. Leading non-significant zeros are suppressed, except possibly in an EXPONENT.

If X references a constant text frame or **notext**, an error results. Otherwise,
if the text frame is too short to contain the resulting numeric item, the text
frame into which the number was to be edited is filled with asterisks. If the
parameters to "putfix" and "putreal" are such that some of the printed digits
will be without significance, zeros are substituted for these digits (and no
error condition is raised).

In "putfix" and "putreal", the numeric item designates that number of the specified form which differs by the smallest possible amount from the value of "r" or from the approximation to the value of "r".

PUTINTprocedureputint(i);integeri; ... ; The value of the parameter is converted to an INTEGER ITEM which designates an integer equal to that value. PUTFIXprocedureputfix(r,n);r; integern; ... ; The resulting numeric item is an INTEGER ITEM if n=0 or a DECIMAL ITEM with a FRACTION of n digits if n>0. It designates a number equal to the value of r or an approximation to the value of r, correctly rounded to n decimal places. If n<0, a run-time error is caused. PUTREALprocedureputreal(r,n);r; integern; ... ; The resulting numeric item is a REAL ITEM containing an EXPONENT with a fixed implementation-defined number of characters. The EXPONENT is preceded by a SIGN PART if n=0, or by an INTEGER ITEM with one digit if n=1, or if n>1, by a DECIMAL ITEM with an INTEGER ITEM of 1 digit only, and a fraction of n-1 digits. If n<0 a runtime error is caused. PUTFRACprocedureputfrac(i,n);integeri,n; ... ; The resulting numeric item is a GROUPED ITEM with no DECIMAL MARK if n<=0, and with a DECIMAL MARK followed by total of n digits if n>0. Each digit group consists of 3 digits, except possibly the first one, and possibly the last one following a DECIMAL MARK. The numeric item is an exact representation of the number i * 10**(-n).

**Examples**

procedurecompact(T);textT;begintextU;characterc; T.setpos(1); U:- T;whileU.moredobeginc:=U.getchar;ifc <> ' 'thenT.putchar(c)end;whileT.moredoT.putchar(' ')endcompact;

The procedure rearranges the characters of the text frame referenced by its parameter. The non-blank characters are collected in the leftmost part of the text frame and the remainder, if any, is filled with blank characters. Since the parameter is called by reference, its position indicator is not altered.

If tr at *** holds the textbegintexttr, type, amount, price, payment;integerpay, total; tr :- blanks(80); type :- tr.sub(1,5); amount :- tr.sub(20,5); price :- tr.sub(30,6); payment :- tr.sub(40,10); ... ; ! ***;iftype = "order"thenbeginpay := amount.getint * price.getfrac; total := total + pay; payment.putfrac(pay,2)endend

"order 1200 155.75 ..."it will after editing contain

"order 1200 155.75 18 690.00 ...".