as is
without express or implied warranty. Export of this
software outside of the United States of America may require an
export license.
$Id: TextUtils.m3.html,v 1.3 2010-04-29 17:17:56 wagner Exp $
MODULEfind first occurrence of sub in in; IMPORT Text; IMPORT Fmt; IMPORT TextSet, TextSetDef, TextList; PROCEDURE TextUtils CountCharOccurences (in: TEXT; c: CHAR): CARDINAL = VAR count := 0; BEGIN FOR i := 0 TO Text.Length(in) - 1 DO IF Text.GetChar(in,i) = c THEN INC(count); END; END; RETURN count; END CountCharOccurences; PROCEDUREReplaceChar (in : TEXT; old, new : CHAR) : TEXT = VAR res := NEW(REF ARRAY OF CHAR, Text.Length(in)); BEGIN FOR i := 0 TO Text.Length(in) - 1 DO WITH char = Text.GetChar(in,i) DO IF char = old THEN res[i] := new ELSE res[i] := char END END END; RETURN Text.FromChars(res^) END ReplaceChar; PROCEDUREReplace (in, old, new : TEXT) : TEXT = VAR startpos := 0; nextpos : CARDINAL; BEGIN WHILE FindSub(in, old, nextpos, startpos) DO in := Text.Sub(in, 0, nextpos) & new & Text.Sub(in, nextpos + Text.Length(old)); startpos := nextpos + Text.Length(old) - Text.Length(new) END; RETURN in END Replace;
PROCEDUREFindSub (in, sub : TEXT; VAR pos : CARDINAL; start := 0) : BOOLEAN = VAR inA := NEW(REF ARRAY OF CHAR, Text.Length(in)); subA := NEW(REF ARRAY OF CHAR, Text.Length(sub)); BEGIN Text.SetChars(inA^,in); Text.SetChars(subA^,sub); FOR i := start TO LAST(inA^) - LAST(subA^) DO VAR success := TRUE; BEGIN FOR j := 0 TO LAST(subA^) DO IF subA[j] # inA[i + j] THEN success := FALSE; EXIT END END; IF success THEN pos := i; RETURN TRUE END END END; RETURN FALSE END FindSub; PROCEDUREHaveSub (in, sub : TEXT) : BOOLEAN = VAR x : CARDINAL; BEGIN RETURN FindSub(in, sub, x) END HaveSub; PROCEDUREHavePrefix (in, prefix: TEXT): BOOLEAN = BEGIN RETURN Text.Equal(Text.Sub(in, 0, Text.Length(prefix)), prefix); END HavePrefix; PROCEDUREHaveSuffix (in, suffix: TEXT): BOOLEAN = VAR pos := Text.Length(in) - Text.Length(suffix); BEGIN RETURN pos >= 0 AND Text.Equal(Text.Sub(in, pos), suffix); END HaveSuffix; PROCEDURERemoveSuffix (in, suffix: TEXT): TEXT = VAR pos := Text.Length(in) - Text.Length(suffix); BEGIN <* ASSERT pos >= 0 AND Text.Equal(Text.Sub(in, pos), suffix) *> RETURN Text.Sub(in, 0, pos); END RemoveSuffix; PROCEDUREPluralize (noun : TEXT; n : INTEGER; ending : TEXT; printNum : BOOLEAN) : TEXT = VAR res : TEXT; BEGIN IF printNum THEN res := Fmt.Int(n) & " " ELSE res := "" END; IF n = 1 THEN RETURN res & noun ELSE RETURN res & noun & ending END END Pluralize; PROCEDUREListToSet (l : TextList.T) : TextSet.T = VAR res := NEW(TextSetDef.T).init(); BEGIN WHILE l # NIL DO EVAL res.insert(l.head); l := l.tail END; RETURN res END ListToSet; PROCEDURESetToList (set : TextSet.T) : TextList.T = VAR iter := set.iterate(); t : TEXT; res : TextList.T := NIL; BEGIN WHILE iter.next(t) DO res := TextList.Cons(t,res) END; RETURN res END SetToList; BEGIN END TextUtils.