annotate lib/ur/string.ur @ 2021:2da693675de9

String.trim; add OnChange to more tags
author Adam Chlipala <adam@chlipala.net>
date Tue, 10 Jun 2014 10:58:22 -0400
parents 65fbb250b875
children 1a4b2b983889
rev   line source
adamc@821 1 type t = Basis.string
adamc@821 2
adamc@1023 3 val str = Basis.str1
adamc@1023 4
adamc@828 5 val length = Basis.strlen
adam@1388 6 val lengthGe = Basis.strlenGe
adamc@828 7 val append = Basis.strcat
adamc@828 8
adamc@821 9 val sub = Basis.strsub
adamc@821 10 val suffix = Basis.strsuffix
adamc@829 11
adamc@829 12 val index = Basis.strindex
adam@1390 13 fun sindex r = Basis.strsindex r.Haystack r.Needle
adamc@829 14 val atFirst = Basis.strchr
adamc@829 15
adamc@1272 16 fun mindex {Haystack = s, Needle = chs} =
adamc@1272 17 let
adamc@1272 18 val n = Basis.strcspn s chs
adamc@1272 19 in
adamc@1272 20 if n >= length s then
adamc@1272 21 None
adamc@1272 22 else
adamc@1272 23 Some n
adamc@1272 24 end
adamc@831 25
adamc@829 26 fun substring s {Start = start, Len = len} = Basis.substring s start len
adamc@829 27
adam@1389 28 fun seek s ch =
adam@1389 29 case index s ch of
adam@1389 30 None => None
adam@1389 31 | Some i => Some (suffix s (i + 1))
adam@1389 32 fun mseek {Haystack = s, Needle = chs} =
adam@1389 33 case mindex {Haystack = s, Needle = chs} of
adam@1389 34 None => None
adam@1389 35 | Some i => Some (sub s i, suffix s (i + 1))
adam@1389 36
adamc@829 37 fun split s ch =
adamc@829 38 case index s ch of
adamc@829 39 None => None
adamc@829 40 | Some i => Some (substring s {Start = 0, Len = i},
adam@1389 41 suffix s (i + 1))
adam@1389 42 fun split' s ch =
adam@1389 43 case index s ch of
adam@1389 44 None => None
adam@1389 45 | Some i => Some (substring s {Start = 0, Len = i},
adam@1389 46 suffix s i)
adamc@831 47 fun msplit {Haystack = s, Needle = chs} =
adamc@831 48 case mindex {Haystack = s, Needle = chs} of
adamc@831 49 None => None
adamc@831 50 | Some i => Some (substring s {Start = 0, Len = i},
adamc@831 51 sub s i,
adam@1389 52 suffix s (i + 1))
adamc@1057 53
adam@1390 54 fun ssplit r =
adam@1390 55 case sindex r of
adam@1390 56 None => None
adam@1390 57 | Some i => Some (substring r.Haystack {Start = 0, Len = i},
adam@1390 58 suffix r.Haystack (i + length r.Needle))
adam@1390 59
adamc@1057 60 fun all f s =
adamc@1057 61 let
adamc@1057 62 val len = length s
adamc@1057 63
adamc@1057 64 fun al i =
adamc@1057 65 i >= len
adamc@1057 66 || (f (sub s i) && al (i + 1))
adamc@1057 67 in
adamc@1057 68 al 0
adamc@1057 69 end
adamc@1122 70
adamc@1131 71 fun mp f s =
adamc@1131 72 let
adamc@1131 73 fun mp' i acc =
adamc@1131 74 if i < 0 then
adamc@1131 75 acc
adamc@1131 76 else
adamc@1131 77 mp' (i - 1) (str (f (sub s i)) ^ acc)
adamc@1131 78 in
adamc@1131 79 mp' (length s - 1) ""
adamc@1131 80 end
adamc@1131 81
adam@1304 82 fun newlines [ctx] [[Body] ~ ctx] (s : string) : xml ([Body] ++ ctx) [] [] =
adamc@1122 83 case split s #"\n" of
adamc@1122 84 None => cdata s
adamc@1122 85 | Some (s1, s2) => <xml>{[s1]}<br/>{newlines s2}</xml>
adamc@1174 86
adamc@1174 87 fun isPrefix {Full = f, Prefix = p} =
adamc@1174 88 length f >= length p && substring f {Start = 0, Len = length p} = p
adam@2021 89
adam@2021 90 fun trim s =
adam@2021 91 let
adam@2021 92 val len = length s
adam@2021 93
adam@2021 94 fun findStart i =
adam@2021 95 if i < len && Char.isSpace (sub s i) then
adam@2021 96 findStart (i+1)
adam@2021 97 else
adam@2021 98 i
adam@2021 99
adam@2021 100 fun findFinish i =
adam@2021 101 if i >= 0 && Char.isSpace (sub s i) then
adam@2021 102 findFinish (i-1)
adam@2021 103 else
adam@2021 104 i
adam@2021 105
adam@2021 106 val start = findStart 0
adam@2021 107 val finish = findFinish (len - 1)
adam@2021 108 in
adam@2021 109 if finish >= start then
adam@2021 110 substring s {Start = start, Len = finish - start + 1}
adam@2021 111 else
adam@2021 112 ""
adam@2021 113 end