git.iko.soy/typeable/pandoc
on master help sign in
Put smart, strict in separate options field in state.

This is the beginning of a larger transition that will make Options, not ParserState, the parameter of the read functions. (Options will also be used in writers, in place of WriterOptions.) Next step is to remove strict, replacing it with granular tests for different extensions.

commitda3702357dc9a310b460c82411fe5b8c870416d5 authorJohn MacFarlane <fiddlosopher@gmail.com> dateWed 25 Jul 2012, 10:45 (14 years ago) parent0d21b8d
8 files changed+52−27
src/Tests/Readers/Markdown.hs+3−1 src/Text/Pandoc.hs+3 src/Text/Pandoc/Options.hs+16−2 src/Text/Pandoc/Parsing.hs+7−8 src/Text/Pandoc/Readers/HTML.hs+3−2 src/Text/Pandoc/Readers/Markdown.hs+11−10 src/Text/Pandoc/Readers/Textile.hs+5−1 src/pandoc.hs+4−3
src/Tests/Readers/Markdown.hs+3−1
@@ -13,7 +13,9 @@ markdown :: String -> Pandoc
1313markdown = readMarkdown defaultParserState{ stateStandalone = True }
1414
1515markdownSmart :: String -> Pandoc
16−markdownSmart = readMarkdown defaultParserState{ stateSmart = True }
16+markdownSmart = readMarkdown defaultParserState{ stateOptions =
17+ let oldOpts = stateOptions defaultParserState in
18+ oldOpts { optionSmart = True } }
1719
1820infix 4 =:
1921(=:) :: ToString c
src/Text/Pandoc.hs+3
@@ -60,6 +60,8 @@ module Text.Pandoc
6060 module Text.Pandoc.Definition
6161 -- * Generics
6262 , module Text.Pandoc.Generic
63+ -- * Options
64+ , module Text.Pandoc.Options
6365 -- * Lists of readers and writers
6466 , readers
6567 , writers
@@ -151,6 +153,7 @@ import Text.Pandoc.Writers.AsciiDoc
151153import Text.Pandoc.Templates
152154import Text.Pandoc.Parsing
153155import Text.Pandoc.Shared
156+import Text.Pandoc.Options
154157import Data.ByteString.Lazy (ByteString)
155158import Data.Version (showVersion)
156159import Text.JSON.Generic
src/Text/Pandoc/Options.hs+16−2
@@ -29,10 +29,13 @@ Data structures and functions for representing parser and writer
2929options.
3030-}
3131module Text.Pandoc.Options ( Extension(..)
32+ , Options(..)
3233 ) where
3334import Data.Set (Set)
35+import qualified Data.Set as Set
36+import Data.Default
3437
35−-- | Individually selectable markdown syntax extensions.
38+-- | Individually selectable syntax extensions.
3639data Extension = Footnotes
3740 | TeX_math
3841 | Delimited_code_blocks
@@ -45,6 +48,17 @@ data Extension = Footnotes
4548 | Blank_before_blockquote
4649 | Blank_before_header
4750 | Significant_bullets
48− deriving (Show, Read, Enum, Eq, Bounded)
51+ deriving (Show, Read, Enum, Eq, Ord, Bounded)
4952
53+data Options = Options{
54+ optionExtensions :: Set Extension
55+ , optionSmart :: Bool
56+ , optionStrict :: Bool -- FOR TRANSITION ONLY
57+ } deriving (Show, Read)
5058
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 ( (>>~),
129129where
130130
131131import Text.Pandoc.Definition
132+import Text.Pandoc.Options
132133import Text.Pandoc.Generic
133134import qualified Text.Pandoc.UTF8 as UTF8 (putStrLn)
134135import Text.Parsec
@@ -391,7 +392,7 @@ nullBlock = anyChar >> return Null
391392failIfStrict :: Parsec [a] ParserState ()
392393failIfStrict = do
393394 state <- getState
394− if stateStrict state then fail "strict mode" else return ()
395+ if optionStrict (stateOptions state) then fail "strict mode" else return ()
395396
396397-- | Fail unless we're in literate haskell mode.
397398failUnlessLHS :: Parsec [tok] ParserState ()
@@ -688,7 +689,8 @@ testStringWith parser str = UTF8.putStrLn $ show $
688689
689690-- | Parsing options.
690691data ParserState = ParserState
691− { stateParseRaw :: Bool, -- ^ Parse raw HTML and LaTeX?
692+ { stateOptions :: Options, -- ^ User options
693+ stateParseRaw :: Bool, -- ^ Parse raw HTML and LaTeX?
692694 stateParserContext :: ParserContext, -- ^ Inside list?
693695 stateQuoteContext :: QuoteContext, -- ^ Inside quoted environment?
694696 stateMaxNestingLevel :: Int, -- ^ Max # of nested Strong/Emph
@@ -701,8 +703,6 @@ data ParserState = ParserState
701703 stateTitle :: [Inline], -- ^ Title of document
702704 stateAuthors :: [[Inline]], -- ^ Authors of document
703705 stateDate :: [Inline], -- ^ Date of document
704− stateStrict :: Bool, -- ^ Use strict markdown syntax?
705− stateSmart :: Bool, -- ^ Use smart typography?
706706 stateOldDashes :: Bool, -- ^ Use pandoc <= 1.8.2.1 behavior
707707 -- in parsing dashes; -- is em-dash;
708708 -- before numeral is en-dash
@@ -724,7 +724,8 @@ instance Default ParserState where
724724
725725defaultParserState :: ParserState
726726defaultParserState =
727− ParserState { stateParseRaw = False,
727+ ParserState { stateOptions = def,
728+ stateParseRaw = False,
728729 stateParserContext = NullState,
729730 stateQuoteContext = NoQuote,
730731 stateMaxNestingLevel = 6,
@@ -737,8 +738,6 @@ defaultParserState =
737738 stateTitle = [],
738739 stateAuthors = [],
739740 stateDate = [],
740− stateStrict = False,
741− stateSmart = False,
742741 stateOldDashes = False,
743742 stateLiterateHaskell = False,
744743 stateColumns = 80,
@@ -796,7 +795,7 @@ lookupKeySrc table key = case M.lookup key table of
796795
797796-- | Fail unless we're in "smart typography" mode.
798797failUnlessSmart :: Parsec [tok] ParserState ()
799−failUnlessSmart = getState >>= guard . stateSmart
798+failUnlessSmart = getState >>= guard . optionSmart . stateOptions
800799
801800smartPunctuation :: Parsec [Char] ParserState Inline
802801 -> Parsec [Char] ParserState Inline
src/Text/Pandoc/Readers/HTML.hs+3−2
@@ -41,6 +41,7 @@ import Text.HTML.TagSoup.Match
4141import Text.Pandoc.Definition
4242import Text.Pandoc.Builder (text, toList)
4343import Text.Pandoc.Shared
44+import Text.Pandoc.Options
4445import Text.Pandoc.Parsing
4546import Data.Maybe ( fromMaybe, isJust )
4647import Data.List ( intercalate )
@@ -125,7 +126,7 @@ pOrderedList :: TagParser [Block]
125126pOrderedList = try $ do
126127 TagOpen _ attribs <- pSatisfy (~== TagOpen "ol" [])
127128 st <- getState
128− let (start, style) = if stateStrict st
129+ let (start, style) = if optionStrict (stateOptions st)
129130 then (1, DefaultStyle)
130131 else (sta', sty')
131132 where sta = fromMaybe "1" $
@@ -280,7 +281,7 @@ pCodeBlock = try $ do
280281 let attribsClasses = words $ fromMaybe "" $ lookup "class" attr
281282 let attribsKV = filter (\(k,_) -> k /= "class" && k /= "id") attr
282283 st <- getState
283− let attribs = if stateStrict st
284+ let attribs = if optionStrict (stateOptions st)
284285 then ("",[],[])
285286 else (attribsId, attribsClasses, attribsKV)
286287 return [CodeBlock attribs result]
src/Text/Pandoc/Readers/Markdown.hs+11−10
@@ -37,6 +37,7 @@ import Data.Char ( isAlphaNum )
3737import Data.Maybe
3838import Text.Pandoc.Definition
3939import Text.Pandoc.Generic
40+import Text.Pandoc.Options
4041import Text.Pandoc.Shared
4142import Text.Pandoc.Parsing
4243import Text.Pandoc.Readers.LaTeX ( rawLaTeXInline, rawLaTeXBlock )
@@ -181,7 +182,7 @@ parseMarkdown = do
181182 -- docMinusKeys is the raw document with blanks where the keys/notes were...
182183 st <- getState
183184 let firstPassParser = referenceKey
184− <|> (if stateStrict st then mzero else noteBlock)
185+ <|> (if optionStrict (stateOptions st) then mzero else noteBlock)
185186 <|> liftM snd (withRaw codeBlockDelimited)
186187 <|> lineClump
187188 docMinusKeys <- liftM concat $ manyTill firstPassParser eof
@@ -292,7 +293,7 @@ parseBlocks = manyTill block eof
292293block :: Parser [Char] ParserState Block
293294block = do
294295 st <- getState
295− choice (if stateStrict st
296+ choice (if optionStrict (stateOptions st)
296297 then [ header
297298 , codeBlockIndented
298299 , blockQuote
@@ -533,7 +534,7 @@ anyOrderedListStart = try $ do
533534 skipNonindentSpaces
534535 notFollowedBy $ string "p." >> spaceChar >> digit -- page number
535536 state <- getState
536− if stateStrict state
537+ if optionStrict (stateOptions state)
537538 then do many1 digit
538539 char '.'
539540 spaceChar
@@ -694,7 +695,7 @@ para = try $ do
694695 option (Plain result) $ try $ do
695696 newline
696697 blanklines <|>
697− (getState >>= guard . stateStrict >>
698+ (getState >>= guard . optionStrict . stateOptions >>
698699 lookAhead (blockQuote <|> header) >> return "")
699700 return $ Para result
700701
@@ -1008,7 +1009,7 @@ escapedChar' :: Parser [Char] ParserState Char
10081009escapedChar' = try $ do
10091010 char '\\'
10101011 state <- getState
1011− if stateStrict state
1012+ if optionStrict (stateOptions state)
10121013 then oneOf "\\`*_{}[]()>#+-.!~"
10131014 else satisfy (not . isAlphaNum)
10141015
@@ -1023,7 +1024,7 @@ escapedChar = do
10231024ltSign :: Parser [Char] ParserState Inline
10241025ltSign = do
10251026 st <- getState
1026− if stateStrict st
1027+ if optionStrict (stateOptions st)
10271028 then char '<'
10281029 else notFollowedBy' rawHtmlBlocks >> char '<' -- unless it starts html
10291030 return $ Str ['<']
@@ -1159,7 +1160,7 @@ nonEndline = satisfy (/='\n')
11591160
11601161str :: Parser [Char] ParserState Inline
11611162str = do
1162− smart <- stateSmart `fmap` getState
1163+ smart <- (optionSmart . stateOptions) `fmap` getState
11631164 a <- alphaNum
11641165 as <- many $ alphaNum
11651166 <|> (try $ char '_' >>~ lookAhead alphaNum)
@@ -1200,7 +1201,7 @@ endline = try $ do
12001201 newline
12011202 notFollowedBy blankline
12021203 st <- getState
1203− when (stateStrict st) $ do
1204+ when (optionStrict (stateOptions st)) $ do
12041205 notFollowedBy emailBlockQuoteStart
12051206 notFollowedBy (char '#') -- atx header
12061207 -- parse potential list-starts differently if in a list:
@@ -1282,7 +1283,7 @@ autoLink = try $ do
12821283 (orig, src) <- uri <|> emailAddress
12831284 char '>'
12841285 st <- getState
1285− return $ if stateStrict st
1286+ return $ if optionStrict (stateOptions st)
12861287 then Link [Str orig] (src, "")
12871288 else Link [Code ("",["url"],[]) orig] (src, "")
12881289
@@ -1343,7 +1344,7 @@ inBrackets parser = do
13431344rawHtmlInline :: Parser [Char] ParserState Inline
13441345rawHtmlInline = do
13451346 st <- getState
1346− (_,result) <- if stateStrict st
1347+ (_,result) <- if optionStrict (stateOptions st)
13471348 then htmlTag (not . isTextTag)
13481349 else htmlTag isInlineTag
13491350 return $ RawInline "html" result
src/Text/Pandoc/Readers/Textile.hs+5−1
@@ -57,6 +57,7 @@ module Text.Pandoc.Readers.Textile ( readTextile) where
5757
5858import Text.Pandoc.Definition
5959import Text.Pandoc.Shared
60+import Text.Pandoc.Options
6061import Text.Pandoc.Parsing
6162import Text.Pandoc.Readers.HTML ( htmlTag, isInlineTag, isBlockTag )
6263import Text.Pandoc.Readers.LaTeX ( rawLaTeXInline, rawLaTeXBlock )
@@ -77,7 +78,10 @@ readTextile state s =
7778parseTextile :: Parser [Char] ParserState Pandoc
7879parseTextile = do
7980 -- textile allows raw HTML and does smart punctuation by default
80− updateState (\state -> state { stateParseRaw = True, stateSmart = True })
81+ oldOpts <- stateOptions `fmap` getState
82+ updateState $ \state -> state { stateParseRaw = True
83+ , stateOptions = oldOpts{ optionSmart = True }
84+ }
8185 many blankline
8286 startPos <- getPosition
8387 -- go through once just to get list of reference keys and notes
src/pandoc.hs+4−3
@@ -942,11 +942,12 @@ main = do
942942 lhsExtension sources,
943943 stateStandalone = standalone',
944944 stateCitations = map CSL.refId refs,
945− stateSmart = smart || (texLigatures &&
946− (laTeXOutput || writerName' == "context")),
947945 stateOldDashes = oldDashes,
948946 stateColumns = columns,
949− stateStrict = strict,
947+ stateOptions = def{ optionStrict = strict
948+ , optionSmart = smart ||
949+ (texLigatures &&
950+ (laTeXOutput || writerName' == "context")) },
950951 stateIndentedCodeClasses = codeBlockClasses,
951952 stateApplyMacros = not laTeXOutput
952953 }