packages feed

Interpolation (empty) → 0.1

raw patch · 4 files changed

+176/−0 lines, 4 filesdep +basedep +sybdep +template-haskellsetup-changed

Dependencies added: base, syb, template-haskell

Files

+ Data/String/Interpolation.hs view
@@ -0,0 +1,132 @@+{-# LANGUAGE QuasiQuotes,TemplateHaskell,DeriveDataTypeable #-}+module Data.String.Interpolation(str) where+import Language.Haskell.TH as TH+import Language.Haskell.TH.Quote+import Data.Data+import Data.Maybe+import Data.Char+import Data.List(intercalate)++quoteExprExp :: String -> TH.ExpQ+-- | Quasiquote 'str' implements multiline strings with interpolation.+--   Interpolating a value of parameter a into the string is done by $a$+--   and interpolating anything with instance Show is $:a$.+--+--   Repetitive patterns can be made by # symbol using the following syntax: +--+--  @+--  \#\<var\> in \<list\>: \<interpolated string\> (|\<interpolated string\>)\#+--  @+--   +--   Where (|\<interpolated string\>) denotes optional separator for the +--   elements.+--   +--+--   Example:+-- +--   @+--    \#i in myList: this is $i$|--\#+--   @+--   +--   Which will evaluate to @ 1--2--3 @ given myList of [1,2,3]+--   +-- +--   Multiline indentation is handled by aligning on smallest un-empty+--   line after the first.+--+--   Pattern matching is not supported. +--++str  :: QuasiQuoter+str  =  QuasiQuoter quoteExprExp undefined+--+quoteExprExp s = psToStringE (parParse $ norming s)+--++psToStringE :: PieceString -> TH.Q TH.Exp+psToStringE [] = TH.stringE ""+psToStringE (x:xs) = TH.infixE (Just $ sbitToExp x)+                               ([| (++) |])+                               (Just $ psToStringE xs)++sbitToExp :: StringBits -> ExpQ+sbitToExp (Str x) =  TH.stringE x +sbitToExp (Var x)  =  (TH.varE (TH.mkName x))+sbitToExp (SVar x) = TH.appE (TH.varE (TH.mkName "show"))+                        (TH.varE (TH.mkName x))++sbitToExp (RepVar varName lstName rep sep) +    = [|intercalate $(sepr) (map $(lam) $(lstN))|]+    where+     sepr = psToStringE (fromMaybe [Str ""] sep)+     lam  = TH.lamE [varN] (psToStringE rep)+     varN = TH.varP $ TH.mkName varName+     lstN = TH.varE $ TH.mkName lstName++type PieceString = [StringBits]+data StringBits = Str String | Var String | SVar String+                  | RepVar String String +                    PieceString (Maybe PieceString)+                deriving (Eq,Ord,Show,Typeable,Data)++-- Split to string into pieces. This needs proper error messages.+-- Perhaps parsec?+parParse :: [Char] -> [StringBits]+parParse [] = []++parParse ('$':'$':s) = Str "$":parParse s -- Parse escapes+parParse ('#':'#':s) = Str "#":parParse s++parParse ('$':':':s) = SVar (takeWhile (/='$') s) -- Parse antiquotes+                        :parParse (drop 1 (dropWhile (/='$') s))+parParse ('$':s) = Var (takeWhile (/='$') s)+                    :parParse (drop 1 (dropWhile (/='$') s))++parParse ('#':s) = let (bind,exprS) = break (==':') s+                       (hasSep,expr,sepS) = takeRep $ drop 1 exprS+                       (sep,restS) = break (=='#') $ sepS+                       rest = drop 1 restS+                       [varName,"in",listName] = words bind+                    in if hasSep +                        then RepVar varName listName +                             (parParse expr) (Just $ parParse sep) +                             : parParse rest+                        else RepVar varName listName +                             (parParse expr) (Nothing) +                             : parParse sepS++parParse s = Str (takeWhile (notIn "$#") s)+                 : parParse (dropWhile (notIn "$#") s) ++notIn :: (Eq a) => [a] -> a -> Bool+notIn s x =not $ elem x s ++takeRep :: String -> (Bool,String,String)+takeRep x = takeRep' x []++takeRep' :: String -> String -> (Bool,String,String)+takeRep' [] _ = error "Repetition template does not end"+takeRep' ('|':'|':s) acc = takeRep' s ('|':acc)+takeRep' ('|':s) acc = (True,reverse acc,s)+takeRep' ('#':s) acc = (False,reverse acc,s)+takeRep' (r:s) acc = takeRep' s (r:acc)+++-- Normalize the indentation to match second line++norming :: String -> String+norming = unlines . norming' . lines++norming':: [String] -> [String]+norming' [] = []+norming' (l:lst) = l:map (drop (n)) lst+    where +     n = minimumD 0 $ map (length . takeWhile (==' ') ) +         $ (filter (not.isEmpty) lst)+     isEmpty = all (isSpace)+++minimumD :: (Ord a) => a -> [a] -> a+minimumD d [] = d+minimumD _ x  = minimum x+
+ Interpolation.cabal view
@@ -0,0 +1,18 @@+Name:                  Interpolation+Version:             0.1+Description:         This package adds quasiquoter for multiline +                     strings, interpolation and simple templating.+                     Handy for text generation.+Category:            Text+Synopsis:            Multiline strings, interpolation and templating.+License:             OtherLicense+License-file:        LICENSE+Author:              Ville Tirronen+Maintainer:          aleator@gmail.com+Build-Type:          Simple+Cabal-Version:       >=1.2++Library+  Build-Depends:     base, syb, template-haskell+  Exposed-modules:   Data.String.Interpolation+  ghc-options:       -Wall 
+ LICENSE view
@@ -0,0 +1,24 @@+++The MIT License++Copyright (c) 2009 Ville Tirronen++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.+
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain