module Skylighting.Core ( lookupSyntax , syntaxByName , syntaxByShortName , syntaxesByExtension , syntaxesByFilename , module Skylighting.Types , module Skylighting.Tokenizer , module Skylighting.Parser , module Skylighting.Regex , module Skylighting.Styles , module Skylighting.Loader , module Skylighting.Format.ANSI , module Skylighting.Format.HTML , module Skylighting.Format.LaTeX ) where import Control.Monad import Data.List (tails) import qualified Data.Map as Map import Data.Maybe (listToMaybe) import Data.Text (Text) import qualified Data.Text as Text import Skylighting.Format.ANSI import Skylighting.Format.HTML import Skylighting.Format.LaTeX import Skylighting.Loader import Skylighting.Parser import Skylighting.Regex import Skylighting.Styles import Skylighting.Tokenizer import Skylighting.Types -- | Returns a list of syntaxes appropriate for the given file extension. syntaxesByExtension :: SyntaxMap -> String -> [Syntax] syntaxesByExtension syntaxmap ('.':ext) = syntaxesByFilename syntaxmap ("*." ++ ext) syntaxesByExtension syntaxmap ext = syntaxesByFilename syntaxmap ("*." ++ ext) -- | Returns a list of syntaxes appropriate for the given filename. syntaxesByFilename :: SyntaxMap -> String -> [Syntax] syntaxesByFilename syntaxmap fn = [s | s <- Map.elems syntaxmap , matchGlobs fn (sExtensions s)] -- | Lookup a syntax by full name (case insensitive). syntaxByName :: SyntaxMap -> Text -> Maybe Syntax syntaxByName syntaxmap name = Map.lookup (Text.toLower name) (Map.mapKeys Text.toLower syntaxmap) -- | Lookup a syntax by short name (case insensitive). syntaxByShortName :: SyntaxMap -> Text -> Maybe Syntax syntaxByShortName syntaxmap name = listToMaybe [s | s <- Map.elems syntaxmap , Text.toLower (sShortname s) == Text.toLower name ] -- | Lookup syntax by (in order) full name (case insensitive), -- short name (case insensitive), extension. lookupSyntax :: Text -> SyntaxMap -> Maybe Syntax lookupSyntax lang syntaxmap -- special cases: | lang == Text.pack "csharp" = lookupSyntax (Text.pack "cs") syntaxmap | lang == Text.pack "fortran" = lookupSyntax (Text.pack "for") syntaxmap | otherwise = syntaxByName syntaxmap lang `mplus` syntaxByShortName syntaxmap lang `mplus` listToMaybe (syntaxesByExtension syntaxmap (Text.unpack lang)) -- | Match filename against a list of globs contained in a semicolon-separated -- string. matchGlobs :: String -> [String] -> Bool matchGlobs fn globs = any (flip matchGlob fn) globs -- | Match filename against a glob pattern with asterisks. matchGlob :: String -> String -> Bool matchGlob ('*':xs) fn = any (matchGlob xs) (tails fn) matchGlob (x:xs) (y:ys) = x == y && matchGlob xs ys matchGlob "" "" = True matchGlob _ _ = False