on master help sign in
Pattern version updates
d2aaf33Jasper Van der Jeugt
src/Hakyll/Core/Identifier/Pattern.hs+46−44
@@ -37,13 +37,13 @@ module Hakyll.Core.Identifier.Pattern
37 , fromList
37 , fromList
38 , fromRegex
38 , fromRegex
39 , fromVersion
39 , fromVersion
40+ , hasVersion
41+ , hasNoVersion
40
42
41− -- * Manipulating patterns
43+ -- * Composing patterns
42 , (.&&.)
44 , (.&&.)
43 , (.||.)
45 , (.||.)
44 , complement
46 , complement
45− , withVersion
46− , noVersion
47
47
48 -- * Applying patterns
48 -- * Applying patterns
49 , matches
49 , matches
@@ -105,7 +105,6 @@ data Pattern
105 = Everything
105 = Everything
106 | Complement Pattern
106 | Complement Pattern
107 | And Pattern Pattern
107 | And Pattern Pattern
108− | Or Pattern Pattern
109 | Glob [GlobComponent]
108 | Glob [GlobComponent]
110 | List (Set Identifier)
109 | List (Set Identifier)
111 | Regex String
110 | Regex String
@@ -118,20 +117,18 @@ instance Binary Pattern where
118 put Everything = putWord8 0
117 put Everything = putWord8 0
119 put (Complement p) = putWord8 1 >> put p
118 put (Complement p) = putWord8 1 >> put p
120 put (And x y) = putWord8 2 >> put x >> put y
119 put (And x y) = putWord8 2 >> put x >> put y
121− put (Or x y) = putWord8 3 >> put x >> put y
120+ put (Glob g) = putWord8 3 >> put g
122− put (Glob g) = putWord8 4 >> put g
123− put (List is) = putWord8 5 >> put is
121+ put (List is) = putWord8 4 >> put is
124− put (Regex r) = putWord8 6 >> put r
122+ put (Regex r) = putWord8 5 >> put r
125− put (Version v) = putWord8 7 >> put v
123+ put (Version v) = putWord8 6 >> put v
126
124
127 get = getWord8 >>= \t -> case t of
125 get = getWord8 >>= \t -> case t of
128 0 -> pure Everything
126 0 -> pure Everything
129 1 -> Complement <$> get
127 1 -> Complement <$> get
130 2 -> And <$> get <*> get
128 2 -> And <$> get <*> get
131− 3 -> Or <$> get <*> get
132− 4 -> Glob <$> get
129+ 3 -> Glob <$> get
133− 5 -> List <$> get
130+ 4 -> List <$> get
134− 6 -> Regex <$> get
131+ 5 -> Regex <$> get
135 _ -> Version <$> get
132 _ -> Version <$> get
136
133
137
134
@@ -146,19 +143,6 @@ instance Monoid Pattern where
146 mappend = (.&&.)
143 mappend = (.&&.)
147
144
148
145
149−--------------------------------------------------------------------------------
150−-- | This is necessary for good 'isLiteral' results
151−optimize :: Pattern -> Pattern
152−optimize (Complement x) = Complement (optimize x)
153−optimize (And x Everything) = x
154−optimize (And Everything y) = y
155−optimize (And x y) = And (optimize x) (optimize y)
156−optimize (Or _ Everything) = Everything
157−optimize (Or Everything _) = Everything
158−optimize (Or x y) = Or (optimize x) (optimize y)
159−optimize p = p
160−
161−
162--------------------------------------------------------------------------------
146--------------------------------------------------------------------------------
163-- | Parse a pattern from a string
147-- | Parse a pattern from a string
164fromGlob :: String -> Pattern
148fromGlob :: String -> Pattern
@@ -174,7 +158,24 @@ fromGlob = Glob . parse'
174
158
175
159
176--------------------------------------------------------------------------------
160--------------------------------------------------------------------------------
177−-- | Create a 'Pattern' from a list of 'Identifier's it should match
161+-- | Create a 'Pattern' from a list of 'Identifier's it should match.
162+--
163+-- /Warning/: use this carefully with 'hasNoVersion' and 'hasVersion'. The
164+-- 'Identifier's in the list /already/ have versions assigned, and the pattern
165+-- will then only match the intersection of both versions.
166+--
167+-- A more concrete example,
168+--
169+-- > fromList ["foo.markdown"] .&&. hasVersion "pdf"
170+--
171+-- will not match anything! The @"foo.markdown"@ 'Identifier' has no version
172+-- assigned, so the LHS of '.&&.' will only match this 'Identifier' with no
173+-- version. The RHS only matches 'Identifier's with version set to @"pdf"@ --
174+-- hence, this pattern matches nothing.
175+--
176+-- The correct way to use this is:
177+--
178+-- > fromList (map (setVersion "pdf") ["foo.markdown"])
178fromList :: [Identifier] -> Pattern
179fromList :: [Identifier] -> Pattern
179fromList = List . S.fromList
180fromList = List . S.fromList
180
181
@@ -195,17 +196,33 @@ fromVersion :: Maybe String -> Pattern
195fromVersion = Version
196fromVersion = Version
196
197
197
198
199+--------------------------------------------------------------------------------
200+-- | Specify a version, e.g.
201+--
202+-- > "foo/*.markdown" .&&. hasVersion "pdf"
203+hasVersion :: String -> Pattern
204+hasVersion = fromVersion . Just
205+
206+
207+--------------------------------------------------------------------------------
208+-- | Match only if the identifier has no version set, e.g.
209+--
210+-- > "foo/*.markdown" .&&. hasNoVersion
211+hasNoVersion :: Pattern
212+hasNoVersion = fromVersion Nothing
213+
214+
198--------------------------------------------------------------------------------
215--------------------------------------------------------------------------------
199-- | '&&' for patterns: the given identifier must match both subterms
216-- | '&&' for patterns: the given identifier must match both subterms
200(.&&.) :: Pattern -> Pattern -> Pattern
217(.&&.) :: Pattern -> Pattern -> Pattern
201−x .&&. y = optimize (And x y)
218+x .&&. y = And x y
202infixr 3 .&&.
219infixr 3 .&&.
203
220
204
221
205--------------------------------------------------------------------------------
222--------------------------------------------------------------------------------
206-- | '||' for patterns: the given identifier must match any subterm
223-- | '||' for patterns: the given identifier must match any subterm
207(.||.) :: Pattern -> Pattern -> Pattern
224(.||.) :: Pattern -> Pattern -> Pattern
208−x .||. y = optimize (Or x y)
225+x .||. y = complement (complement x `And` complement y) -- De Morgan's law
209infixr 2 .||.
226infixr 2 .||.
210
227
211
228
@@ -219,27 +236,12 @@ complement :: Pattern -> Pattern
219complement = Complement
236complement = Complement
220
237
221
238
222−--------------------------------------------------------------------------------
223−-- | Specify a version, e.g.
224−--
225−-- > "foo/*.markdown" `withVersion` "pdf"
226−withVersion :: Pattern -> String -> Pattern
227−withVersion p v = optimize $ And p $ fromVersion $ Just v
228−
229−
230−--------------------------------------------------------------------------------
231−-- | Match only if the identifier has no version set
232−noVersion :: Pattern -> Pattern
233−noVersion p = optimize $ And p $ fromVersion Nothing
234−
235−
236--------------------------------------------------------------------------------
239--------------------------------------------------------------------------------
237-- | Check if an identifier matches a pattern
240-- | Check if an identifier matches a pattern
238matches :: Pattern -> Identifier -> Bool
241matches :: Pattern -> Identifier -> Bool
239matches Everything _ = True
242matches Everything _ = True
240matches (Complement p) i = not $ matches p i
243matches (Complement p) i = not $ matches p i
241matches (And x y) i = matches x i && matches y i
244matches (And x y) i = matches x i && matches y i
242−matches (Or x y) i = matches x i || matches y i
243matches (Glob p) i = isJust $ capture (Glob p) i
245matches (Glob p) i = isJust $ capture (Glob p) i
244matches (List l) i = i `S.member` l
246matches (List l) i = i `S.member` l
245matches (Regex r) i = toFilePath i =~ r
247matches (Regex r) i = toFilePath i =~ r
tests/Hakyll/Core/Identifier/Tests.hs+1
@@ -56,4 +56,5 @@ matchesTests = fromAssertions "matches"
56 , True @=? matches (complement "foo.markdown") "bar.markdown"
56 , True @=? matches (complement "foo.markdown") "bar.markdown"
57 , False @=? matches (complement "foo.markdown") "foo.markdown"
57 , False @=? matches (complement "foo.markdown") "foo.markdown"
58 , True @=? matches ("foo" .||. "bar") "bar"
58 , True @=? matches ("foo" .||. "bar") "bar"
59+ , False @=? matches ("bar" .&&. hasNoVersion) (setVersion (Just "xz") "bar")
59 ]
60 ]
web/tutorials/06-versions.markdown+2−2
@@ -55,13 +55,13 @@ is valid code, but **probably not** what you want to do: this will select all
55to fix this, use any of the following:
55to fix this, use any of the following:
56
56
57```haskell
57```haskell
58−loadAll (noVersion "posts/*") :: Compiler [Item String]
58+loadAll ("posts/*" .&&. hasNoVersion) :: Compiler [Item String]
59```
59```
60
60
61for the default versions, i.e. the HTML pages, and:
61for the default versions, i.e. the HTML pages, and:
62
62
63```haskell
63```haskell
64−loadAll ("posts/*" `withVersion` "raw") :: Compiler [Item String]
64+loadAll ("posts/*" .&&. hasVersion "raw") :: Compiler [Item String]
65```
65```
66
66
67for the raw versions.
67for the raw versions.