neat-interpolation 0.1.1 → 0.2.0
raw patch · 6 files changed
+235/−56 lines, 6 filesdep −classy-preludenew-component:exe:neat-interpolation-demo
Dependencies removed: classy-prelude
Files
- neat-interpolation.cabal +130/−27
- src/Demo.hs +26/−0
- src/NeatInterpolation.hs +24/−22
- src/NeatInterpolation/Parsing.hs +2/−3
- src/NeatInterpolation/Prelude.hs +52/−0
- src/NeatInterpolation/String.hs +1/−4
neat-interpolation.cabal view
@@ -1,30 +1,133 @@-name: neat-interpolation-version: 0.1.1-cabal-version: >=1.8-build-type: Simple-license: MIT-license-file: LICENSE-copyright: (c) 2013, Nikita Volkov-author: Nikita Volkov-maintainer: Nikita Volkov <nikita.y.volkov@mail.ru>-stability: experimental-homepage: https://github.com/nikita-volkov/neat-interpolation-bug-reports: https://github.com/nikita-volkov/neat-interpolation/issues-synopsis: A quasiquoter for neat and simple multiline text interpolation-description: NeatInterpolation provides a quasiquoter for producing `Text` data with a simple interpolation of input values. It removes the excessive indentation from the input text and accurately manages the indentation of all lines of interpolated variables. -category: Text, String, QuasiQoutes+name:+ neat-interpolation+version:+ 0.2.0+synopsis:+ A quasiquoter for neat and simple multiline text interpolation+description:+ NeatInterpolation provides a quasiquoter for producing strings + with a simple interpolation of input values. + It removes the excessive indentation from the input and + accurately manages the indentation of all lines of interpolated variables. +category:+ String, QuasiQoutes+license:+ MIT+license-file:+ LICENSE+copyright:+ (c) 2013, Nikita Volkov+author:+ Nikita Volkov <nikita.y.volkov@mail.ru>+maintainer:+ Nikita Volkov <nikita.y.volkov@mail.ru>+homepage:+ https://github.com/nikita-volkov/neat-interpolation+bug-reports:+ https://github.com/nikita-volkov/neat-interpolation/issues+build-type:+ Simple+cabal-version:+ >=1.10 -library- hs-source-dirs: src- extensions: PatternGuards- exposed-modules: NeatInterpolation- other-modules: NeatInterpolation.Parsing- NeatInterpolation.String- build-depends: base >= 4.5 && < 5,- classy-prelude >= 0.5.3,- template-haskell,- parsec source-repository head- type: git- location: git://github.com/nikita-volkov/neat-interpolation.git+ type:+ git+ location:+ git://github.com/nikita-volkov/neat-interpolation.git+++library+ hs-source-dirs:+ src+ exposed-modules:+ NeatInterpolation+ other-modules:+ NeatInterpolation.Prelude+ NeatInterpolation.Parsing+ NeatInterpolation.String+ build-depends:+ parsec,+ template-haskell,+ base >= 4.5 && < 5+ default-extensions:+ NoImplicitPrelude+ PatternGuards+ MultiWayIf+ LambdaCase+ Arrows+ MultiParamTypeClasses+ NoMonomorphismRestriction+ FlexibleInstances+ FlexibleContexts+ GADTs+ EmptyDataDecls+ StandaloneDeriving+ ConstraintKinds+ RankNTypes+ TypeFamilies+ TypeOperators+ DataKinds+ ImpredicativeTypes+ LiberalTypeSynonyms+ OverloadedStrings+ TemplateHaskell+ QuasiQuotes+ GeneralizedNewtypeDeriving+ DeriveDataTypeable+ DeriveGeneric+ DefaultSignatures+ ScopedTypeVariables+ BangPatterns+ RecordWildCards+ TupleSections+ default-language:+ Haskell2010+++executable neat-interpolation-demo+ hs-source-dirs:+ src+ main-is:+ Demo.hs+ ghc-options:+ -threaded + "-with-rtsopts=-N"+ build-depends:+ parsec,+ template-haskell,+ base >= 4.5 && < 5+ default-extensions:+ NoImplicitPrelude+ PatternGuards+ MultiWayIf+ LambdaCase+ Arrows+ MultiParamTypeClasses+ NoMonomorphismRestriction+ FlexibleInstances+ FlexibleContexts+ GADTs+ EmptyDataDecls+ StandaloneDeriving+ ConstraintKinds+ RankNTypes+ TypeFamilies+ TypeOperators+ DataKinds+ ImpredicativeTypes+ LiberalTypeSynonyms+ OverloadedStrings+ TemplateHaskell+ QuasiQuotes+ GeneralizedNewtypeDeriving+ DeriveDataTypeable+ DeriveGeneric+ DefaultSignatures+ ScopedTypeVariables+ BangPatterns+ RecordWildCards+ TupleSections+ default-language:+ Haskell2010
+ src/Demo.hs view
@@ -0,0 +1,26 @@++import NeatInterpolation.Prelude+import NeatInterpolation++main = do+ let a' = [string| + function startsWith( start, string ){+ return string.lastIndexOf( start ) == 0+ }+ |]+ let pattern = [string| {+ ++ $a'++ single inlining: ( $a' )+++ {+ multiple inlining: ( $a' ) ( $a' )+ }+++ } + |]+ putStrLn pattern
src/NeatInterpolation.hs view
@@ -1,20 +1,20 @@-{-# LANGUAGE QuasiQuotes, TemplateHaskell, DeriveDataTypeable, OverloadedStrings #-} {-# OPTIONS_GHC -fno-warn-missing-fields #-} --- | NeatInterpolation provides a quasiquoter for producing `Text` data with a --- simple interpolation of input values. It removes the excessive indentation --- from the input text and accurately manages the indentation of all lines of --- interpolated variables. But enough words, the code shows it better.+-- | +-- NeatInterpolation provides a quasiquoter for producing strings +-- with a simple interpolation of input values. +-- It removes the excessive indentation from the input and +-- accurately manages the indentation of all lines of interpolated variables. +-- But enough words, the code shows it better. -- -- Consider the following declaration: -- -- > {-# LANGUAGE QuasiQuotes, OverloadedStrings #-} -- > -- > import NeatInterpolation--- > import qualified Data.Text.IO as Text -- > --- > f :: Text -> Text -> Text+-- > f :: String -> String -> String -- > f a b = --- > [text|+-- > [string| -- > function(){ -- > function(){ -- > $a@@ -25,7 +25,7 @@ -- -- Executing the following: -- --- > main = Text.putStrLn $ f "1" "2"+-- > main = putStrLn $ f "1" "2" -- -- will produce this (notice the reduced indentation compared to how it was -- declared):@@ -37,9 +37,9 @@ -- > return 2 -- > } -- --- Now let's test it with multiline text parameters:+-- Now let's test it with multiline string parameters: -- --- > main = Text.putStrLn $ f +-- > main = putStrLn $ f -- > "{\n indented line\n indented line\n}" -- > "{\n indented line\n indented line\n}" --@@ -60,10 +60,9 @@ -- -- See how it neatly preserved the indentation levels of lines the -- variable placeholders were at? -module NeatInterpolation (text, indentQQPlaceholder) where+module NeatInterpolation (string, indentQQPlaceholder) where -import Prelude ()-import ClassyPrelude+import NeatInterpolation.Prelude import Language.Haskell.TH import Language.Haskell.TH.Quote@@ -72,24 +71,27 @@ import NeatInterpolation.Parsing --text :: QuasiQuoter-text = QuasiQuoter {quoteExp = quoteExprExp}+-- |+-- The quasiquoter.+string :: QuasiQuoter+string = QuasiQuoter {quoteExp = quoteExprExp} -indentQQPlaceholder :: Int -> Text -> Text+-- |+-- A function used internally by quasiquoter. Just ignore it.+indentQQPlaceholder :: Int -> String -> String indentQQPlaceholder indent text = case lines text of- head:tail -> intercalate "\n" $ head : map (replicate indent " " ++) tail+ head:tail -> intercalate "\n" $ head : map (replicate indent ' ' ++) tail [] -> text -quoteExprExp :: [Char] -> Q Exp+quoteExprExp :: String -> Q Exp quoteExprExp input = case parseLines $ normalizeQQInput input of Left e -> fail $ show e Right lines -> appE [|unlines|] $ linesExp lines linesExp :: [Line] -> Q Exp-linesExp [] = [|([] :: [Text])|]+linesExp [] = [|([] :: [String])|] linesExp (head : tail) = (binaryOpE [|(:)|]) (lineExp head)@@ -114,7 +116,7 @@ Nothing -> fail $ "Value `" ++ name ++ "` is not in scope" msumExps :: [Q Exp] -> Q Exp-msumExps = fold (binaryOpE mappendE) memptyE+msumExps = foldr (binaryOpE mappendE) memptyE memptyE = [|mempty|] mappendE = [|mappend|]
src/NeatInterpolation/Parsing.hs view
@@ -1,9 +1,8 @@-{-# LANGUAGE NoMonomorphismRestriction #-} module NeatInterpolation.Parsing where -import Prelude ()-import ClassyPrelude hiding (try, (<|>))+import NeatInterpolation.Prelude hiding (try, (<|>), many) import Text.Parsec hiding (Line)+-- import qualified Data.Attoparsec.Text as AP data Line = Line {lineIndent :: Int, lineContents :: [LineContent]}
+ src/NeatInterpolation/Prelude.hs view
@@ -0,0 +1,52 @@+module NeatInterpolation.Prelude + ( + module Exports,+ (?:),+ traceM,+ )+ where++-- base+import Prelude as Exports hiding (concat, foldr, mapM_, sequence_, foldl1, maximum, minimum, product, sum, all, and, any, concatMap, elem, foldl, foldr1, notElem, or, mapM, sequence, FilePath, id, (.))+import Control.Monad as Exports hiding (mapM_, sequence_, forM_, msum, mapM, sequence, forM)+import Control.Applicative as Exports+import Control.Arrow as Exports hiding (left, right)+import Control.Category as Exports+import Data.Monoid as Exports+import Data.Foldable as Exports+import Data.Traversable as Exports hiding (for)+import Data.Maybe as Exports+import Data.List as Exports hiding (concat, foldr, foldl1, maximum, minimum, product, sum, all, and, any, concatMap, elem, foldl, foldr1, notElem, or, find, maximumBy, minimumBy, mapAccumL, mapAccumR, foldl')+import Data.Tuple as Exports+import Data.Ord as Exports (Down(..))+import Data.String as Exports+import Data.Int as Exports+import Data.Word as Exports+import Data.Ratio as Exports+import Data.Fixed as Exports+import Data.Ix as Exports+import Data.Data as Exports+import Text.Read as Exports (readMaybe, readEither)+import Control.Exception as Exports hiding (tryJust)+import Control.Concurrent as Exports hiding (yield)+import System.Timeout as Exports+import System.Exit as Exports+import System.IO.Unsafe as Exports+import System.IO as Exports (Handle, hClose)+import System.IO.Error as Exports+import Unsafe.Coerce as Exports+import GHC.Exts as Exports (groupWith, sortWith)+import GHC.Generics as Exports (Generic)+import GHC.IO.Exception as Exports+import Debug.Trace as Exports+import Data.IORef as Exports+import Data.STRef as Exports+import Control.Monad.ST as Exports+++(?:) :: Maybe a -> a -> a+maybeA ?: b = fromMaybe b maybeA+{-# INLINE (?:) #-}++traceM :: (Monad m) => String -> m ()+traceM s = trace s $ return ()
src/NeatInterpolation/String.hs view
@@ -1,10 +1,7 @@-{-# LANGUAGE OverloadedStrings, NoMonomorphismRestriction #-} module NeatInterpolation.String where -import Prelude ()-import ClassyPrelude+import NeatInterpolation.Prelude import Data.Char-import Data.Foldable (foldr) normalizeQQInput :: [Char] -> [Char]