--simple text processing tools----------------------------
--defs. follow Bird/Wadler and are not equivalent to Prelude

-------------------------------------------- type synomyms
type Text = String
type Line = String
type Word = String
type Para = [Line]

------------------------------------------examples

microText =
 "Stille Nacht, \n heilige Nacht, \n\n alles schlaeft,\n einsam wacht...\n"

headline = "Weihnachten in Salzburg\n"

{-----------------------------------text as lines, preliminary

asLines:: Text->[Line]
asLines  = foldr break_on_newline [[]]
  where break_on_newline:: Char->[Line]->[Line]
        break_on_newline c ls
          |c == '\n' = []:ls                     --new group
          |otherwise = (c:(head ls)) : (tail ls) --add to group

--------------------------------------------------------------}

------------------------------allgemeines break_on fuer Listen
                           --behandelt break-elem als Separator

break_on:: Eq a => a->a->[[a]]->[[a]]
break_on b c ls
   |c == b    = []:ls                     --new group
   |otherwise = (c:(head ls)) : (tail ls) --add to group

-----------------------------------------------text as lines

asLines:: Text->[Line]
asLines  = foldr (break_on '\n') [[]]

-----------------------------------------------lines as words
                                             --no empty words

asWords:: Line->[Word]
asWords = filter (/= []) . foldr (break_on ' ') [[]]

---------------------------------------line lists as paragraphs
                                               --no empty lines

asParas:: [Line]->[Para]
asParas = filter (/= []) . foldr (break_on []) [[]]

-------------------------------allgemeines concWith fuer Listen

concWith:: a->[a]->[a]->[a]
concWith x ys zs = ys ++ [x] ++ zs

-----------------------------------------------Umkehrfunktionen
                                        --re-insert Separatoren
                                  --erfordern nichtleere Listen
                                --wg. filter nicht exakt invers

unLines:: [Line]->Text
unLines = foldr1 (concWith '\n')

unWords:: [Word]->Line
unWords = foldr1 (concWith ' ')

unParas:: [Para]->[Line]
unParas = foldr1 (concWith [])

-----------------------------------------------Kombinationen

parse:: Text->[[[Word]]]
parse = map(map asWords) . asParas . asLines

unparse:: [[[Word]]]->Text
unparse = unLines . unParas . map(map unWords)

simplify:: Text->Text        --entferne redundante Separatoren
simplify = unparse . parse

countLines = length . asLines
countWords = length . concat. map asWords . asLines
countParas = length . asParas . asLines

                           