git.iko.soy/typeable/pandoc
on master help sign in
Put smart, strict in separate options field in state.
da37023John MacFarlane
src/Tests/Readers/Markdown.hs+3−1
@@ -13,7 +13,9 @@ markdown :: String -> Pandoc
13markdown = readMarkdown defaultParserState{ stateStandalone = True }
13markdown = readMarkdown defaultParserState{ stateStandalone = True }
14
14
15markdownSmart :: String -> Pandoc
15markdownSmart :: String -> Pandoc
16−markdownSmart = readMarkdown defaultParserState{ stateSmart = True }
16+markdownSmart = readMarkdown defaultParserState{ stateOptions =
17+ let oldOpts = stateOptions defaultParserState in
18+ oldOpts { optionSmart = True } }
17
19
18infix 4 =:
20infix 4 =:
19(=:) :: ToString c
21(=:) :: ToString c
src/Text/Pandoc.hs+3
@@ -60,6 +60,8 @@ module Text.Pandoc
60 module Text.Pandoc.Definition
60 module Text.Pandoc.Definition
61 -- * Generics
61 -- * Generics
62 , module Text.Pandoc.Generic
62 , module Text.Pandoc.Generic
63+ -- * Options
64+ , module Text.Pandoc.Options
63 -- * Lists of readers and writers
65 -- * Lists of readers and writers
64 , readers
66 , readers
65 , writers
67 , writers
@@ -151,6 +153,7 @@ import Text.Pandoc.Writers.AsciiDoc
151import Text.Pandoc.Templates
153import Text.Pandoc.Templates
152import Text.Pandoc.Parsing
154import Text.Pandoc.Parsing
153import Text.Pandoc.Shared
155import Text.Pandoc.Shared
156+import Text.Pandoc.Options
154import Data.ByteString.Lazy (ByteString)
157import Data.ByteString.Lazy (ByteString)
155import Data.Version (showVersion)
158import Data.Version (showVersion)
156import Text.JSON.Generic
159import Text.JSON.Generic
src/Text/Pandoc/Options.hs+16−2
@@ -29,10 +29,13 @@ Data structures and functions for representing parser and writer
29options.
29options.
30-}
30-}
31module Text.Pandoc.Options ( Extension(..)
31module Text.Pandoc.Options ( Extension(..)
32+ , Options(..)
32 ) where
33 ) where
33import Data.Set (Set)
34import Data.Set (Set)
35+import qualified Data.Set as Set
36+import Data.Default
34
37
35−-- | Individually selectable markdown syntax extensions.
38+-- | Individually selectable syntax extensions.
36data Extension = Footnotes
39data Extension = Footnotes
37 | TeX_math
40 | TeX_math
38 | Delimited_code_blocks
41 | Delimited_code_blocks
@@ -45,6 +48,17 @@ data Extension = Footnotes
45 | Blank_before_blockquote
48 | Blank_before_blockquote
46 | Blank_before_header
49 | Blank_before_header
47 | Significant_bullets
50 | Significant_bullets
48− deriving (Show, Read, Enum, Eq, Bounded)
51+ deriving (Show, Read, Enum, Eq, Ord, Bounded)
49
52
53+data Options = Options{
54+ optionExtensions :: Set Extension
55+ , optionSmart :: Bool
56+ , optionStrict :: Bool -- FOR TRANSITION ONLY
57+ } deriving (Show, Read)
50
58
59+instance Default Options
60+ where def = Options{
61+ optionExtensions = Set.fromList [minBound..maxBound]
62+ , optionSmart = False
63+ , optionStrict = False
64+ }
src/Text/Pandoc/Parsing.hs+7−8
@@ -129,6 +129,7 @@ module Text.Pandoc.Parsing ( (>>~),
129where
129where
130
130
131import Text.Pandoc.Definition
131import Text.Pandoc.Definition
132+import Text.Pandoc.Options
132import Text.Pandoc.Generic
133import Text.Pandoc.Generic
133import qualified Text.Pandoc.UTF8 as UTF8 (putStrLn)
134import qualified Text.Pandoc.UTF8 as UTF8 (putStrLn)
134import Text.Parsec
135import Text.Parsec
@@ -391,7 +392,7 @@ nullBlock = anyChar >> return Null
391failIfStrict :: Parsec [a] ParserState ()
392failIfStrict :: Parsec [a] ParserState ()
392failIfStrict = do
393failIfStrict = do
393 state <- getState
394 state <- getState
394− if stateStrict state then fail "strict mode" else return ()
395+ if optionStrict (stateOptions state) then fail "strict mode" else return ()
395
396
396-- | Fail unless we're in literate haskell mode.
397-- | Fail unless we're in literate haskell mode.
397failUnlessLHS :: Parsec [tok] ParserState ()
398failUnlessLHS :: Parsec [tok] ParserState ()
@@ -688,7 +689,8 @@ testStringWith parser str = UTF8.putStrLn $ show $
688
689
689-- | Parsing options.
690-- | Parsing options.
690data ParserState = ParserState
691data ParserState = ParserState
692+ { stateOptions :: Options, -- ^ User options
691− { stateParseRaw :: Bool, -- ^ Parse raw HTML and LaTeX?
693+ stateParseRaw :: Bool, -- ^ Parse raw HTML and LaTeX?
692 stateParserContext :: ParserContext, -- ^ Inside list?
694 stateParserContext :: ParserContext, -- ^ Inside list?
693 stateQuoteContext :: QuoteContext, -- ^ Inside quoted environment?
695 stateQuoteContext :: QuoteContext, -- ^ Inside quoted environment?
694 stateMaxNestingLevel :: Int, -- ^ Max # of nested Strong/Emph
696 stateMaxNestingLevel :: Int, -- ^ Max # of nested Strong/Emph
@@ -701,8 +703,6 @@ data ParserState = ParserState
701 stateTitle :: [Inline], -- ^ Title of document
703 stateTitle :: [Inline], -- ^ Title of document
702 stateAuthors :: [[Inline]], -- ^ Authors of document
704 stateAuthors :: [[Inline]], -- ^ Authors of document
703 stateDate :: [Inline], -- ^ Date of document
705 stateDate :: [Inline], -- ^ Date of document
704− stateStrict :: Bool, -- ^ Use strict markdown syntax?
705− stateSmart :: Bool, -- ^ Use smart typography?
706 stateOldDashes :: Bool, -- ^ Use pandoc <= 1.8.2.1 behavior
706 stateOldDashes :: Bool, -- ^ Use pandoc <= 1.8.2.1 behavior
707 -- in parsing dashes; -- is em-dash;
707 -- in parsing dashes; -- is em-dash;
708 -- before numeral is en-dash
708 -- before numeral is en-dash
@@ -724,7 +724,8 @@ instance Default ParserState where
724
724
725defaultParserState :: ParserState
725defaultParserState :: ParserState
726defaultParserState =
726defaultParserState =
727+ ParserState { stateOptions = def,
727− ParserState { stateParseRaw = False,
728+ stateParseRaw = False,
728 stateParserContext = NullState,
729 stateParserContext = NullState,
729 stateQuoteContext = NoQuote,
730 stateQuoteContext = NoQuote,
730 stateMaxNestingLevel = 6,
731 stateMaxNestingLevel = 6,
@@ -737,8 +738,6 @@ defaultParserState =
737 stateTitle = [],
738 stateTitle = [],
738 stateAuthors = [],
739 stateAuthors = [],
739 stateDate = [],
740 stateDate = [],
740− stateStrict = False,
741− stateSmart = False,
742 stateOldDashes = False,
741 stateOldDashes = False,
743 stateLiterateHaskell = False,
742 stateLiterateHaskell = False,
744 stateColumns = 80,
743 stateColumns = 80,
@@ -796,7 +795,7 @@ lookupKeySrc table key = case M.lookup key table of
796
795
797-- | Fail unless we're in "smart typography" mode.
796-- | Fail unless we're in "smart typography" mode.
798failUnlessSmart :: Parsec [tok] ParserState ()
797failUnlessSmart :: Parsec [tok] ParserState ()
799−failUnlessSmart = getState >>= guard . stateSmart
798+failUnlessSmart = getState >>= guard . optionSmart . stateOptions
800
799
801smartPunctuation :: Parsec [Char] ParserState Inline
800smartPunctuation :: Parsec [Char] ParserState Inline
802 -> Parsec [Char] ParserState Inline
801 -> Parsec [Char] ParserState Inline
src/Text/Pandoc/Readers/HTML.hs+3−2
@@ -41,6 +41,7 @@ import Text.HTML.TagSoup.Match
41import Text.Pandoc.Definition
41import Text.Pandoc.Definition
42import Text.Pandoc.Builder (text, toList)
42import Text.Pandoc.Builder (text, toList)
43import Text.Pandoc.Shared
43import Text.Pandoc.Shared
44+import Text.Pandoc.Options
44import Text.Pandoc.Parsing
45import Text.Pandoc.Parsing
45import Data.Maybe ( fromMaybe, isJust )
46import Data.Maybe ( fromMaybe, isJust )
46import Data.List ( intercalate )
47import Data.List ( intercalate )
@@ -125,7 +126,7 @@ pOrderedList :: TagParser [Block]
125pOrderedList = try $ do
126pOrderedList = try $ do
126 TagOpen _ attribs <- pSatisfy (~== TagOpen "ol" [])
127 TagOpen _ attribs <- pSatisfy (~== TagOpen "ol" [])
127 st <- getState
128 st <- getState
128− let (start, style) = if stateStrict st
129+ let (start, style) = if optionStrict (stateOptions st)
129 then (1, DefaultStyle)
130 then (1, DefaultStyle)
130 else (sta', sty')
131 else (sta', sty')
131 where sta = fromMaybe "1" $
132 where sta = fromMaybe "1" $
@@ -280,7 +281,7 @@ pCodeBlock = try $ do
280 let attribsClasses = words $ fromMaybe "" $ lookup "class" attr
281 let attribsClasses = words $ fromMaybe "" $ lookup "class" attr
281 let attribsKV = filter (\(k,_) -> k /= "class" && k /= "id") attr
282 let attribsKV = filter (\(k,_) -> k /= "class" && k /= "id") attr
282 st <- getState
283 st <- getState
283− let attribs = if stateStrict st
284+ let attribs = if optionStrict (stateOptions st)
284 then ("",[],[])
285 then ("",[],[])
285 else (attribsId, attribsClasses, attribsKV)
286 else (attribsId, attribsClasses, attribsKV)
286 return [CodeBlock attribs result]
287 return [CodeBlock attribs result]
src/Text/Pandoc/Readers/Markdown.hs+11−10
@@ -37,6 +37,7 @@ import Data.Char ( isAlphaNum )
37import Data.Maybe
37import Data.Maybe
38import Text.Pandoc.Definition
38import Text.Pandoc.Definition
39import Text.Pandoc.Generic
39import Text.Pandoc.Generic
40+import Text.Pandoc.Options
40import Text.Pandoc.Shared
41import Text.Pandoc.Shared
41import Text.Pandoc.Parsing
42import Text.Pandoc.Parsing
42import Text.Pandoc.Readers.LaTeX ( rawLaTeXInline, rawLaTeXBlock )
43import Text.Pandoc.Readers.LaTeX ( rawLaTeXInline, rawLaTeXBlock )
@@ -181,7 +182,7 @@ parseMarkdown = do
181 -- docMinusKeys is the raw document with blanks where the keys/notes were...
182 -- docMinusKeys is the raw document with blanks where the keys/notes were...
182 st <- getState
183 st <- getState
183 let firstPassParser = referenceKey
184 let firstPassParser = referenceKey
184− <|> (if stateStrict st then mzero else noteBlock)
185+ <|> (if optionStrict (stateOptions st) then mzero else noteBlock)
185 <|> liftM snd (withRaw codeBlockDelimited)
186 <|> liftM snd (withRaw codeBlockDelimited)
186 <|> lineClump
187 <|> lineClump
187 docMinusKeys <- liftM concat $ manyTill firstPassParser eof
188 docMinusKeys <- liftM concat $ manyTill firstPassParser eof
@@ -292,7 +293,7 @@ parseBlocks = manyTill block eof
292block :: Parser [Char] ParserState Block
293block :: Parser [Char] ParserState Block
293block = do
294block = do
294 st <- getState
295 st <- getState
295− choice (if stateStrict st
296+ choice (if optionStrict (stateOptions st)
296 then [ header
297 then [ header
297 , codeBlockIndented
298 , codeBlockIndented
298 , blockQuote
299 , blockQuote
@@ -533,7 +534,7 @@ anyOrderedListStart = try $ do
533 skipNonindentSpaces
534 skipNonindentSpaces
534 notFollowedBy $ string "p." >> spaceChar >> digit -- page number
535 notFollowedBy $ string "p." >> spaceChar >> digit -- page number
535 state <- getState
536 state <- getState
536− if stateStrict state
537+ if optionStrict (stateOptions state)
537 then do many1 digit
538 then do many1 digit
538 char '.'
539 char '.'
539 spaceChar
540 spaceChar
@@ -694,7 +695,7 @@ para = try $ do
694 option (Plain result) $ try $ do
695 option (Plain result) $ try $ do
695 newline
696 newline
696 blanklines <|>
697 blanklines <|>
697− (getState >>= guard . stateStrict >>
698+ (getState >>= guard . optionStrict . stateOptions >>
698 lookAhead (blockQuote <|> header) >> return "")
699 lookAhead (blockQuote <|> header) >> return "")
699 return $ Para result
700 return $ Para result
700
701
@@ -1008,7 +1009,7 @@ escapedChar' :: Parser [Char] ParserState Char
1008escapedChar' = try $ do
1009escapedChar' = try $ do
1009 char '\\'
1010 char '\\'
1010 state <- getState
1011 state <- getState
1011− if stateStrict state
1012+ if optionStrict (stateOptions state)
1012 then oneOf "\\`*_{}[]()>#+-.!~"
1013 then oneOf "\\`*_{}[]()>#+-.!~"
1013 else satisfy (not . isAlphaNum)
1014 else satisfy (not . isAlphaNum)
1014
1015
@@ -1023,7 +1024,7 @@ escapedChar = do
1023ltSign :: Parser [Char] ParserState Inline
1024ltSign :: Parser [Char] ParserState Inline
1024ltSign = do
1025ltSign = do
1025 st <- getState
1026 st <- getState
1026− if stateStrict st
1027+ if optionStrict (stateOptions st)
1027 then char '<'
1028 then char '<'
1028 else notFollowedBy' rawHtmlBlocks >> char '<' -- unless it starts html
1029 else notFollowedBy' rawHtmlBlocks >> char '<' -- unless it starts html
1029 return $ Str ['<']
1030 return $ Str ['<']
@@ -1159,7 +1160,7 @@ nonEndline = satisfy (/='\n')
1159
1160
1160str :: Parser [Char] ParserState Inline
1161str :: Parser [Char] ParserState Inline
1161str = do
1162str = do
1162− smart <- stateSmart `fmap` getState
1163+ smart <- (optionSmart . stateOptions) `fmap` getState
1163 a <- alphaNum
1164 a <- alphaNum
1164 as <- many $ alphaNum
1165 as <- many $ alphaNum
1165 <|> (try $ char '_' >>~ lookAhead alphaNum)
1166 <|> (try $ char '_' >>~ lookAhead alphaNum)
@@ -1200,7 +1201,7 @@ endline = try $ do
1200 newline
1201 newline
1201 notFollowedBy blankline
1202 notFollowedBy blankline
1202 st <- getState
1203 st <- getState
1203− when (stateStrict st) $ do
1204+ when (optionStrict (stateOptions st)) $ do
1204 notFollowedBy emailBlockQuoteStart
1205 notFollowedBy emailBlockQuoteStart
1205 notFollowedBy (char '#') -- atx header
1206 notFollowedBy (char '#') -- atx header
1206 -- parse potential list-starts differently if in a list:
1207 -- parse potential list-starts differently if in a list:
@@ -1282,7 +1283,7 @@ autoLink = try $ do
1282 (orig, src) <- uri <|> emailAddress
1283 (orig, src) <- uri <|> emailAddress
1283 char '>'
1284 char '>'
1284 st <- getState
1285 st <- getState
1285− return $ if stateStrict st
1286+ return $ if optionStrict (stateOptions st)
1286 then Link [Str orig] (src, "")
1287 then Link [Str orig] (src, "")
1287 else Link [Code ("",["url"],[]) orig] (src, "")
1288 else Link [Code ("",["url"],[]) orig] (src, "")
1288
1289
@@ -1343,7 +1344,7 @@ inBrackets parser = do
1343rawHtmlInline :: Parser [Char] ParserState Inline
1344rawHtmlInline :: Parser [Char] ParserState Inline
1344rawHtmlInline = do
1345rawHtmlInline = do
1345 st <- getState
1346 st <- getState
1346− (_,result) <- if stateStrict st
1347+ (_,result) <- if optionStrict (stateOptions st)
1347 then htmlTag (not . isTextTag)
1348 then htmlTag (not . isTextTag)
1348 else htmlTag isInlineTag
1349 else htmlTag isInlineTag
1349 return $ RawInline "html" result
1350 return $ RawInline "html" result
src/Text/Pandoc/Readers/Textile.hs+5−1
@@ -57,6 +57,7 @@ module Text.Pandoc.Readers.Textile ( readTextile) where
57
57
58import Text.Pandoc.Definition
58import Text.Pandoc.Definition
59import Text.Pandoc.Shared
59import Text.Pandoc.Shared
60+import Text.Pandoc.Options
60import Text.Pandoc.Parsing
61import Text.Pandoc.Parsing
61import Text.Pandoc.Readers.HTML ( htmlTag, isInlineTag, isBlockTag )
62import Text.Pandoc.Readers.HTML ( htmlTag, isInlineTag, isBlockTag )
62import Text.Pandoc.Readers.LaTeX ( rawLaTeXInline, rawLaTeXBlock )
63import Text.Pandoc.Readers.LaTeX ( rawLaTeXInline, rawLaTeXBlock )
@@ -77,7 +78,10 @@ readTextile state s =
77parseTextile :: Parser [Char] ParserState Pandoc
78parseTextile :: Parser [Char] ParserState Pandoc
78parseTextile = do
79parseTextile = do
79 -- textile allows raw HTML and does smart punctuation by default
80 -- textile allows raw HTML and does smart punctuation by default
81+ oldOpts <- stateOptions `fmap` getState
80− updateState (\state -> state { stateParseRaw = True, stateSmart = True })
82+ updateState $ \state -> state { stateParseRaw = True
83+ , stateOptions = oldOpts{ optionSmart = True }
84+ }
81 many blankline
85 many blankline
82 startPos <- getPosition
86 startPos <- getPosition
83 -- go through once just to get list of reference keys and notes
87 -- go through once just to get list of reference keys and notes
src/pandoc.hs+4−3
@@ -942,11 +942,12 @@ main = do
942 lhsExtension sources,
942 lhsExtension sources,
943 stateStandalone = standalone',
943 stateStandalone = standalone',
944 stateCitations = map CSL.refId refs,
944 stateCitations = map CSL.refId refs,
945− stateSmart = smart || (texLigatures &&
946− (laTeXOutput || writerName' == "context")),
947 stateOldDashes = oldDashes,
945 stateOldDashes = oldDashes,
948 stateColumns = columns,
946 stateColumns = columns,
949− stateStrict = strict,
947+ stateOptions = def{ optionStrict = strict
948+ , optionSmart = smart ||
949+ (texLigatures &&
950+ (laTeXOutput || writerName' == "context")) },
950 stateIndentedCodeClasses = codeBlockClasses,
951 stateIndentedCodeClasses = codeBlockClasses,
951 stateApplyMacros = not laTeXOutput
952 stateApplyMacros = not laTeXOutput
952 }
953 }