TextEdit.mesa; written by Bill Paxton, February 1981
edited by McGregor, March 18, 1983 10:56 am
edited by Bill Paxton, July 11, 1983 12:36 pm
DIRECTORY
RopeEdit,
TiogaLooks,
TiogaNode,
UndoEvent;
TextEdit: CEDAR DEFINITIONS
IMPORTS TiogaLooks, RopeEdit =
BEGIN
Ref: TYPE = TiogaNode.Ref;
RefTextNode: TYPE = TiogaNode.RefTextNode;
RefItemNode: TYPE = TiogaNode.RefItemNode;
RefBranchNode: TYPE = TiogaNode.RefBranchNode;
ROPE: TYPE = RopeEdit.ROPE;
Looks: TYPE = TiogaLooks.Looks;
noLooks: Looks = TiogaLooks.noLooks;
allLooks: Looks = TiogaLooks.allLooks;
Offset: TYPE = TiogaLooks.Offset;
MaxLen, MaxOffset: Offset = LAST[Offset];
MaxNat: NAT = LAST[NAT];
Event: TYPE = UndoEvent.Ref;
**** General operations ****
Flatten: PROC [text: RefTextNode] RETURNS [BOOLEAN];
returns true if it decides to flatten rope & runs
this is done automatically after a certain number of edits to the node
AlreadySaved: PROC [text: RefTextNode, event: Event] RETURNS [BOOLEAN];
returns TRUE if there is already a ChangingText record for given node in the event
**** Operations to add or delete looks ****
ChangeLooks: PROC [
root: RefBranchNode, text: RefTextNode, remove, add: Looks,
start: Offset ← 0, len: Offset ← MaxOffset, event: Event ← NIL];
first remove then add in the given range
AddLooks: PROC [
root: RefBranchNode, text: RefTextNode, add: Looks,
start: Offset ← 0, len: Offset ← MaxOffset, event: Event ← NIL]
= INLINE { ChangeLooks[root, text, noLooks, add, start, len, event] };
RemoveLooks: PROC [
root: RefBranchNode, text: RefTextNode, remove: Looks ← allLooks,
start: Offset ← 0, len: Offset ← MaxOffset, event: Event ← NIL]
= INLINE { ChangeLooks[root, text, remove, noLooks, start, len, event] };
SetLooks: PROC [
root: RefBranchNode, text: RefTextNode, new: Looks,
start: Offset ← 0, len: Offset ← MaxOffset, event: Event ← NIL]
= INLINE { ChangeLooks[root, text, allLooks, new, start, len, event] };
ClearLooks: PROC [
root: RefBranchNode, text: RefTextNode, start: Offset ← 0, len: Offset ← MaxOffset, event: Event ← NIL]
= INLINE { ChangeLooks[root, text, allLooks, noLooks, start, len, event] };
**** Changing Style / Format / Property of node ****
ChangeFormat: PROC [
node: Ref, formatName: TiogaNode.Name, event: Event ← NIL, root: RefBranchNode ← NIL];
ChangeStyle: PROC [
node: Ref, name: ROPE, event: Event ← NIL, root: RefBranchNode ← NIL];
appends <name> style to end of node prefix
PutProp: PROC [
node: Ref, name: ROPE, value: REF, event: Event ← NIL, root: RefBranchNode ← NIL];
GetProp: PROC [node: Ref, name: ROPE] RETURNS [value: REF];
**** Editing Operations for text ****
NOTE: edit operations do not create or delete addrs,
but they can change their locations within the text
TwoSpanProc: TYPE = PROC [
destRoot, sourceRoot: RefBranchNode,
dest: RefTextNode, destStart: Offset ← 0, destLen: Offset ← MaxLen,
source: RefTextNode, sourceStart: Offset ← 0, sourceLen: Offset ← MaxLen,
event: Event ← NIL]
RETURNS [resultStart, resultLen: Offset];
DestSpanProc: TYPE = PROC [
destRoot, sourceRoot: RefBranchNode,
dest: RefTextNode, destLoc: Offset ← 0,
source: RefTextNode, start: Offset ← 0, len: Offset ← MaxLen, event: Event ← NIL]
RETURNS [resultStart, resultLen: Offset];
ReplaceText: TwoSpanProc;
replace the dest text by a copy of the source text
addrs that are in the replaced text move to destStart
addrs that are after the replaced text are adjusted
OneSpanProc: TYPE = PROC [
root: RefBranchNode,
text: RefTextNode, start: Offset ← 0, len: Offset ← MaxLen, event: Event ← NIL];
DeleteText: OneSpanProc;
delete the specified range of text
addrs that are in the deleted section move to start
CopyText: DestSpanProc;
copy the specified text
add length of inserted text to addrs that are beyond destLoc
MoveText: DestSpanProc;
move [start..start+len) in source to destLoc in dest
no-op if dest=source and destLoc IN [start..start+len]
addrs that are in the moved text do one of the following:
move with the text if dest = source,
or move to start if dest # source
MoveTextOnto: TwoSpanProc;
move [start..start+len) onto [destStart..destStart+destLen)
implemented by appropriate calls on MoveText and DeleteText
TransposeProc: TYPE = PROC [
alphaRoot, betaRoot: RefBranchNode,
alpha: RefTextNode, alphaStart: Offset ← 0, alphaLen: Offset ← MaxLen,
beta: RefTextNode, betaStart: Offset ← 0, betaLen: Offset ← MaxLen, event: Event ← NIL]
RETURNS [alphaResultStart, alphaResultLen, betaResultStart, betaResultLen: Offset];
TransposeText: TransposeProc;
transpose the alpha text and the beta text
addrs treated same as in Move
move with the text if alpha = beta,
or move to respective starts if alpha # beta
ReplaceByText: PROC [
root: RefBranchNode,
dest: RefTextNode, destStart: Offset ← 0, destLen: Offset ← MaxLen,
sourceRope: ROPE, sourceRuns: TiogaLooks.Runs,
sourceStart: Offset ← 0, sourceLen: Offset ← MaxLen, event: Event ← NIL]
RETURNS [resultStart, resultLen: Offset];
like ReplaceText, except give rope and runs as source instead of node
ReplaceWords: TwoSpanProc;
replace the dest words by a copy of the source words
adjusts appropriately to retain proper spacing
returns the start location and length of the new text
DeleteWords: OneSpanProc;
delete the specified words
CopyWords: DestSpanProc;
copy the specified words
MoveWords: DestSpanProc;
MoveWordsOnto: TwoSpanProc;
move the words in [start..start+len) onto those in [destStart..destStart+destLen)
adjusts appropriately to retain proper spacing
TransposeWords: TransposeProc;
transpose the alpha words and the beta words
adjusts appropriately to retain proper spacing
returns new starts and lengths
alphaResultStart, alphaResultLen are new start and length for alpha words
betaResultStart, betaResultLen are new start and length for beta words
ReplaceByChar: PROC [
root: RefBranchNode,
dest: RefTextNode, char: CHAR,
start: Offset ← 0, len: Offset ← MaxLen,
inherit: BOOLEANTRUE, looks: Looks ← noLooks, event: Event ← NIL]
RETURNS [resultStart, resultLen: Offset];
if inherit is false, char gets specifed looks  
if inherit is true, char gets looks in following manner:
if dest length is 0, then gets looks from argument list, else
if start > 0, then looks of previous char,
else looks of char following replacement
InsertChar: PROC [
root: RefBranchNode,
dest: RefTextNode, char: CHAR, destLoc: Offset ← 0,
inherit: BOOLEANTRUE, looks: Looks ← noLooks, event: Event ← NIL]
RETURNS [resultStart, resultLen: Offset] = INLINE {
[resultStart,resultLen] ← ReplaceByChar[root, dest, char, destLoc, 0, inherit, looks, event] };
AppendChar: PROC [
root: RefBranchNode,
dest: RefTextNode, char: CHAR,
inherit: BOOLEANTRUE, looks: Looks ← noLooks, event: Event ← NIL]
RETURNS [resultStart, resultLen: Offset] = INLINE {
[resultStart,resultLen] ← InsertChar[root, dest, char, MaxLen, inherit, looks, event] };
ReplaceByString: PROC [
root: RefBranchNode,
dest: RefTextNode, string: REF READONLY TEXT,
stringStart: NAT ← 0, stringNum: NAT ← MaxNat,
start: Offset ← 0, len: Offset ← MaxLen,
inherit: BOOLEANTRUE, looks: Looks ← noLooks, event: Event ← NIL]
RETURNS [resultStart, resultLen: Offset];
InsertString: PROC [
root: RefBranchNode,
dest: RefTextNode, string: REF READONLY TEXT,
stringStart: NAT ← 0, stringNum: NAT ← MaxNat,
destLoc: Offset ← 0,
inherit: BOOLEANTRUE, looks: Looks ← noLooks, event: Event ← NIL]
RETURNS [resultStart, resultLen: Offset] = INLINE {
[resultStart,resultLen] ← ReplaceByString[root,dest,string,stringStart,stringNum,
destLoc,0,inherit,looks,event] };
AppendString: PROC [
root: RefBranchNode,
dest: RefTextNode, string: REF READONLY TEXT,
stringStart: NAT ← 0, stringNum: NAT ← MaxNat,
inherit: BOOLEANTRUE, looks: Looks ← noLooks, event: Event ← NIL]
RETURNS [resultStart, resultLen: Offset] = INLINE {
[resultStart,resultLen] ← InsertString[root,dest,string,stringStart,stringNum,
MaxLen,inherit,looks,event] };
ReplaceByRope: PROC [
root: RefBranchNode,
dest: RefTextNode, rope: ROPE,
start: Offset ← 0, len: Offset ← MaxLen,
inherit: BOOLEANTRUE, looks: Looks ← noLooks, event: Event ← NIL]
RETURNS [resultStart, resultLen: Offset];
InsertRope: PROC [
root: RefBranchNode,
dest: RefTextNode, rope: ROPE, destLoc: Offset ← 0,
inherit: BOOLEANTRUE, looks: Looks ← noLooks, event: Event ← NIL]
RETURNS [resultStart, resultLen: Offset] = INLINE {
[resultStart,resultLen] ← ReplaceByRope[root,dest,rope,destLoc,0,inherit,looks,event] };
AppendRope: PROC [
root: RefBranchNode,
dest: RefTextNode, rope: ROPE,
inherit: BOOLEANTRUE, looks: Looks ← noLooks, event: Event ← NIL]
RETURNS [resultStart, resultLen: Offset] = INLINE {
[resultStart,resultLen] ← InsertRope[root,dest,rope,MaxLen,inherit,looks,event] };
***** Cap's and Lowercase
AllCaps: PROC [
root: RefBranchNode,
dest: RefTextNode, start: Offset ← 0, len: Offset ← MaxLen, event: Event ← NIL] =
INLINE { ChangeCaps[root,dest,start,len,allCaps,event] };
force specified span to all uppercase
AllLower: PROC [
root: RefBranchNode,
dest: RefTextNode, start: Offset ← 0, len: Offset ← MaxLen, event: Event ← NIL] =
INLINE { ChangeCaps[root,dest,start,len,allLower,event] };
force specified span to all lowercase
InitialCaps: PROC [
root: RefBranchNode,
dest: RefTextNode, start: Offset ← 0, len: Offset ← MaxLen, event: Event ← NIL] =
INLINE { ChangeCaps[root,dest,start,len,initCaps,event] };
force first letter of words uppercase
CapChange: TYPE = {allCaps, allLower, initCaps, firstCap};
ChangeCaps: PROC [
root: RefBranchNode,
dest: RefTextNode, start: Offset ← 0, len: Offset ← MaxLen,
how: CapChange ← allCaps, event: Event ← NIL];
END.