+let shift off = List.map (fun (start,stop,v) -> start+off,stop+off,v);;
+
+let (^^) (map1,s1) (map2,s2) = map1 @ (shift (utf8_string_length s1) map2), s1 ^ s2;;
+
+(* CSC: inefficient (quadratic) implementation *)
+let mapped_string_concat sep =
+ let sep_len = utf8_string_length sep in
+ let rec aux off =
+ function
+ [] -> [],""
+ | [map,s] -> shift off map,s
+ | (map,s)::tl ->
+ let map = shift off map in
+ let map2,s2 = aux (off + utf8_string_length s + sep_len) tl in
+ map@map2, s ^ sep ^ s2
+ in
+ aux 0
+;;
+
+let indent_string s = string_indent ^^ s