packages feed

heredoc 0.1.0.1 → 0.2.0.0

raw patch · 3 files changed

+122/−38 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Text.Here: here :: QuasiQuoter
- Text.Here: there :: QuasiQuoter
+ Text.Heredoc: here :: QuasiQuoter
+ Text.Heredoc: str :: QuasiQuoter
+ Text.Heredoc: there :: QuasiQuoter

Files

heredoc.cabal view
@@ -1,5 +1,5 @@ name:                heredoc-version:             0.1.0.1+version:             0.2.0.0 synopsis:            multi-line string / here document using QuasiQuotes description:         multi-line string / here document using QuasiQuotes @@ -16,7 +16,7 @@ cabal-version:       >=1.8  library-  exposed-modules:   Text.Here+  exposed-modules:   Text.Heredoc   build-depends:     base >= 4 && < 5,     template-haskell >= 2.5
− src/Text/Here.hs
@@ -1,36 +0,0 @@-module Text.Here (here, there) where--import Language.Haskell.TH-  ( litE-  , stringL-  )--import Language.Haskell.TH.Quote-  ( QuasiQuoter-    ( QuasiQuoter-    , quoteExp-    , quotePat-    , quoteType-    , quoteDec-    )-  , quoteFile-  )--err :: String -> String-err ctx =-  "You have used the `here` QuasiQuoter in a " ++ ctx ++ " context; " ++-  "you must only use it as a string literal expression"---- | Create a string-literal expression from the string being quoted.-here :: QuasiQuoter-here = QuasiQuoter-  { quoteExp  = litE . stringL-  , quotePat  = const $ error $ err "pattern"-  , quoteType = const $ error $ err "type"-  , quoteDec  = const $ error $ err "declaration"-  }---- | Create a string-literal expression from--- the contents of the file at the filepath being quoted.-there :: QuasiQuoter-there = quoteFile here
+ src/Text/Heredoc.hs view
@@ -0,0 +1,120 @@+module Text.Heredoc (here, there, str) where++import Data.Maybe (fromMaybe)+import Data.List (intercalate)+import Language.Haskell.TH+  ( litE+  , stringL+  )++import Language.Haskell.TH.Quote+  ( QuasiQuoter+    ( QuasiQuoter+    , quoteExp+    , quotePat+    , quoteType+    , quoteDec+    )+  , quoteFile+  )++data Ctx = Exp | Pat | Type | Dec++qq :: String -> Ctx -> QuasiQuoter+qq qqName correctCtx = QuasiQuoter+  { quoteExp  = const $ error $ errorString Exp+  , quotePat  = const $ error $ errorString Pat+  , quoteType = const $ error $ errorString Type+  , quoteDec  = const $ error $ errorString Dec+  }+  where+    errorString ctx =+      "You have used the `" ++ qqName ++ "` QuasiQuoter " +++      "in " ++ ctxName ctx ++ " context; " +++      "you must only use it in " ++ ctxName correctCtx ++ " context"++    ctxName c = case c of+      Exp  -> "an expression"+      Pat  -> "a pattern"+      Type -> "a type"+      Dec  -> "a declaration"+++toUnix :: String -> String+toUnix cs = case cs of+  '\r':'\n' : cs -> '\n' : toUnix cs+  '\r'      : cs -> '\n' : toUnix cs+  c         : cs -> c    : toUnix cs+  []             -> []++{-| Create a string-literal expression from the string being quoted.++    Newline literals are normalized to UNIX newlines (one '\n' character).+-}+here :: QuasiQuoter+here = (qq "here" Exp) { quoteExp  = litE . stringL . toUnix }++{-| Create a string-literal expression from+    the contents of the file at the filepath being quoted.++    Newline literals are normalized to UNIX newlines (one '\n' character).+-}+there :: QuasiQuoter+there = quoteFile here++{-| Create a multi-line string literal whose left edge is demarcated by the+    "pipe" character ('|'). For example,++    >famousQuote = [str|Any dictator would admire the+    >                  |uniformity and obedience of the U.S. media.+    >                  |+    >                  |    -- Noam Chomsky+    >                  |]++    is functionally equivalent to++    >famousQuote = "Any dictator would admire the\n" +++    >              "uniformity and obedience of the U.S. media.\n" +++    >              "\n" +++    >              "    -- Noam Chomsky\n"++    If desired, you can have a ragged left-edge, so++    >myHtml = [str|<html>+    >                 |<body>+    >                     |<h1>My home page</h1>+    >                 |</body>+    >             |</html>+    >             |]++    is functionally equivalent to++    >myHtml = "<html>\n" +++    >         "<body>\n" +++    >         "<h1>My home page</h1>\n" +++    >          "</body>\n" +++    >         "</html>\n"+-}+str :: QuasiQuoter+str = (qq "str" Exp)+      { quoteExp = litE . stringL . intercalate "\n" . unPipe . lines . toUnix }+  where+    unPipe ls = case ls of+      []     -> []+      l : ls -> l : case splitLast ls of+        Nothing              -> []+        Just (middles, last) ->+          map removePipe middles ++ [fromMaybe "" (tryRemovePipe last)]+            where+            removePipe cs = case tryRemovePipe cs of+              Nothing -> error "no pipe character found in line '" ++ cs ++ "'"+              Just cs -> cs++            tryRemovePipe cs = case dropWhile (/='|') cs of+              []   -> Nothing+              c:cs -> Just cs++    splitLast :: [a] -> Maybe ([a], a)+    splitLast xs = case reverse xs of+      []  -> Nothing+      l:i -> Just (reverse i, l)