packages feed

hsass 0.1.0 → 0.2.0

raw patch · 8 files changed

+171/−88 lines, 8 filesdep ~basePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base

API changes (from Hackage documentation)

+ Text.Sass.Compilation: data SassExtendedResult
+ Text.Sass.Compilation: errorStatus :: SassError -> Int
+ Text.Sass.Compilation: instance SassResult SassExtendedResult
+ Text.Sass.Compilation: instance SassResult String
+ Text.Sass.Compilation: instance Show SassExtendedResult
+ Text.Sass.Compilation: resultIncludes :: SassExtendedResult -> IO [String]
+ Text.Sass.Compilation: resultSourcemap :: SassExtendedResult -> IO (Maybe String)
+ Text.Sass.Compilation: resultString :: SassExtendedResult -> String
+ Text.Sass.Compilation: type ExtendedResult = IO (Either SassError SassExtendedResult)
+ Text.Sass.Compilation: type StringResult = IO (Either SassError String)
- Text.Sass.Compilation: compileFile :: FilePath -> SassOptions -> IO (Either SassError String)
+ Text.Sass.Compilation: compileFile :: SassResult a => FilePath -> SassOptions -> IO (Either SassError a)
- Text.Sass.Compilation: compileString :: String -> SassOptions -> IO (Either SassError String)
+ Text.Sass.Compilation: compileString :: SassResult a => String -> SassOptions -> IO (Either SassError a)

Files

CHANGELOG.md view
@@ -2,6 +2,16 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## 0.2.0 - 2015-06-01+### Changed+- Return type of 'compileString' and 'compileFile' is now polymorphic - may+  return both 'String' and 'SassExtendedResult' on success.+- Fixes in documentation (articles, mostly).++### Added+- 'SassExtendedResult' with a compiled string, a list of files included during+  compilation and a source map.+ ## 0.1.0 - 2015-04-11 ### Added - Support for functions, importers, headers and sass values.
Text/Sass.hs view
@@ -5,7 +5,8 @@ -- extension language. It supports basic compilation, functions, importers and -- headers, so it should suffice for most of the work. ----- Code used in this document is testable - see test/Text/Sass/TutorialSpec.hs.+-- Code used in this document is testable - see+-- @test\/Text\/Sass\/TutorialSpec.hs@. module Text.Sass   (     -- * Compilation@@ -37,14 +38,18 @@ import           Text.Sass.Values  -- $compilation--- Compilation of Sass source is very easy - you only have to use 'compileFile'--- or 'compileString' and leave the work to hsass. 'compileFile' takes path to--- the file as first parameter, while 'compileString' takes source code.--- Both functions take 'SassOptions' as second parameter, so if you want to--- customize compilation behaviour, you may use it.+-- Compilation of a Sass source is very easy - you only have to use+-- 'compileFile' or 'compileString' and leave the work to hsass. 'compileFile'+-- a takes path to the file as a first parameter, while 'compileString' takes a+-- source code. Both functions take 'SassOptions' as a second parameter, so if+-- you want to customize compilation behaviour, you may use it. -- -- The result of both functions is 'Either' @Left 'SassError'@, indicating that--- something went wrong, or @Right 'String'@ with resulting code.+-- something went wrong, @Right 'String'@ with resulting code or+-- @Right 'SassExtendedResult'@ with a compiled code, a list of included files+-- and optionally a source map. Compilation functions are polymorphic in their+-- return type (there are no separate functions based on return type), but the+-- compiler should be able to infer the type easily. -- You can examine 'SassError' to gain more knowledge about the error. -- -- 'SassOptions' is instance of 'Default' class, so you may use 'def' function@@ -61,6 +66,10 @@ -- When you want to compile source code instead of file, consider setting -- 'sassIncludePaths' - it will allow to resolve @includes without custom -- importers.+--+-- If you want access to the extended result, you have to use 'resultString',+-- 'resultIncludes' and 'resultSourcemap' on the result to extract desirable+-- information.  -- $options -- 'SassOptions' wraps <http://libsass.org libsass> context options. It does not@@ -69,31 +78,30 @@  -- $values -- "Text.Sass.Values" module wraps native values that libsass uses. It provides--- easy way to manage them in pure Haskell code.+-- an easy way to manage them in pure Haskell code.  -- $functions_basic -- This is the most advanced stuff in the library (even though it is quite -- simple). It allows you to define functions in Haskell and use them from Sass--- source, provide custom resolution for @import statements and include custom--- headers in files.+-- source, provide custom resolution functions for @import statements and+-- include custom headers in files.  -- $functions--- Let's start with explanation of functions. For example, assume that we want to--- use function @max3@, that takes three numbers and returns the largest. In+-- Let's start with explanation of functions. For example, assume that we want+-- to use function @max3@, that takes three numbers and returns the largest. In -- Haskell, we would write it like this: -- -- > max3 :: Int -> Int -> Int -> Int -- > max3 a b c = max a $ max b c -- -- Unfortunately, sass would not be able to use that. We must rewrite this--- function so that it operates on 'SassValue's. If we want to use function+-- function so that it operates on 'SassValue's. If we want to use a function -- in sass, it has to have following signature: -- -- > func :: SassValue -> IO SassValue ----- It takes an argument that is 'SassList' with all of arguments passed in sass--- code and returns computed 'SassValue'. With this in mind, we may write--- following code:+-- It takes an argument that is 'SassList' with all of its arguments and returns+-- computed 'SassValue'. With this in mind, we may write following code: -- -- > max3 (SassList (SassNumber a _:SassNumber b _:SassNumber c _:_) _) = -- >     return $ SassNumber (max a $ max b c) "px"@@ -103,14 +111,14 @@ -- -- > max3sig = SassFunction "max3($a, $b, $c)" max3 ----- This description allows compiler to map Haskell function (@max3@) to a form--- that may be used in sass. Signature consists of function name (@max3@),--- opening parenthesis, list of arguments (dollar sign and its name) separated--- by comma and closing parenthesis. It is the same as function definition in--- sass code.+-- This description allows the compiler to map Haskell function (@max3@) to a+-- form that may be used in sass. Signature consists of function name (@max3@),+-- an opening parenthesis, a list of arguments (dollar sign and its name)+-- separated by commas and a closing parenthesis. It is the same as a function+-- definition in sass code. ----- With this code we may tell compiler to use this function. In order to do--- this, we must replace 'sassFunctions' field in 'SassOptions':+-- We can now tell the compiler to use our function. In order to do this, we+-- must replace 'sassFunctions' field in 'SassOptions': -- -- > opts = def { sassFunctions = Just [max3sig] } --@@ -122,7 +130,7 @@ -- -- > "foo { margin: 3px; }" ----- There exist several functions that are special:+-- There exists several functions that are special: -- -- * @*@ - fallback implementation -- * @@warn@ - overload warn statement@@ -133,22 +141,22 @@ -- documentation for more information.  -- $headers_and_importers--- Importers are functions that override default behaviour of @import statement--- behaviour. For example, you may implement rewrite rules or even download--- stylesheets from remote server.+-- Importers are functions that override default behaviour of @import statements+-- For example, you may implement rewrite rules or even download stylesheets+-- from remote server. -- -- Headers leverage the same infrastructure as importers - they are just used -- not for @imports, but for every file being loaded. They allow you to inject--- arbitrary sass source in the file.+-- arbitrary sass source in a file. ----- Let's say that we want to inject path to currently compiled file. We may write--- following header:+-- Let's say that we want to inject a path to currently compiled file. We may+-- write the following header: -- -- > header src = return [makeSourceImport $ "$file: " ++ src ++ ";"] ----- It simply returns sass code that defines @$file@ variable set to path to--- current file (first argument of function).--- Then, we must define header signature and options:+-- It simply returns sass code that defines a @$file@ variable set to a path to+-- the current file (first argument of the function).+-- Then, we must define header signature and override options: -- -- > headerSig = SassImporter 1 header -- > opts = def { sassHeaders = Just [headerSig], sassInputPath = Just "path" }@@ -163,11 +171,11 @@ -- -- > "foo { prop: path; }" ----- Importers are defined and act similarly - they just take path to file being--- imported instead of file being processed and are injected using+-- Importers are defined and act similarly - they just take path to the file+-- being imported instead of file being processed and are injected using -- 'sassImporters'. ----- Additionally importers support priorities - if two importers return source+-- Additionally, importers support priorities - if two importers return source -- for some file, the one with higher priority wins. For example -- -- > importer1 src = return [makeSourceImport $ "$file: " ++ src ++ "1;"]@@ -180,8 +188,8 @@ -- -- > "foo { prop: file2; }" ----- Instead of providing source code for imports, you may provide path to file--- and leave loading to library. This is done by settings only 'importPath' and--- 'importBase' in 'SassImport' or using 'makePathImport' instead of--- 'makeSourceImport'. This may be useful to implement just rewrite rules and--- not full loading.+-- Instead of providing source code for imports, you may provide a path to a+-- file and leave loading to the library. This is done by settings only+-- 'importPath' and 'importBase' in 'SassImport' or using 'makePathImport'+-- instead of 'makeSourceImport'. This may be useful to implement just rewrite+-- rules and not full loading.
Text/Sass/Compilation.hs view
@@ -1,12 +1,22 @@ -- | Compilation of sass source or sass files.-{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE BangPatterns         #-}+{-# LANGUAGE FlexibleInstances    #-}+{-# LANGUAGE TypeSynonymInstances #-} module Text.Sass.Compilation   (     -- * Compilation     compileFile   , compileString+    -- * Results+  , SassExtendedResult+  , StringResult+  , ExtendedResult+  , resultString+  , resultIncludes+  , resultSourcemap     -- * Error reporting-  , SassError (errorStatus)+  , SassError+  , errorStatus   , errorJson   , errorText   , errorMessage@@ -16,8 +26,9 @@   , errorColumn   ) where -import qualified Bindings.Libsass   as Lib-import           Control.Monad      ((>=>))+import qualified Bindings.Libsass    as Lib+import           Control.Applicative ((<$>))+import           Control.Monad       (forM, (>=>)) import           Foreign import           Foreign.C import           Text.Sass.Internal@@ -29,6 +40,34 @@     errorContext :: ForeignPtr Lib.SassContext } +-- | Represents extended result - compiled string with a list of includes and+-- a source map.+--+-- Subject to name change in future versions.+data SassExtendedResult = SassExtendedResult {+    resultString  :: String, -- ^ Compiled string.+    resultContext :: ForeignPtr Lib.SassContext+}++-- | Result of compilation - 'Either' 'SassError' or a compiled string.+--+-- Subject to name change in future versions.+type StringResult = IO (Either SassError String)++-- | Result of compilation - 'Either' 'SassError' or extended results - a+-- compiled string with a list of included files and a source map.+--+-- Subject to name change in future versions.+type ExtendedResult = IO (Either SassError SassExtendedResult)++-- | Typeclass that allows multiple results from compilation functions.+--+-- Currently, only two types are supported - 'String' and 'SassExtendedResult'.+-- The first provides only a compiled string, the latter one gives access to a+-- list of included files and a source map (if available).+class SassResult a where+    toSassResult :: ForeignPtr Lib.SassContext -> IO a+ instance Show SassError where     show (SassError s _) =         "SassError: cannot compile provided source, error status: " ++ show s@@ -36,7 +75,23 @@ instance Eq SassError where     (SassError s1 _) == (SassError s2 _) = s1 == s2 --- | Loads specified property from context and converts it to desired type.+instance Show SassExtendedResult where+    show _ = "SassExtendedResult"++-- | Only compiled code.+instance SassResult String where+    toSassResult ptr = withForeignPtr ptr $ \ctx -> do+        result <- Lib.sass_context_get_output_string ctx+        !result' <- peekCString result+        return result'++-- | Compiled code with includes and a source map.+instance SassResult SassExtendedResult where+    toSassResult ptr = do+        str <- toSassResult ptr+        return $ SassExtendedResult str ptr++-- | Loads specified property from a context and converts it to desired type. loadFromError :: (Ptr Lib.SassContext -> IO a) -- ^ Accessor function.               -> (a -> IO b) -- ^ Conversion method.               -> SassError -- ^ Pointer to context.@@ -44,94 +99,105 @@ loadFromError get conv err = withForeignPtr ptr $ get >=> conv     where ptr = errorContext err --- | Equivalent to @'loadFromError' 'get' 'peekCString' 'err'@.-loadStringFromError :: (Ptr Lib.SassContext -> IO CString) -- ^ Accessor function.-                    -> SassError -- ^ Pointer to context.-                    -> IO String -- ^ Result.+-- | Equivalent of @'loadFromError' 'get' 'peekCString' 'err'@.+loadStringFromError+    :: (Ptr Lib.SassContext -> IO CString) -- ^ Accessor function.+    -> SassError -- ^ Pointer to context.+    -> IO String -- ^ Result. loadStringFromError get = loadFromError get peekCString --- | Equivalent to @'loadFromError' 'get' 'fromInteger' 'err'@.+-- | Equivalent of @'loadFromError' 'get' 'fromInteger' 'err'@. loadIntFromError :: (Integral a)                  => (Ptr Lib.SassContext -> IO a) -- ^ Accessor function.                  -> SassError -- ^ Pointer to context.                  -> IO Int -- ^ Result. loadIntFromError get = loadFromError get (return.fromIntegral) --- | Loads information about error as JSON.+-- | Loads information about an error as JSON. errorJson :: SassError -> IO String errorJson = loadStringFromError Lib.sass_context_get_error_json --- | Loads error text.+-- | Loads an error text. errorText :: SassError -> IO String errorText = loadStringFromError Lib.sass_context_get_error_text --- | Loads user-friendly error message.+-- | Loads a user-friendly error message. errorMessage :: SassError -> IO String errorMessage = loadStringFromError Lib.sass_context_get_error_message --- | Loads file where problem occured.+-- | Loads a filename where problem occured. errorFile :: SassError -> IO String errorFile = loadStringFromError Lib.sass_context_get_error_file --- | Loads error source.+-- | Loads an error source. errorSource :: SassError -> IO String errorSource = loadStringFromError Lib.sass_context_get_error_src --- | Loads line in the file where problem occured.+-- | Loads a line in the file where problem occured. errorLine :: SassError -> IO Int errorLine = loadIntFromError Lib.sass_context_get_error_line --- | Loads line in the file where problem occured.+-- | Loads a line in the file where problem occured. errorColumn :: SassError -> IO Int errorColumn = loadIntFromError Lib.sass_context_get_error_column +-- | Loads a list of files that have been included during compilation.+resultIncludes :: SassExtendedResult -> IO [String]+resultIncludes ex = withForeignPtr (resultContext ex) $ \ctx -> do+    lst <- Lib.sass_context_get_included_files ctx+    len <- Lib.sass_context_get_included_files_size ctx+    forM (arrayRange $ fromIntegral len) (peekElemOff lst >=> peekCString)++-- | Loads a source map if it was generated by libsass.+resultSourcemap :: SassExtendedResult -> IO (Maybe String)+resultSourcemap ex = withForeignPtr (resultContext ex) $ \ctx -> do+    cstr <- Lib.sass_context_get_source_map_string ctx+    if cstr == nullPtr+        then return Nothing+        else Just <$> peekCString cstr+ -- | Common code for 'compileFile' and 'compileString'.-compileInternal :: CString -- ^ String that will be passed to 'make context'.+compileInternal :: (SassResult b)+                => CString -- ^ String that will be passed to 'make context'.                 -> SassOptions                 -> (CString -> IO (Ptr a)) -- ^ Make context.                 -> (Ptr a -> IO CInt) -- ^ Compile context.-                -> (Ptr a -> IO ()) -- ^ Delete context.                 -> FinalizerPtr a -- ^ Context finalizer.-                -> IO (Either SassError String)-compileInternal str opts make compile delete finalizer = do+                -> IO (Either SassError b)+compileInternal str opts make compile finalizer = do     -- Makes an assumption, that Sass_*_Context inherits from Sass_Context     -- and Sass_Options.     context <- make str-    let context' = castPtr context     let opts' = castPtr context     copyOptionsToNative opts opts'     status <- withFunctions opts opts' $ compile context+    fptr <- castForeignPtr <$> newForeignPtr finalizer context     if status /= 0-        then do-            fptr <- newForeignPtr finalizer context-            return $ Left $-                SassError (fromIntegral status) (castForeignPtr fptr)+        then return $ Left $+            SassError (fromIntegral status) fptr         else do-            result <- Lib.sass_context_get_output_string context'-            !result' <- peekCString result-            delete context-            return $ Right result'-+            result <- toSassResult fptr+            return $ Right result --- | Compiles file using specified options.-compileFile :: FilePath -- ^ Path to the file.+-- | Compiles a file using specified options.+compileFile :: SassResult a+            => FilePath -- ^ Path to the file.             -> SassOptions -- ^ Compilation options.-            -> IO (Either SassError String) -- ^ Error or output string.+            -> IO (Either SassError a) -- ^ Error or output string. compileFile path opts = withCString path $ \cpath ->     compileInternal cpath opts         Lib.sass_make_file_context         Lib.sass_compile_file_context-        Lib.sass_delete_file_context         Lib.p_sass_delete_file_context  -- | Compiles raw Sass content using specified options.-compileString :: String -- ^ String to compile.+compileString :: SassResult a+              => String -- ^ String to compile.               -> SassOptions -- ^ Compilation options.-              -> IO (Either SassError String) -- ^ Error or output string.+              -> IO (Either SassError a) -- ^ Error or output string. compileString str opts = do     cdata <- newCString str     compileInternal cdata opts         Lib.sass_make_data_context         Lib.sass_compile_data_context-        Lib.sass_delete_data_context         Lib.p_sass_delete_data_context
Text/Sass/Functions/Internal.hs view
@@ -121,4 +121,4 @@ -- Libsass does not provide function to free this kind of objects, but we -- provide it just in case. freeNativeImporterList :: Lib.SassImporterList -> IO ()-freeNativeImporterList lst = (loopCList freeNativeImporter lst) >> free lst+freeNativeImporterList lst = loopCList freeNativeImporter lst >> free lst
Text/Sass/Options/Internal.hs view
@@ -55,7 +55,7 @@               -> IO a -- ^ Action.               -> IO a -- ^ Result withFunctions opt ptr action =-    case (sassFunctions opt) of+    case sassFunctions opt of         Nothing -> action         Just lst -> do             nativeFnList <- makeNativeFunctionList lst
Text/Sass/Utils.hs view
@@ -1,6 +1,5 @@ -- | Helper functions. This module is internal and should not be used in -- production code.-{-# LANGUAGE ViewPatterns #-} module Text.Sass.Utils   (     -- * Interoperation with C API@@ -53,7 +52,7 @@ copyToCList create convert set list = do     let len = length list     result <- create $ fromIntegral len-    zipWithM_ (addToList result) [0..(fromIntegral len) - 1] list+    zipWithM_ (addToList result) [0..fromIntegral len - 1] list     return result     where         addToList lst idx = convert >=> set lst idx
Text/Sass/Values/Internal.hs view
@@ -31,7 +31,7 @@ toNativeValue (SassWarning str) = withCString str Lib.sass_make_warning toNativeValue (SassError str) = withCString str Lib.sass_make_error toNativeValue (SassList lst sep') =-    copyToCList (flip Lib.sass_make_list sep) toNativeValue+    copyToCList (`Lib.sass_make_list` sep) toNativeValue         Lib.sass_list_set_value lst     where sep = fromIntegral $ fromEnum sep' @@ -68,9 +68,9 @@ fromNativeValue' Lib.SassString ptr =     SassString <$> (Lib.sass_string_get_value ptr >>= peekCString) fromNativeValue' Lib.SassNull _ = return SassNull-fromNativeValue' Lib.SassWarning ptr = do+fromNativeValue' Lib.SassWarning ptr =     SassWarning <$> (Lib.sass_warning_get_message ptr >>= peekCString)-fromNativeValue' Lib.SassError ptr = do+fromNativeValue' Lib.SassError ptr =     SassError <$> (Lib.sass_error_get_message ptr >>= peekCString) fromNativeValue' Lib.SassList ptr = do     len <- Lib.sass_list_get_length ptr
hsass.cabal view
@@ -1,5 +1,5 @@ name:                hsass-version:             0.1.0+version:             0.2.0 license:             MIT license-file:        LICENSE author:              Jakub Fijałkowski <fiolek94@gmail.com>@@ -46,7 +46,7 @@     , Text.Sass.Values.Internal     , Text.Sass.Utils   build-depends:-    base               >= 4.7 && <4.8,+    base               >= 4.7 && < 5,     hlibsass           >= 0.1.1,     data-default-class,     filepath           >= 1.0,