TextReplaceImpl.mesa
Copyright Ó 1986, 1992 by Xerox Corporation. All rights reserved.
Last Edited by: Spreitzer, January 10, 1986 10:16:52 pm PST
Last tweaked by Mike Spreitzer on August 18, 1988 12:39:00 pm PDT
Doug Wyatt, September 25, 1992 2:00 pm PDT
EXPORTS TextReplace = {
OPEN TextReplace;
SyntaxError: PUBLIC ERROR = CODE;
NoMapping: PUBLIC SIGNAL [rm: RopeMap, from: ROPE] RETURNS [to: ROPE] = CODE;
Apply:
PUBLIC
PROC [s: RopeMap, r:
ROPE]
RETURNS [mapped:
ROPE] =
{mapped ¬ s.Map[s.data, r]};
id: PUBLIC RopeMap ¬ NEW [RopeMapRep ¬ [Id, NIL]];
Id:
PROC [data:
REF
ANY, name:
ROPE]
RETURNS [value:
ROPE] =
{value ¬ name};
addBrackets: PUBLIC RopeMap ¬ NEW [RopeMapRep ¬ [AddBrackets, NIL]];
AddBrackets:
PROC [data:
REF
ANY, name:
ROPE]
RETURNS [value:
ROPE] =
{value ¬ Rope.Cat["<", name, ">"]};
Constant:
PUBLIC
PROC [result:
ROPE]
RETURNS [rm: RopeMap] = {
rm ¬ NEW [RopeMapRep ¬ [MapToConstant, result]];
};
MapToConstant:
PROC [data:
REF
ANY, arg:
ROPE]
RETURNS [result:
ROPE] = {
constant: ROPE = NARROW[data];
result ¬ constant;
};
Catted: TYPE = REF CattedRep;
CattedRep: TYPE = RECORD [first, second: RopeMap];
Cat:
PUBLIC
PROC [first, second: RopeMap]
RETURNS [catted: RopeMap] = {
catted ¬
NEW [RopeMapRep ¬ [
MapCatted,
NEW [CattedRep ¬ [first, second]] ]];
};
MapCatted:
PROC [data:
REF
ANY, name:
ROPE]
RETURNS [value:
ROPE] = {
c: Catted ¬ NARROW[data];
mid: ROPE ¬ c.first.Map[c.first.data, name];
value ¬ c.second.Map[c.second.data, mid];
};
Layered: TYPE = REF LayeredRep;
LayeredRep: TYPE = RECORD [first, later: RopeMap];
Layer:
PUBLIC
PROC [first, later: RopeMap]
RETURNS [layered: RopeMap] = {
layered ¬
NEW [RopeMapRep ¬ [
MapLayered,
NEW [LayeredRep ¬ [first, later]] ]];
};
MapLayered:
PROC [data:
REF
ANY, name:
ROPE]
RETURNS [value:
ROPE] = {
l: Layered ¬ NARROW[data];
value ¬ l.first.Map[l.first.data, name];
IF value = NIL THEN value ¬ l.later.Map[l.later.data, name];
};
ProcessedPairList: TYPE = LIST OF ProcessedPair;
ProcessedPair:
TYPE =
RECORD [
target: TextFind.Target,
case: BOOL,
word: BOOL,
replace: ROPE,
pattern: BOOL
];
RopeMapFromPairs:
PUBLIC
PROC [pl: PairList]
RETURNS [s: RopeMap] = {
ppl: ProcessedPairList ¬ Process[pl];
s ¬ NEW [RopeMapRep ¬ [MapPairs, ppl]];
};
Process:
PROC [pl: PairList]
RETURNS [ppl: ProcessedPairList] = {
IF pl = NIL THEN RETURN [NIL];
ppl ¬
CONS[
[
target: TextFind.TargetFromRope[rope: pl.first.match, pattern: NOT pl.first.literal],
case: NOT pl.first.ignoreCase,
word: pl.first.word,
replace: pl.first.replace,
pattern: NOT pl.first.literal
],
Process[pl.rest]];
};
MapPairs:
PROC [data:
REF
ANY, name:
ROPE]
RETURNS [value:
ROPE] = {
value ¬ name;
FOR ppl: ProcessedPairList ¬
NARROW[data], ppl.rest
WHILE ppl #
NIL
DO
pp: ProcessedPair ~ ppl.first;
start: INT ¬ 0;
DO
found: BOOL; selStart, selEnd: INT; subs: TextFind.Subs;
[found: found, selStart: selStart, selEnd: selEnd, subs: subs] ¬ TextFind.RopeSearch[
direction: forward, target: pp.target, rope: value, start: start,
case: pp.case, word: pp.word];
IF found
THEN {
rem: INT ~ Rope.Length[value]-selEnd;
value ¬ TextFind.RopeReplace[rope: value, start: selStart, len: selEnd-selStart,
with: pp.replace, pattern: pp.pattern, subs: subs];
start ¬ Rope.Length[value]-rem;
}
ELSE EXIT;
ENDLOOP;
ENDLOOP;
};
}.