Spintax 0.1.0.0 → 0.1.0.1
raw patch · 2 files changed
+76/−71 lines, 2 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- Spintax.cabal +5/−3
- src/Text/Spintax.hs +71/−68
Spintax.cabal view
@@ -1,13 +1,13 @@ name: Spintax-version: 0.1.0.0+version: 0.1.0.1 synopsis: Random text generation based on spintax description: Random text generation based on spintax with nested alternatives and empty options. homepage: https://github.com/MichelBoucey/spintax license: BSD3 license-file: LICENSE author: Michel Boucey-maintainer: michel.boucey@gmail.com-copyright: Copyright © 2016 - Michel Boucey+maintainer: michel.boucey@cybervisible.fr+copyright: Copyright (c) 2016 - Michel Boucey category: Text build-type: Simple cabal-version: >=1.10@@ -21,7 +21,9 @@ , mwc-random , extra default-language: Haskell2010+ GHC-Options: -Wall source-repository head type: git location: https://github.com/MichelBoucey/spintax+
src/Text/Spintax.hs view
@@ -1,80 +1,83 @@ {-# LANGUAGE OverloadedStrings #-} -module Text.Spintax where+module Text.Spintax (spintax) where -import Control.Applicative ((<|>))-import Data.Attoparsec.Text-import Data.Either-import Data.List.Extra as E-import Data.Text as T-import System.Random.MWC+import Control.Applicative ((<|>))+import Data.Attoparsec.Text+import qualified Data.List.Extra as E+import Data.Monoid ((<>))+import qualified Data.Text as T+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 >>= \gen -> runParse gen template- where- runParse gen input =- getText gen "" [] input 0- where- getText gen output alters input nestlev - | nestlev < 0 = return failure- | nestlev == 0 =- case parse spinSyntax input of- Done rest match ->- case match of- "{" -> getText gen output alters rest (nestlev+1)- "}" -> return failure- "|" -> return failure- _ -> getText gen (output `append` match) alters rest nestlev- Partial _ -> return $ Right $ output `append` input- Fail {} -> return failure- | nestlev == 1 =- case parse spinSyntax input of- Done rest match ->- case match of- "{" -> getText gen output (addToLast alters match) rest (nestlev+1)- "}" -> do result <- runParse gen =<< randAlter gen alters- case result of- Left _ -> return failure- Right text -> getText gen (output `append` text) [] rest (nestlev-1)- "|" -> if E.null alters- then getText gen output ["",""] rest nestlev- else getText gen output (E.snoc alters "") rest nestlev- _ -> getText gen output (addToLast alters match) rest nestlev- Partial _ -> return failure- Fail {} -> return failure - | nestlev > 1 =- case parse spinSyntax input of- Done rest match ->- case match of- "{" -> getText gen output (addToLast alters match) rest (nestlev+1)- "}" -> getText gen output (addToLast alters match) rest (nestlev-1)- _ -> getText gen output (addToLast alters match) rest nestlev- Partial _ -> return failure- Fail {} -> return failure- where- failure = Left "Spintax template parsing failure"- addToLast l t =- case E.unsnoc l of- Just (xs,x) -> E.snoc xs $ x `append` t- Nothing -> [t]- randAlter g as = uniformR (1,E.length as) g >>= \r -> return $ (!!) as (r-1)- spinSyntax =+ 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+ | 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+ | 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 E.unsnoc _l of+ Just (xs,x) -> E.snoc xs $ x <> _t+ Nothing -> [_t]+ randAlter _g _as =+ (\r -> (!!) as (r-1)) <$> uniformR (1,E.length _as) _g+ spinSyntax = openBrace <|> closeBrace <|> pipe <|> content- where- pipe = string "|"- openBrace = string "{"- closeBrace = string "}"- content =- takeWhile1 ctt where- ctt '{' = False- ctt '}' = False- ctt '|' = False- ctt _ = True+ 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"