Spintax (empty) → 0.1.0.0
raw patch · 4 files changed
+139/−0 lines, 4 filesdep +attoparsecdep +basedep +extrasetup-changed
Dependencies added: attoparsec, base, extra, mwc-random, text
Files
- LICENSE +30/−0
- Setup.hs +2/−0
- Spintax.cabal +27/−0
- src/Text/Spintax.hs +80/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Michel Boucey (c) 2016++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Michel Boucey nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ Spintax.cabal view
@@ -0,0 +1,27 @@+name: Spintax+version: 0.1.0.0+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+category: Text+build-type: Simple+cabal-version: >=1.10++library+ hs-source-dirs: src+ exposed-modules: Text.Spintax+ build-depends: base >= 4.7 && < 5+ , text+ , attoparsec+ , mwc-random+ , extra+ default-language: Haskell2010++source-repository head+ type: git+ location: https://github.com/MichelBoucey/spintax
+ src/Text/Spintax.hs view
@@ -0,0 +1,80 @@+{-# LANGUAGE OverloadedStrings #-}++module Text.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++-- | 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 :: 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 =+ openBrace <|> closeBrace <|> pipe <|> content+ where+ pipe = string "|"+ openBrace = string "{"+ closeBrace = string "}"+ content =+ takeWhile1 ctt+ where+ ctt '{' = False+ ctt '}' = False+ ctt '|' = False+ ctt _ = True+