git.iko.soy/typeable/pandoc
on master help sign in
Make Extensions a custom type instead of a Set Extension.

The type is implemented in terms of an underlying bitset which should be more efficient. API change: from Text.Pandoc.Extensions export Extensions, emptyExtensions, extensionsFromList, enableExtension, disableExtension, extensionEnabled.

commit3876b91448ad8d279f5d5a9d217e00cf4583e14b authorJohn MacFarlane <jgm@berkeley.edu> dateSat 14 Jan 2017, 13:06 (10 years ago) parent1427252
8 files changed+76−59
pandoc.cabal−1 pandoc.hs+1−2 src/Text/Pandoc.hs+19−17 src/Text/Pandoc/Extensions.hs+37−17 src/Text/Pandoc/Options.hs+3−5 src/Text/Pandoc/Parsing.hs+4−4 src/Text/Pandoc/Readers/Markdown.hs+9−9 tests/Tests/Readers/Markdown.hs+3−4
pandoc.cabal−1
@@ -257,7 +257,6 @@ Library
257257 containers >= 0.1 && < 0.6,
258258 unordered-containers >= 0.2 && < 0.3,
259259 array >= 0.3 && < 0.6,
260− largeword >= 1.2 && < 1.3,
261260 parsec >= 3.1 && < 3.2,
262261 mtl >= 2.2 && < 2.3,
263262 filepath >= 1.1 && < 1.5,
pandoc.hs+1−2
@@ -47,7 +47,6 @@ import System.Environment ( getArgs, getProgName, getEnvironment )
4747import System.Exit ( ExitCode (..), exitSuccess )
4848import System.FilePath
4949import System.Console.GetOpt
50−import qualified Data.Set as Set
5150import Data.Char ( toLower, toUpper )
5251import Data.List ( intercalate, isPrefixOf, isSuffixOf, sort )
5352import System.Directory ( getAppUserDataDirectory, findExecutable,
@@ -1295,7 +1294,7 @@ options =
12951294 (NoArg
12961295 (\_ -> do
12971296 let showExt x = drop 4 (show x) ++
1298− if x `Set.member` pandocExtensions
1297+ if extensionEnabled x pandocExtensions
12991298 then " +"
13001299 else " -"
13011300 mapM_ (UTF8.hPutStrLn stdout . showExt)
src/Text/Pandoc.hs+19−17
@@ -184,15 +184,13 @@ import Text.Pandoc.Class
184184import Data.Aeson
185185import qualified Data.ByteString.Lazy as BL
186186import Data.List (intercalate)
187−import Data.Set (Set)
188−import qualified Data.Set as Set
189187import Text.Parsec
190188import Text.Parsec.Error
191189import qualified Text.Pandoc.UTF8 as UTF8
192190import Control.Monad.Except (throwError)
193191
194192parseFormatSpec :: String
195− -> Either ParseError (String, Set Extension -> Set Extension)
193+ -> Either ParseError (String, Extensions -> Extensions)
196194parseFormatSpec = parse formatSpec ""
197195 where formatSpec = do
198196 name <- formatName
@@ -208,8 +206,8 @@ parseFormatSpec = parse formatSpec ""
208206 | name == "lhs" -> return Ext_literate_haskell
209207 | otherwise -> fail $ "Unknown extension: " ++ name
210208 return $ case polarity of
211− '-' -> Set.delete ext
212− _ -> Set.insert ext
209+ '-' -> disableExtension ext
210+ _ -> enableExtension ext
213211
214212-- TODO: when we get the PandocMonad stuff all sorted out,
215213-- we can simply these types considerably. Errors/MediaBag can be
@@ -330,25 +328,29 @@ writers = [
330328 ,("tei" , StringWriter writeTEI)
331329 ]
332330
333−getDefaultExtensions :: String -> Set Extension
331+getDefaultExtensions :: String -> Extensions
334332getDefaultExtensions "markdown_strict" = strictExtensions
335333getDefaultExtensions "markdown_phpextra" = phpMarkdownExtraExtensions
336334getDefaultExtensions "markdown_mmd" = multimarkdownExtensions
337335getDefaultExtensions "markdown_github" = githubMarkdownExtensions
338336getDefaultExtensions "markdown" = pandocExtensions
339337getDefaultExtensions "plain" = plainExtensions
340−getDefaultExtensions "org" = Set.fromList [Ext_citations,
341− Ext_auto_identifiers]
342−getDefaultExtensions "textile" = Set.fromList [Ext_auto_identifiers]
343−getDefaultExtensions "html" = Set.fromList [Ext_auto_identifiers,
344− Ext_native_divs,
345− Ext_native_spans]
338+getDefaultExtensions "org" = extensionsFromList
339+ [Ext_citations, Ext_auto_identifiers]
340+getDefaultExtensions "textile" = extensionsFromList
341+ [Ext_auto_identifiers]
342+getDefaultExtensions "html" = extensionsFromList
343+ [Ext_auto_identifiers,
344+ Ext_native_divs,
345+ Ext_native_spans]
346346getDefaultExtensions "html5" = getDefaultExtensions "html"
347−getDefaultExtensions "epub" = Set.fromList [Ext_raw_html,
348− Ext_native_divs,
349− Ext_native_spans,
350− Ext_epub_html_exts]
351−getDefaultExtensions _ = Set.fromList [Ext_auto_identifiers]
347+getDefaultExtensions "epub" = extensionsFromList
348+ [Ext_raw_html,
349+ Ext_native_divs,
350+ Ext_native_spans,
351+ Ext_epub_html_exts]
352+getDefaultExtensions _ = extensionsFromList
353+ [Ext_auto_identifiers]
352354
353355-- | Retrieve reader based on formatSpec (format+extensions).
354356getReader :: PandocMonad m => String -> Either String (Reader m)
src/Text/Pandoc/Extensions.hs+37−17
@@ -29,6 +29,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2929Data structures and functions for representing markup extensions.
3030-}
3131module Text.Pandoc.Extensions ( Extension(..)
32+ , Extensions
33+ , emptyExtensions
34+ , extensionsFromList
35+ , extensionEnabled
36+ , enableExtension
37+ , disableExtension
3238 , pandocExtensions
3339 , plainExtensions
3440 , strictExtensions
@@ -36,15 +42,29 @@ module Text.Pandoc.Extensions ( Extension(..)
3642 , githubMarkdownExtensions
3743 , multimarkdownExtensions )
3844where
39−import Data.LargeWord (Word256)
40−import Data.Bits ()
41−import Data.Set (Set)
42−import qualified Data.Set as Set
45+import Data.Word (Word64)
46+import Data.Bits (testBit, setBit, clearBit)
4347import Data.Data (Data)
4448import Data.Typeable (Typeable)
4549import GHC.Generics (Generic)
4650
47−newtype Extensions = Extensions { unExtensions :: Word256 }
51+newtype Extensions = Extensions Word64
52+ deriving (Show, Read, Eq, Ord, Bounded, Data, Typeable, Generic)
53+
54+extensionsFromList :: [Extension] -> Extensions
55+extensionsFromList = foldr enableExtension emptyExtensions
56+
57+emptyExtensions :: Extensions
58+emptyExtensions = Extensions 0
59+
60+extensionEnabled :: Extension -> Extensions -> Bool
61+extensionEnabled x (Extensions exts) = testBit exts (fromEnum x)
62+
63+enableExtension :: Extension -> Extensions -> Extensions
64+enableExtension x (Extensions exts) = Extensions (setBit exts (fromEnum x))
65+
66+disableExtension :: Extension -> Extensions -> Extensions
67+disableExtension x (Extensions exts) = Extensions (clearBit exts (fromEnum x))
4868
4969-- | Individually selectable syntax extensions.
5070data Extension =
@@ -112,8 +132,8 @@ data Extension =
112132 | Ext_shortcut_reference_links -- ^ Shortcut reference links
113133 deriving (Show, Read, Enum, Eq, Ord, Bounded, Data, Typeable, Generic)
114134
115−pandocExtensions :: Set Extension
116−pandocExtensions = Set.fromList
135+pandocExtensions :: Extensions
136+pandocExtensions = extensionsFromList
117137 [ Ext_footnotes
118138 , Ext_inline_notes
119139 , Ext_pandoc_title_block
@@ -157,8 +177,8 @@ pandocExtensions = Set.fromList
157177 , Ext_shortcut_reference_links
158178 ]
159179
160−plainExtensions :: Set Extension
161−plainExtensions = Set.fromList
180+plainExtensions :: Extensions
181+plainExtensions = extensionsFromList
162182 [ Ext_table_captions
163183 , Ext_implicit_figures
164184 , Ext_simple_tables
@@ -175,8 +195,8 @@ plainExtensions = Set.fromList
175195 , Ext_strikeout
176196 ]
177197
178−phpMarkdownExtraExtensions :: Set Extension
179−phpMarkdownExtraExtensions = Set.fromList
198+phpMarkdownExtraExtensions :: Extensions
199+phpMarkdownExtraExtensions = extensionsFromList
180200 [ Ext_footnotes
181201 , Ext_pipe_tables
182202 , Ext_raw_html
@@ -190,8 +210,8 @@ phpMarkdownExtraExtensions = Set.fromList
190210 , Ext_shortcut_reference_links
191211 ]
192212
193−githubMarkdownExtensions :: Set Extension
194−githubMarkdownExtensions = Set.fromList
213+githubMarkdownExtensions :: Extensions
214+githubMarkdownExtensions = extensionsFromList
195215 [ Ext_angle_brackets_escapable
196216 , Ext_pipe_tables
197217 , Ext_raw_html
@@ -208,8 +228,8 @@ githubMarkdownExtensions = Set.fromList
208228 , Ext_shortcut_reference_links
209229 ]
210230
211−multimarkdownExtensions :: Set Extension
212−multimarkdownExtensions = Set.fromList
231+multimarkdownExtensions :: Extensions
232+multimarkdownExtensions = extensionsFromList
213233 [ Ext_pipe_tables
214234 , Ext_raw_html
215235 , Ext_markdown_attribute
@@ -237,8 +257,8 @@ multimarkdownExtensions = Set.fromList
237257 , Ext_subscript
238258 ]
239259
240−strictExtensions :: Set Extension
241−strictExtensions = Set.fromList
260+strictExtensions :: Extensions
261+strictExtensions = extensionsFromList
242262 [ Ext_raw_html
243263 , Ext_shortcut_reference_links
244264 ]
src/Text/Pandoc/Options.hs+3−5
@@ -45,17 +45,15 @@ module Text.Pandoc.Options ( module Text.Pandoc.Extensions
4545 , isEnabled
4646 ) where
4747import Text.Pandoc.Extensions
48−import qualified Data.Set as Set
4948import Data.Default
5049import Text.Pandoc.Highlighting (Style, pygments)
5150import Text.Pandoc.MediaBag (MediaBag)
5251import Data.Data (Data)
53−import Data.Set (Set)
5452import Data.Typeable (Typeable)
5553import GHC.Generics (Generic)
5654
5755data ReaderOptions = ReaderOptions{
58− readerExtensions :: Set Extension -- ^ Syntax extensions
56+ readerExtensions :: Extensions -- ^ Syntax extensions
5957 , readerSmart :: Bool -- ^ Smart punctuation
6058 , readerStandalone :: Bool -- ^ Standalone document with header
6159 , readerParseRaw :: Bool -- ^ Parse raw HTML, LaTeX
@@ -165,7 +163,7 @@ data WriterOptions = WriterOptions
165163 , writerNumberSections :: Bool -- ^ Number sections in LaTeX
166164 , writerNumberOffset :: [Int] -- ^ Starting number for section, subsection, ...
167165 , writerSectionDivs :: Bool -- ^ Put sections in div tags in HTML
168− , writerExtensions :: Set Extension -- ^ Markdown extensions that can be used
166+ , writerExtensions :: Extensions -- ^ Markdown extensions that can be used
169167 , writerReferenceLinks :: Bool -- ^ Use reference links in writing markdown, rst
170168 , writerDpi :: Int -- ^ Dpi for pixel to/from inch/cm conversions
171169 , writerWrapText :: WrapOption -- ^ Option for wrapping text
@@ -248,4 +246,4 @@ instance Default WriterOptions where
248246
249247-- | Returns True if the given extension is enabled.
250248isEnabled :: Extension -> WriterOptions -> Bool
251−isEnabled ext opts = ext `Set.member` (writerExtensions opts)
249+isEnabled ext opts = ext `extensionEnabled` (writerExtensions opts)
src/Text/Pandoc/Parsing.hs+4−4
@@ -1031,11 +1031,11 @@ defaultParserState =
10311031
10321032-- | Succeed only if the extension is enabled.
10331033guardEnabled :: (Stream s m a, HasReaderOptions st) => Extension -> ParserT s st m ()
1034−guardEnabled ext = getOption readerExtensions >>= guard . Set.member ext
1034+guardEnabled ext = getOption readerExtensions >>= guard . extensionEnabled ext
10351035
10361036-- | Succeed only if the extension is disabled.
10371037guardDisabled :: (Stream s m a, HasReaderOptions st) => Extension -> ParserT s st m ()
1038−guardDisabled ext = getOption readerExtensions >>= guard . not . Set.member ext
1038+guardDisabled ext = getOption readerExtensions >>= guard . not . extensionEnabled ext
10391039
10401040-- | Update the position on which the last string ended.
10411041updateLastStrPos :: (Stream s m a, HasLastStrPosition st) => ParserT s st m ()
@@ -1090,10 +1090,10 @@ registerHeader (ident,classes,kvs) header' = do
10901090 ids <- extractIdentifierList <$> getState
10911091 exts <- getOption readerExtensions
10921092 let insert' = M.insertWith (\_new old -> old)
1093− if null ident && Ext_auto_identifiers `Set.member` exts
1093+ if null ident && Ext_auto_identifiers `extensionEnabled` exts
10941094 then do
10951095 let id' = uniqueIdent (B.toList header') ids
1096− let id'' = if Ext_ascii_identifiers `Set.member` exts
1096+ let id'' = if Ext_ascii_identifiers `extensionEnabled` exts
10971097 then catMaybes $ map toAsciiChar id'
10981098 else id'
10991099 updateState $ updateIdentifierList $ Set.insert id'
src/Text/Pandoc/Readers/Markdown.hs+9−9
@@ -61,7 +61,6 @@ import Text.Pandoc.Readers.HTML ( htmlTag, htmlInBalanced, isInlineTag, isBlockT
6161import Control.Monad
6262import System.FilePath (takeExtension, addExtension)
6363import Text.HTML.TagSoup
64−import qualified Data.Set as Set
6564import Text.Printf (printf)
6665import Debug.Trace (trace)
6766import Data.Monoid ((<>))
@@ -310,11 +309,11 @@ toMetaValue opts x = toMeta <$> readMarkdown opts' (T.unpack x)
310309 | otherwise -> MetaInlines xs
311310 Pandoc _ bs -> MetaBlocks bs
312311 endsWithNewline t = T.pack "\n" `T.isSuffixOf` t
313− opts' = opts{readerExtensions=readerExtensions opts `Set.difference` meta_exts}
314− meta_exts = Set.fromList [ Ext_pandoc_title_block
315− , Ext_mmd_title_block
316− , Ext_yaml_metadata_block
317− ]
312+ opts' = opts{readerExtensions =
313+ disableExtension Ext_pandoc_title_block $
314+ disableExtension Ext_mmd_title_block $
315+ disableExtension Ext_yaml_metadata_block $
316+ readerExtensions opts }
318317
319318yamlToMeta :: PandocMonad m => ReaderOptions -> Yaml.Value -> m MetaValue
320319yamlToMeta opts (Yaml.String t) = toMetaValue opts t
@@ -534,8 +533,9 @@ header = setextHeader <|> atxHeader <?> "header"
534533atxChar :: PandocMonad m => MarkdownParser m Char
535534atxChar = do
536535 exts <- getOption readerExtensions
537− return $ if Set.member Ext_literate_haskell exts
538− then '=' else '#'
536+ return $ if extensionEnabled Ext_literate_haskell exts
537+ then '='
538+ else '#'
539539
540540atxHeader :: PandocMonad m => MarkdownParser m (F Blocks)
541541atxHeader = try $ do
@@ -1013,7 +1013,7 @@ para = try $ do
10131013 result' <- result
10141014 case B.toList result' of
10151015 [Image attr alt (src,tit)]
1016− | Ext_implicit_figures `Set.member` exts ->
1016+ | Ext_implicit_figures `extensionEnabled` exts ->
10171017 -- the fig: at beginning of title indicates a figure
10181018 return $ B.para $ B.singleton
10191019 $ Image attr alt (src,'f':'i':'g':':':tit)
tests/Tests/Readers/Markdown.hs+3−4
@@ -6,7 +6,6 @@ import Test.Framework
66import Tests.Helpers
77import Text.Pandoc.Arbitrary()
88import Text.Pandoc.Builder
9−import qualified Data.Set as Set
109import Text.Pandoc
1110
1211markdown :: String -> Pandoc
@@ -16,7 +15,7 @@ markdownSmart :: String -> Pandoc
1615markdownSmart = purely $ readMarkdown def { readerSmart = True }
1716
1817markdownCDL :: String -> Pandoc
19−markdownCDL = purely $ readMarkdown def { readerExtensions = Set.insert
18+markdownCDL = purely $ readMarkdown def { readerExtensions = enableExtension
2019 Ext_compact_definition_lists $ readerExtensions def }
2120
2221markdownGH :: String -> Pandoc
@@ -30,7 +29,7 @@ infix 4 =:
3029testBareLink :: (String, Inlines) -> Test
3130testBareLink (inp, ils) =
3231 test (purely $ readMarkdown def{ readerExtensions =
33− Set.fromList [Ext_autolink_bare_uris, Ext_raw_html] })
32+ extensionsFromList [Ext_autolink_bare_uris, Ext_raw_html] })
3433 inp (inp, doc $ para ils)
3534
3635autolink :: String -> Inlines
@@ -303,7 +302,7 @@ tests = [ testGroup "inline code"
303302 =?> para (note (para "See [^1]"))
304303 ]
305304 , testGroup "lhs"
306− [ test (purely $ readMarkdown def{ readerExtensions = Set.insert
305+ [ test (purely $ readMarkdown def{ readerExtensions = enableExtension
307306 Ext_literate_haskell $ readerExtensions def })
308307 "inverse bird tracks and html" $
309308 "> a\n\n< b\n\n<div>\n"