packages feed

acme-lolcat (empty) → 0.1

raw patch · 6 files changed

+337/−0 lines, 6 filesdep +basedep +parsecdep +randomsetup-changed

Dependencies added: base, parsec, random, random-shuffle, text

Files

+ Acme/LOLCAT.hs view
@@ -0,0 +1,244 @@+-- | Module:      Acme.LOLCAT+--  Copyright:   (c) 2013 Antonio Nikishaev+--  License:     BSD+--  Maintainer:  me@lelf.lu+--+--+-- LOLCAT translator.+--+-- Roughly based on <https://metacpan.org/pod/Acme::LOLCAT Acme::LOLCAT>+-- for Perl.++{-# LANGUAGE OverloadedStrings, FlexibleInstances, TupleSections #-}+{-# LANGUAGE Trustworthy #-}++module Acme.LOLCAT (translate, KindaText()) where++import Data.Text (Text)+import qualified Data.Text as T++import Text.Parsec+import Text.Parsec.Text()++import Control.Applicative ((<$>),(<*),(<*>))+import Control.Arrow+import Control.Monad+import Data.String (IsString(..))+import Data.Monoid+import Data.Char++import System.Random+import qualified System.Random.Shuffle as SHU (shuffle')++import Acme.LOLCAT.IO+++{-# NOINLINE shuffle #-}+shuffle :: [a] -> [a]+shuffle xs = do io <- OH HAI I CAN HAZ IO? THXBYE+                SHU.shuffle' xs (length xs) (io newStdGen)+++-- | Given a list, return a infinity list of its elements in random order+variants :: [a] -> [a]+variants xs = shuffle xs ++ variants xs++++type Parser = Parsec Text ParserState+data ParserState = Word | Punct deriving Eq++type Pattern = Parser String+++-- | Replace the part that matched by pattern PAT with TO in S.+-- Return Right NEW-STRING or Left ORIGINAL if nothing matches.+replaceOne :: Pattern -> Text -> Text -> Either Text Text+replaceOne pat to s | Right s' <- parsed = Right s'+                    | otherwise          = Left s+    where repl (pref,r) = pref <> to <> T.drop (T.length pref + length r) s+          parsed = repl <$> myRun (find pat) s+++-- | Run parser+myRun :: Parser a -> Text -> Either ParseError a+myRun p s = runP p Punct "" s+++-- | Replace PAT with TOS (cycling) in STR+replace :: Pattern -> [Text] -> Text -> Text+replace pat tos str = repl (cycle tos) $ Right str+    where repl (t:ts) (Right s) = repl ts $ replaceOne pat t s+          repl _ (Left s)       = s+++{-# NOINLINE translateT #-}+translateT :: Text -> Text+translateT src+           | n == 1    = base <> " THX"+           | n == 2    = base <> " THXBYE."+           | otherwise = base+    where+      Just n = OH HAI I CAN HAZ IO? THXBYE+               <*> Just (randomRIO (1,10)) :: Maybe Int++      base = T.toUpper $ last $ scanl f src rules+      f s (pat,repls) = replace pat (variants repls) s+++++-- | Text/String-like things+class KindaText a where+    fromText :: Text -> a+    toText :: a -> Text++instance KindaText Text where+    fromText = id+    toText = id++instance KindaText String where+    fromText = T.unpack+    toText = T.pack+++-- | >>> translate "You too can speak like a lolcat!"+-- YOU 2 CAN SPEKK LIEK LOLCAT! THXBYE.+translate :: KindaText s => s -> s+translate = fromText . translateT . toText++++instance IsString (Parser String) where+    fromString = string+++-- | Given a parser for X returns a new parser for “smth and then X”+-- returning (SMTH,X)+-- +-- Weird? This is Acme.*.+find :: Pattern -> Parser (Text,String)+find pat = try (("",) <$> pat)+           <|> do c <- anyChar+                  putState $ if isLetter c then Word else Punct+                  first (T.cons c) <$> find pat+++-- | word S exactly+word :: String -> Parser String+word s = do Punct <- getState+            string s <* wordEnd++-- | S is inside word+inside :: String -> Parser String+inside s = do Word <- getState+              string s <* letter++-- | word S and then any punctuations+wordPuncts :: String -> Parser String+wordPuncts w = (++) <$> word w <*> many1 space++-- | word ending with S+wEnds :: String -> Parser String+wEnds s = string s <* wordEnd+++wordEnd = notFollowedBy letter+++++main = forever $ getLine >>= putStrLn . translate++++rules :: [(Parser String, [Text])]++rules = [+ ("what",                       ["wut", "whut"]),+ (wEnds "you",		        ["yu", "yous", "yoo", "u"]),+ ("cture",			["kshur"]),+ ("unless",			["unles"]),+ (wEnds "the",	         	["teh"]),+ ("more",			["moar"]),+ ("my",				["muh", "mah"]),+ ("are",			["r", "is", "ar"]),+ (word "a",			[""]),+ ("eese",			["eez"]),+ ("catamorphi",			["cat-a-murrphi"]),+ ("morphi",			["murrphi"]),+ ("ph",				["f"]),+ (wEnds "as",			["az"]),+ ("seriously",			["srsly"]),+ (wEnds "er",			["r"]),+ ("sion",			["shun"]),+ ("just",			["jus"]),+ (wEnds "ose",			["oze"]),+ ("eady",			["eddy"]),+ (wEnds "om" <|> wEnds "ome",	["um"]),+ (wEnds "of",			["of", "ov", "of"]),+ ("uestion",			["wesjun"]),+ (word "want",			["wants"]),+ (wEnds "ead",			["edd"]),+ ("ucke",			["ukki", "ukke"]),+ ("sion",			["shun"]),+ ("eak",			["ekk"]),+ ("age",			["uj"]),+ ("like",			["likes", "liek"]),+ ("love",			["loves", "lub", "lubs", "luv"]),+ (word "is",			["ar teh","ar"]),+ (wEnds "nd",			["n"]),+ ("who",			["hoo"]),+ ("'",				[""]),+ (wEnds "ese",			["eez"]),+ ("outh",			["owf"]),+ ("scio",			["shu"]),+ ("esque",			["esk"]),+ ("ture",			["chur"]),+ (word "too" <|> word "to",	["to", "t", "2", "to", "t"]),+ ("tious",			["shus"]),+ (wEnds "sure",			["shur"]),+ (wEnds "tty",			["tteh"]),+ ("were",			["was"]),+ (wEnds "ok",			["k", "kay"]),+ ("ym",				["im"]),+ (wEnds "thy",			["fee"]),+ (inside "ly",			["li"]),+ ("que" <* letter,		["kwe"]),+ ("oth",			["udd"]), -- ?+ ("ease",			["eez"]),+ (wEnds "ing",			["in", "ins", "ng", "ing"]),+ ("your",			["yur", "ur", "yore", "yoar"]),+ (wEnds "ove",			["oov", "ove", "uuv", "uv", "oove"]),+ ("for",			["for", "4", "fr", "fur", "for", "foar"]),+ ("thank",			["fank", "tank", "thx", "thnx"]),+ ("good",			["gud", "goed", "guud", "gude", "gewd"]),+ ("really",			["rly", "rily", "rilly", "rilley"]),+ ("world",			["wurrld", "whirld", "wurld", "wrld"]),+ (word "i'm" <|> word "im",	["im"]),++ -- ("(?!e)ight",		["ite"]),+ ("tion",			["shun"]),             -- ("(?!ues)tion",["shun"])+ ("you're" <|> "youre" <|> "you are",+				["yore", "yr"]),++-- ("\\boh\\b(?!.*hai)",	["o", "ohs"]),+ (word "oh",			["o", "ohs"]), -- ???++-- ("can" <+spaces, [""]),++ (join<$>sequence [wordPuncts "can",+                   wordPuncts "i",+                   wordPuncts "have",+                   word "a"],	["i can has"]),++ ("have",			["has", "hav", "haz a"]),++ (word "hello" <|> word "hi"+    <|> word "hey" <|> word "howdy" <|> word "yo",+				["oh hai"]),++ (word "god",			["ceiling cat"])++ ]+
+ Acme/LOLCAT/IO.hs view
@@ -0,0 +1,24 @@+-- | Module:      Acme.LOLCAT+--   Copyright:   (c) 2013 Antonio Nikishaev+--   License:     BSD+--   Maintainer:  me@lelf.lu+{-# LANGUAGE Unsafe #-}++module Acme.LOLCAT.IO (OH(..),HAI(..),I(..),CAN(..),HAZ(..),+                       IO(..),YO(..),(?),THXBYE(..)) where++import Prelude hiding (IO)+import System.IO.Unsafe (unsafePerformIO)+++data HAI a b c d e = HAI a b c d e+data OH a b c d e = OH a b c d e+data I = I+data IO = IO+data YO = YO+data CAN = CAN+data HAZ = HAZ+data THXBYE = THXBYE++_?_ = return unsafePerformIO+
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2013, Antonio Nikishaev++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 Anton Nikishaev 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.
+ README.markdown view
@@ -0,0 +1,3 @@+LOLCAT translator.++Roughly based on [Acme::LOLCAT](https://metacpan.org/pod/Acme::LOLCAT)
+ Setup.lhs view
@@ -0,0 +1,3 @@+#!/usr/bin/env runhaskell+> import Distribution.Simple+> main = defaultMain
+ acme-lolcat.cabal view
@@ -0,0 +1,33 @@+name:                acme-lolcat+version:             0.1+homepage:            https://github.com/llelf/acme-lolcat+synopsis:            LOLSPEAK translator+description:	     LOLSPEAK translator+license:             BSD3+license-file:        LICENSE+author:              Antonio Nikishaev <me@lelf.lu>+maintainer:          Antonio Nikishaev <me@lelf.lu>+copyright:           2013,2014 Antonio Nikishaev+category:            Acme+build-type:          Simple+cabal-version:       >=1.14+extra-source-files:  README.markdown+tested-with:         GHC==7.6.3, GHC==7.8.3, GHC==7.9.20140419++library+  exposed-modules:     Acme.LOLCAT, Acme.LOLCAT.IO+  build-depends:       +        base >= 4.5 && < 5, parsec >= 1.3.1, text >= 0.11.3.1,+        random >= 1.0.1.1, random-shuffle >= 0.0.4+  default-language:    Haskell2010+--  ghc-options: -Wall++source-repository head+  type:     git+  location: https://github.com/llelf/acme-lolcat++source-repository head+  type:     darcs+  location: http://hub.darcs.net/lelf/acme-lolcat++