@@ -33,6 +33,7 @@
3333--
3434module Hakyll.Core.Identifier.Pattern
3535 ( Pattern
36+ , castPattern
3637 , parseGlob
3738 , predicate
3839 , regex
@@ -64,21 +65,27 @@ data GlobComponent = Capture
6465
6566-- | Type that allows matching on identifiers
6667--
67−data Pattern = Glob [GlobComponent]
68− | Predicate (Identifier -> Bool)
68+data Pattern a = Glob [GlobComponent]
69+ | Predicate (Identifier -> Bool)
70+ | List [Identifier]
6971
70−instance IsString Pattern where
72+instance IsString (Pattern a) where
7173 fromString = parseGlob
7274
73−instance Monoid Pattern where
75+instance Monoid (Pattern a) where
7476 mempty = Predicate (const True)
75− g@(Glob _) `mappend` x = Predicate (matches g) `mappend` x
76− x `mappend` g@(Glob _) = x `mappend` Predicate (matches g)
77− Predicate f `mappend` Predicate g = Predicate $ \i -> f i && g i
77+ p1 `mappend` p2 = Predicate $ \i -> matches p1 i && matches p2 i
78+
79+-- | Discard the phantom type parameter
80+--
81+castPattern :: Pattern a -> Pattern b
82+castPattern (Glob g) = Glob g
83+castPattern (Predicate p) = Predicate p
84+castPattern (List l) = List l
7885
7986-- | Parse a pattern from a string
8087--
81−parseGlob :: String -> Pattern
88+parseGlob :: String -> Pattern a
8289parseGlob = Glob . parse'
8390 where
8491 parse' str =
@@ -95,7 +102,7 @@ parseGlob = Glob . parse'
95102--
96103-- > predicate (\i -> matches "foo/*" i && not (matches "foo/bar" i))
97104--
98−predicate :: (Identifier -> Bool) -> Pattern
105+predicate :: (Identifier -> Bool) -> Pattern a
99106predicate = Predicate
100107
101108-- | Create a 'Pattern' from a regex
@@ -104,24 +111,25 @@ predicate = Predicate
104111--
105112-- > regex "^foo/[^x]*$
106113--
107−regex :: String -> Pattern
114+regex :: String -> Pattern a
108115regex str = predicate $ fromMaybe False . (=~~ str) . toFilePath
109116
110117-- | Create a 'Pattern' which matches if the identifier is in a certain group
111118-- (or in no group)
112119--
113−inGroup :: Maybe String -> Pattern
120+inGroup :: Maybe String -> Pattern a
114121inGroup group = predicate $ (== group) . identifierGroup
115122
116123-- | Check if an identifier matches a pattern
117124--
118−matches :: Pattern -> Identifier -> Bool
125+matches :: Pattern a -> Identifier -> Bool
119126matches (Glob p) = isJust . capture (Glob p)
120127matches (Predicate p) = (p $)
128+matches (List l) = (`elem` l)
121129
122130-- | Given a list of identifiers, retain only those who match the given pattern
123131--
124−filterMatches :: Pattern -> [Identifier] -> [Identifier]
132+filterMatches :: Pattern a -> [Identifier] -> [Identifier]
125133filterMatches = filter . matches
126134
127135-- | Split a list at every possible point, generate a list of (init, tail)
@@ -132,9 +140,9 @@ splits = inits &&& tails >>> uncurry zip >>> reverse
132140
133141-- | Match a glob against a pattern, generating a list of captures
134142--
135−capture :: Pattern -> Identifier -> Maybe [String]
143+capture :: Pattern a -> Identifier -> Maybe [String]
136144capture (Glob p) (Identifier _ i) = capture' p i
137−capture (Predicate _) _ = Nothing
145+capture _ _ = Nothing
138146
139147-- | Internal verion of 'capture'
140148--
@@ -164,17 +172,17 @@ capture' (CaptureMany : ms) str =
164172--
165173-- > "tags/foo"
166174--
167−fromCapture :: Pattern -> String -> Identifier
175+fromCapture :: Pattern a -> String -> Identifier
168176fromCapture pattern = fromCaptures pattern . repeat
169177
170178-- | Create an identifier from a pattern by filling in the captures with the
171179-- given list of strings
172180--
173−fromCaptures :: Pattern -> [String] -> Identifier
174−fromCaptures (Glob p) = Identifier Nothing . fromCaptures' p
175−fromCaptures (Predicate _) = error $
176− "Hakyll.Core.Identifier.Pattern.fromCaptures: fromCaptures called on a " ++
177− "predicate instead of a glob"
181+fromCaptures :: Pattern a -> [String] -> Identifier
182+fromCaptures (Glob p) = Identifier Nothing . fromCaptures' p
183+fromCaptures _ = error $
184+ "Hakyll.Core.Identifier.Pattern.fromCaptures: fromCaptures only works " ++
185+ "on simple globs!"
178186
179187-- | Internally used version of 'fromCaptures'
180188--