adamc@821: type t = Basis.string
adamc@821: 
adamc@1023: val str = Basis.str1
adamc@1023: 
adamc@828: val length = Basis.strlen
adamc@828: val append = Basis.strcat
adamc@828: 
adamc@821: val sub = Basis.strsub
adamc@821: val suffix = Basis.strsuffix
adamc@829: 
adamc@829: val index = Basis.strindex
adamc@829: val atFirst = Basis.strchr
adamc@829: 
adamc@831: fun mindex {Haystack = s, Needle = chs} = Basis.strcspn s chs
adamc@831: 
adamc@829: fun substring s {Start = start, Len = len} = Basis.substring s start len
adamc@829: 
adamc@829: fun split s ch =
adamc@829:     case index s ch of
adamc@829:         None => None
adamc@829:       | Some i => Some (substring s {Start = 0, Len = i},
adamc@829:                         substring s {Start = i + 1, Len = length s - i - 1})
adamc@831: fun msplit {Haystack = s, Needle = chs} =
adamc@831:     case mindex {Haystack = s, Needle = chs} of
adamc@831:         None => None
adamc@831:       | Some i => Some (substring s {Start = 0, Len = i},
adamc@831:                         sub s i,
adamc@831:                         substring s {Start = i + 1, Len = length s - i - 1})
adamc@1057: 
adamc@1057: fun all f s =
adamc@1057:     let
adamc@1057:         val len = length s
adamc@1057: 
adamc@1057:         fun al i =
adamc@1057:             i >= len
adamc@1057:             || (f (sub s i) && al (i + 1))
adamc@1057:     in
adamc@1057:         al 0
adamc@1057:     end
adamc@1122: 
adamc@1131: fun mp f s =
adamc@1131:     let
adamc@1131:         fun mp' i acc =
adamc@1131:             if i < 0 then
adamc@1131:                 acc
adamc@1131:             else
adamc@1131:                 mp' (i - 1) (str (f (sub s i)) ^ acc)
adamc@1131:     in
adamc@1131:         mp' (length s - 1) ""
adamc@1131:     end
adamc@1131: 
adamc@1122: fun newlines [ctx] [[Body] ~ ctx] s : xml ([Body] ++ ctx) [] [] =
adamc@1122:     case split s #"\n" of
adamc@1122:         None => cdata s
adamc@1122:       | Some (s1, s2) => <xml>{[s1]}<br/>{newlines s2}</xml>