hsass 0.4.2 → 0.5.0
raw patch · 10 files changed
+109/−46 lines, 10 filesdep ~hlibsassPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: hlibsass
API changes (from Hackage documentation)
+ Text.Sass.Functions: SassHeader :: Double -> SassHeaderType -> SassHeader
+ Text.Sass.Functions: [headerFunction] :: SassHeader -> SassHeaderType
+ Text.Sass.Functions: [headerPriority] :: SassHeader -> Double
+ Text.Sass.Functions: data SassHeader
+ Text.Sass.Functions: type SassHeaderType = String Absolute path to the file being processed. -> IO [SassImport] Imports.
- Text.Sass.Functions: type SassImporterType = String Path to the import that needs to be loaded or file that is being processed when used as a header. -> IO [SassImport] Imports.
+ Text.Sass.Functions: type SassImporterType = String Path to the import that needs to be loaded. -> String Absolute path to the importing file. -> IO [SassImport] Imports.
- Text.Sass.Options: SassOptions :: Int -> SassOutputStyle -> Bool -> Bool -> Bool -> Bool -> Bool -> String -> String -> Maybe FilePath -> Maybe FilePath -> Maybe [FilePath] -> Maybe [FilePath] -> Maybe FilePath -> Maybe String -> Maybe [SassFunction] -> Maybe [SassImporter] -> Maybe [SassImporter] -> SassOptions
+ Text.Sass.Options: SassOptions :: Int -> SassOutputStyle -> Bool -> Bool -> Bool -> Bool -> Bool -> String -> String -> Maybe FilePath -> Maybe FilePath -> Maybe [FilePath] -> Maybe [FilePath] -> Maybe FilePath -> Maybe String -> Maybe [SassFunction] -> Maybe [SassHeader] -> Maybe [SassImporter] -> SassOptions
- Text.Sass.Options: [sassHeaders] :: SassOptions -> Maybe [SassImporter]
+ Text.Sass.Options: [sassHeaders] :: SassOptions -> Maybe [SassHeader]
Files
- CHANGELOG.md +9/−0
- Text/Sass.hs +27/−17
- Text/Sass/Functions.hs +19/−5
- Text/Sass/Functions/Internal.hs +8/−3
- Text/Sass/Options.hs +1/−1
- Text/Sass/Options/Internal.hs +6/−1
- hsass.cabal +1/−1
- test/Text/Sass/CompilationSpec.hs +2/−2
- test/Text/Sass/FunctionsSpec.hs +18/−9
- test/Text/Sass/TutorialSpec.hs +18/−7
CHANGELOG.md view
@@ -2,6 +2,14 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [0.5.0] - 2017-11-01+### Changed+- Split `SassImporter` into `SassImporter` and `SassHeader` (thanks @h-3-0)++### Added+- `SassIporter` now takes path to the file that is being imported into (thanks+ @h-3-0)+ ## [0.4.2] - 2017-08-28 ### Added - Introduce `defaultSassOptions` as default options (thanks @chris-martin !)@@ -53,3 +61,4 @@ [0.4.0]: https://github.com/jakubfijalkowski/hsass/compare/v0.3.0...v0.4.0 [0.4.1]: https://github.com/jakubfijalkowski/hsass/compare/v0.4.0...v0.4.1 [0.4.2]: https://github.com/jakubfijalkowski/hsass/compare/v0.4.1...v0.4.2+[0.5.0]: https://github.com/jakubfijalkowski/hsass/compare/v0.4.2...v0.5.0
Text/Sass.hs view
@@ -141,16 +141,15 @@ -- documentation for more information. -- $headers_and_importers--- Importers are functions that override default behaviour of @import statements--- 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 a 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 a file.+-- Headers allow you to insert arbitrary sass at the beginning of the file being+-- compiled. ----- Let's say that we want to inject a path to currently compiled file. We may--- write the following header:+-- Let's say that we want to inject a path to the currently compiled file. We+-- may write the following header: -- -- > header src = return [makeSourceImport $ "$file: " ++ src ++ ";"] --@@ -158,10 +157,10 @@ -- the current file (first argument of the function). -- Then, we must define header signature and override options: ----- > headerSig = SassImporter 1 header+-- > headerSig = SassHeader 1 header -- > opts = def { sassHeaders = Just [headerSig], sassInputPath = Just "path" } ----- We set 'sassInputPath', because we will be compiling string and it won't be+-- We set 'sassInputPath', because we will be compiling a string and it won't be -- set automatically. -- Now, executing --@@ -171,15 +170,26 @@ -- -- > "foo { prop: path; }" ----- 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'.+-- Importers are defined and act similarly, but they take two arguments. The+-- first argument is the path to the file being imported, and the second+-- argument is the path to the importing file. For example ----- Additionally, importers support priorities - if two importers return source--- for some file, the one with higher priority wins. For example+-- > importer imp src = return+-- > [makeSourceImport $ "/* imported " ++ imp ++ " into " ++ src ++ " */"]+-- > sassImporter = Just [SassImporter 1 importer]+-- > opts = def { sassImporters = sassImporter, sassInputPath = Just "file" }+-- > compileString "@import \"relative/path\"" opts ----- > importer1 src = return [makeSourceImport $ "$file: " ++ src ++ "1;"]--- > importer2 src = return [makeSourceImport $ "$file: " ++ src ++ "2;"]+-- Gives+--+-- > "/* imported relative/path into file */"+--+-- The first argument to 'SassHeader' or 'SassImporter' is its priority - if two+-- importers return source for some file, the one with higher priority wins. For+-- example+--+-- > importer1 imp _ = return [makeSourceImport $ "$file: " ++ imp ++ "1;"]+-- > importer2 imp _ = return [makeSourceImport $ "$file: " ++ imp ++ "2;"] -- > importerSigs = [SassImporter 0.5 importer1, SassImporter 1 importer2] -- > opts = def { sassImporters = Just importerSigs } -- > compileString "@import \"file\";\nfoo { prop: $file; }" opts
Text/Sass/Functions.hs view
@@ -8,6 +8,8 @@ , SassImport (..) , SassImporterType , SassImporter (..)+ , SassHeaderType+ , SassHeader (..) , makeSourceImport , makePathImport ) where@@ -40,20 +42,32 @@ importSourceMap :: Maybe String -- ^ Source map of the import. } --- | Type of the function that acts like importer/header.+-- | Type of the function that acts like an importer. ----- You may return empty list in order to tell libsass to handle the import by--- itself or not insert any header.+-- You may return the empty list in order to tell libsass to handle the import by+-- itself. type SassImporterType = String- -- ^ Path to the import that needs to be loaded or file that is being- -- processed when used as a header.+ -- ^ Path to the import that needs to be loaded.+ -> String+ -- ^ Absolute path to the importing file. -> IO [SassImport] -- ^ Imports. -- | Description of the importer. data SassImporter = SassImporter { importerPriority :: Double -- ^ Priority of the importer. , importerFunction :: SassImporterType -- ^ Main function.+}++-- | Type of the function that acts like a header.+type SassHeaderType =+ String -- ^ Absolute path to the file being processed.+ -> IO [SassImport] -- ^ Imports.++-- | Description of the header.+data SassHeader = SassHeader {+ headerPriority :: Double -- ^ Priority of the header.+ , headerFunction :: SassHeaderType -- ^ Main function. } -- | 'makeSourceImport' @s@ is equivalent to 'SassImport'
Text/Sass/Functions/Internal.hs view
@@ -75,9 +75,14 @@ -- | Wraps function of type 'SassImporterType'. wrapImporter :: SassImporterType -> Lib.SassImporterFnType-wrapImporter fn url _ _ = peekCString url >>= fn >>= \case- [] -> return nullPtr- xs -> makeNativeImportList xs+wrapImporter fn url _ compiler = do+ lastImport <- Lib.sass_compiler_get_last_import compiler+ absPath <- Lib.sass_import_get_abs_path lastImport >>= peekCString+ url' <- peekCString url+ importList <- fn url' absPath+ case importList of+ [] -> return nullPtr+ xs -> makeNativeImportList xs -- | Converts 'SassImport' into native representation. makeNativeImport :: SassImport -> IO Lib.SassImportEntry
Text/Sass/Options.hs view
@@ -51,7 +51,7 @@ -- | List of user-supplied functions that provide "headers" for sass files. -- Header is injected at the beginning of a file which name is passed as -- the first argument of importer.- , sassHeaders :: Maybe [SassImporter]+ , sassHeaders :: Maybe [SassHeader] -- | List of user-supplied functions that resolve @import directives. , sassImporters :: Maybe [SassImporter] }
Text/Sass/Options/Internal.hs view
@@ -15,6 +15,7 @@ import Control.Monad ((>=>)) import Foreign import Foreign.C+import Text.Sass.Functions import Text.Sass.Functions.Internal import Text.Sass.Options import Text.Sass.Utils@@ -45,11 +46,15 @@ withOptionalCString (sassSourceMapRoot opt) (Lib.sass_option_set_source_map_root ptr) maybe (return ())- (makeNativeImporterList >=> Lib.sass_option_set_c_headers ptr)+ (makeNativeImporterList . fmap fromHeader+ >=> Lib.sass_option_set_c_headers ptr) (sassHeaders opt) maybe (return ()) (makeNativeImporterList >=> Lib.sass_option_set_c_importers ptr) (sassImporters opt)+ where+ fromHeader (SassHeader p f) = SassImporter p (\filename _ -> f filename)+ -- | Copies 'sassFunctions' to native object, executes action, clears leftovers -- (see documentation of 'makeNativeFunction') and returns action result.
hsass.cabal view
@@ -1,5 +1,5 @@ name: hsass-version: 0.4.2+version: 0.5.0 license: MIT license-file: LICENSE author: Jakub Fijałkowski <fiolek94@gmail.com>
test/Text/Sass/CompilationSpec.hs view
@@ -13,8 +13,8 @@ main :: IO () main = hspec spec -importerFunc :: String -> IO [SassImport]-importerFunc _ = return [makeSourceImport "a { margin: 1px; }"]+importerFunc :: String -> String -> IO [SassImport]+importerFunc _ _ = return [makeSourceImport "a { margin: 1px; }"] importers :: [SassImporter] importers = [SassImporter 1 importerFunc]
test/Text/Sass/FunctionsSpec.hs view
@@ -1,7 +1,7 @@ module Text.Sass.FunctionsSpec where import Test.Hspec-import Text.Sass+import Text.Sass hiding (headerFunction) fooFunction :: SassValue -> IO SassValue fooFunction _ = return $ SassNumber 1 "px"@@ -23,14 +23,14 @@ altInclContent = "b {\n margin: 5px; }\n" headerFunction :: String -> IO [SassImport]-headerFunction _ = return [makeSourceImport inclContent]+headerFunction src = return [makeSourceImport $ src ++ "{\n margin: 1px; }\n"] -headers :: [SassImporter]-headers = [SassImporter 1 headerFunction]+headers :: [SassHeader]+headers = [SassHeader 1 headerFunction] -importFunction :: String -> IO [SassImport]-importFunction "_imp" = return [makeSourceImport inclContent]-importFunction _ = return [makeSourceImport altInclContent]+importFunction :: String -> String -> IO [SassImport]+importFunction "_imp" _ = return [makeSourceImport inclContent]+importFunction _ _ = return [makeSourceImport altInclContent] importers :: [SassImporter] importers = [SassImporter 1 importFunction]@@ -51,9 +51,18 @@ Right "a {\n margin: 1px; }\n" it "should correctly inject header" $ do- let opts = def { sassHeaders = Just headers }+ let opts = def { sassHeaders = Just headers, sassInputPath = Just "path" } compileString "a { margin : 1px; }" opts `shouldReturn`- Right (inclContent ++ "\na {\n margin: 1px; }\n")+ Right ("path {\n margin: 1px; }\n\na {\n margin: 1px; }\n")++ it "should not apply header to imports" $ do+ let opts = def {+ sassHeaders = Just headers+ , sassImporters = Just importers+ , sassInputPath = Just "path"+ }+ compileString "@import '_imp';" opts `shouldReturn`+ Right ("path {\n margin: 1px; }\n\n" ++ inclContent) it "should call importers" $ do let opts = def { sassImporters = Just importers }
test/Text/Sass/TutorialSpec.hs view
@@ -24,15 +24,22 @@ header :: String -> IO [SassImport] header src = return [makeSourceImport $ "$file: " ++ src ++ ";"] -headerSig :: SassImporter-headerSig = SassImporter 1 header+headerSig :: SassHeader+headerSig = SassHeader 1 header -importer1 :: String -> IO [SassImport]-importer1 src = return [makeSourceImport $ "$file: " ++ src ++ "1;"]+importer :: String -> String -> IO [SassImport]+importer imp src = return+ [makeSourceImport $ "/* imported " ++ imp ++ " into " ++ src ++ " */"] -importer2 :: String -> IO [SassImport]-importer2 src = return [makeSourceImport $ "$file: " ++ src ++ "2;"]+sassImporter :: Maybe [SassImporter]+sassImporter = Just [SassImporter 1 importer] +importer1 :: String -> String -> IO [SassImport]+importer1 imp _ = return [makeSourceImport $ "$file: " ++ imp ++ "1;"]++importer2 :: String -> String -> IO [SassImport]+importer2 imp _ = return [makeSourceImport $ "$file: " ++ imp ++ "2;"]+ importerSigs :: [SassImporter] importerSigs = [SassImporter 0.5 importer1, SassImporter 1 importer2] @@ -75,7 +82,11 @@ compileString "foo { prop: $file; }" opts `shouldReturn` Right "foo {\n prop: path; }\n" - describe "Importers" $+ describe "Importers" $ do+ it "should provide the importer with the correct arguments" $ do+ let opts = def { sassImporters = sassImporter, sassInputPath = Just "file" }+ compileString "@import \"relative/path\"" opts+ `shouldReturn` Right "/* imported relative/path into file */\n" it "should inject import with higher priority" $ do let opts = def { sassImporters = Just importerSigs } compileString "@import \"file\";\nfoo { prop: $file; }" opts