Skip to content

Commit

Permalink
rewritten
Browse files Browse the repository at this point in the history
  • Loading branch information
Michel Boucey committed Oct 19, 2016
1 parent f238a9d commit 2496c49
Showing 1 changed file with 56 additions and 57 deletions.
113 changes: 56 additions & 57 deletions src/Text/Spintax.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{-# LANGUAGE OverloadedStrings #-}

module Text.Spintax where
module Text.Spintax (spintax) where

import Control.Applicative ((<|>))
import Data.Attoparsec.Text
Expand All @@ -11,73 +11,72 @@ import System.Random.MWC

-- | Generate random texts based on a spinning syntax template, with nested alternatives and empty options.
--
-- >λ> spintax "{A|B|C|{a|b|c{1|2|3}|d}|D}{|, {..|etc}.}"
-- > Right "c2"
-- >λ> spintax {{Oh my God|Awesome}, {a|the}|A|The} {quick {and dirty |||}||}{brown |pink |grey |}{fox|flea|elephant} jumps over {the|a} {lazy |smelly |sleepy |}{dog|cat|whale}{.|!|...}
-- > Right "Awesome, the quick pink fox jumps over a sleepy whale."
--
spintax :: T.Text -> IO (Either T.Text T.Text)
spintax template =
createSystemRandom >>= flip runParse template
where
runParse g' i' = go g' "" [] i' (0::Int)
where
go g o as i l
createSystemRandom >>= flip runParse template
where
runParse g' i' = go g' "" [] i' (0::Int)
where
go g o as i l
| l < 0 = failure
| l == 0 =
case parse spinSyntax i of
Done r m ->
case m of
"{" -> go g o as r (l+1)
"}" -> failure
"|" -> failure
_ -> go g (o <> m) as r l
Partial _ -> return $ Right $ o <> i
Fail {} -> failure
case parse spinSyntax i of
Done r m ->
case m of
"{" -> go g o as r (l+1)
"}" -> failure
"|" -> failure
_ -> go g (o <> m) as r l
Partial _ -> return $ Right $ o <> i
Fail {} -> failure
| l == 1 =
case parse spinSyntax i of
Done r m ->
case m of
"{" -> go g o (add as m) r (l+1)
"}" -> do r' <- runParse g =<< randAlter g as
case r' of
Left _ -> failure
Right t ->
go g (o <> t) [] r (l-1)
"|" -> if E.null as
then go g o ["",""] r l
else go g o (E.snoc as "") r l
_ -> go g o (add as m) r l
Partial _ -> failure
Fail {} -> failure
case parse spinSyntax i of
Done r m ->
case m of
"{" -> go g o (add as m) r (l+1)
"}" -> do r' <- runParse g =<< randAlter g as
case r' of
Left _ -> failure
Right t -> go g (o <> t) [] r (l-1)
"|" -> if E.null as
then go g o ["",""] r l
else go g o (E.snoc as "") r l
_ -> go g o (add as m) r l
Partial _ -> failure
Fail {} -> failure
| l > 1 =
case parse spinSyntax i of
Done r m ->
case m of
"{" -> go g o (add as m) r (l+1)
"}" -> go g o (add as m) r (l-1)
_ -> go g o (add as m) r l
Partial _ -> failure
Fail {} -> failure
where
add _l _t =
case parse spinSyntax i of
Done r m ->
case m of
"{" -> go g o (add as m) r (l+1)
"}" -> go g o (add as m) r (l-1)
_ -> go g o (add as m) r l
Partial _ -> failure
Fail {} -> failure
where
add _l _t =
case E.unsnoc _l of
Just (xs,x) -> E.snoc xs $ x <> _t
Nothing -> [_t]
randAlter _g _as =
Just (xs,x) -> E.snoc xs $ x <> _t
Nothing -> [_t]
randAlter _g _as =
(\r -> (!!) as (r-1)) <$> uniformR (1,E.length _as) _g
spinSyntax =
spinSyntax =
openBrace <|> closeBrace <|> pipe <|> content
where
pipe = string "|"
openBrace = string "{"
closeBrace = string "}"
content =
takeWhile1 ctt
where
ctt '{' = False
ctt '}' = False
ctt '|' = False
ctt _ = True
go _ _ _ _ _ = failure
openBrace = string "{"
closeBrace = string "}"
pipe = string "|"
content =
takeWhile1 ctt
where
ctt '{' = False
ctt '}' = False
ctt '|' = False
ctt _ = True
go _ _ _ _ _ = failure

failure :: IO (Either T.Text b)
failure = return $ Left "Spintax template parsing failure"
Expand Down

0 comments on commit 2496c49

Please sign in to comment.