@@ -45,7 +45,7 @@ import Text.Pandoc.Readers.HTML ( rawHtmlBlock, anyHtmlBlockTag,
4545 htmlBlockElement, htmlComment, unsanitaryURI )
4646import Text.Pandoc.CharacterReferences ( decodeCharacterReferences )
4747import Text.ParserCombinators.Parsec
48−import Control.Monad (when, liftM)
48+import Control.Monad (when, liftM, unless)
4949
5050-- | Read markdown from an input string and return a Pandoc document.
5151readMarkdown :: ParserState -- ^ Parser state, including options for parser
@@ -109,7 +109,7 @@ failUnlessBeginningOfLine = do
109109failUnlessSmart :: GenParser tok ParserState ()
110110failUnlessSmart = do
111111 state <- getState
112− if stateSmart state then return () else fail "Smart typography feature"
112+ if stateSmart state then return () else pzero
113113
114114-- | Parse a sequence of inline elements between square brackets,
115115-- including inlines between balanced pairs of square brackets.
@@ -118,9 +118,7 @@ inlinesInBalancedBrackets :: GenParser Char ParserState Inline
118118inlinesInBalancedBrackets parser = try $ do
119119 char '['
120120 result <- manyTill ( (do lookAhead $ try $ do (Str res) <- parser
121− if res == "["
122− then return ()
123− else pzero
121+ unless (res == "[") pzero
124122 bal <- inlinesInBalancedBrackets parser
125123 return $ [Str "["] ++ bal ++ [Str "]"])
126124 <|> (count 1 parser))
@@ -678,26 +676,36 @@ dashedLine ch = do
678676 return $ (length dashes, length $ dashes ++ sp)
679677
680678-- Parse a table header with dashed lines of '-' preceded by
681−-- one line of text.
682−simpleTableHeader :: GenParser Char ParserState ([[Char]], [Alignment], [Int])
683−simpleTableHeader = try $ do
684− rawContent <- anyLine
679+-- one (or zero) line of text.
680+simpleTableHeader :: Bool -- ^ Headerless table
681+ -> GenParser Char ParserState ([[Char]], [Alignment], [Int])
682+simpleTableHeader headless = try $ do
683+ rawContent <- if headless
684+ then return ""
685+ else anyLine
685686 initSp <- nonindentSpaces
686687 dashes <- many1 (dashedLine '-')
687688 newline
688689 let (lengths, lines') = unzip dashes
689690 let indices = scanl (+) (length initSp) lines'
690− let rawHeads = tail $ splitByIndices (init indices) rawContent
691+ -- If no header, calculate alignment on basis of first row of text
692+ rawHeads <- liftM (tail . splitByIndices (init indices)) $
693+ if headless
694+ then lookAhead anyLine
695+ else return rawContent
691696 let aligns = zipWith alignType (map (\a -> [a]) rawHeads) lengths
692− return (rawHeads, aligns, indices)
697+ let rawHeads' = if headless
698+ then replicate (length dashes) ""
699+ else rawHeads
700+ return (rawHeads', aligns, indices)
693701
694702-- Parse a table footer - dashed lines followed by blank line.
695703tableFooter :: GenParser Char ParserState [Char]
696704tableFooter = try $ skipNonindentSpaces >> many1 (dashedLine '-') >> blanklines
697705
698706-- Parse a table separator - dashed line.
699−tableSep :: GenParser Char ParserState String
700−tableSep = try $ skipNonindentSpaces >> many1 (dashedLine '-') >> string "\n"
707+tableSep :: GenParser Char ParserState Char
708+tableSep = try $ skipNonindentSpaces >> many1 (dashedLine '-') >> char '\n'
701709
702710-- Parse a raw line and split it into chunks by indices.
703711rawTableLine :: [Int]
@@ -772,9 +780,11 @@ tableWith headerParser lineParser footerParser = try $ do
772780 return $ Table caption aligns widths heads lines'
773781
774782-- Parse a simple table with '---' header and one line per row.
775−simpleTable :: GenParser Char ParserState Block
776−simpleTable = do
777− Table c a _w h l <- tableWith simpleTableHeader tableLine blanklines
783+simpleTable :: Bool -- ^ Headerless table
784+ -> GenParser Char ParserState Block
785+simpleTable headless = do
786+ Table c a _w h l <- tableWith (simpleTableHeader headless) tableLine
787+ (if headless then tableFooter else tableFooter <|> blanklines)
778788 -- Simple tables get 0s for relative column widths (i.e., use default)
779789 return $ Table c a (replicate (length a) 0) h l
780790
@@ -782,23 +792,36 @@ simpleTable = do
782792-- (which may be multiline), then the rows,
783793-- which may be multiline, separated by blank lines, and
784794-- ending with a footer (dashed line followed by blank line).
785−multilineTable :: GenParser Char ParserState Block
786−multilineTable = tableWith multilineTableHeader multilineRow tableFooter
787−
788−multilineTableHeader :: GenParser Char ParserState ([String], [Alignment], [Int])
789−multilineTableHeader = try $ do
790− tableSep
791− rawContent <- many1 (notFollowedBy' tableSep >> many1Till anyChar newline)
795+multilineTable :: Bool -- ^ Headerless table
796+ -> GenParser Char ParserState Block
797+multilineTable headless =
798+ tableWith (multilineTableHeader headless) multilineRow tableFooter
799+
800+multilineTableHeader :: Bool -- ^ Headerless table
801+ -> GenParser Char ParserState ([String], [Alignment], [Int])
802+multilineTableHeader headless = try $ do
803+ if headless
804+ then return '\n'
805+ else tableSep
806+ rawContent <- if headless
807+ then return $ repeat ""
808+ else many1
809+ (notFollowedBy tableSep >> many1Till anyChar newline)
792810 initSp <- nonindentSpaces
793811 dashes <- many1 (dashedLine '-')
794812 newline
795813 let (lengths, lines') = unzip dashes
796814 let indices = scanl (+) (length initSp) lines'
797− let rawHeadsList = transpose $ map
798− (\ln -> tail $ splitByIndices (init indices) ln)
799− rawContent
800− let rawHeads = map (intercalate " ") rawHeadsList
815+ rawHeadsList <- if headless
816+ then liftM (map (:[]) . tail .
817+ splitByIndices (init indices)) $ lookAhead anyLine
818+ else return $ transpose $ map
819+ (\ln -> tail $ splitByIndices (init indices) ln)
820+ rawContent
801821 let aligns = zipWith alignType rawHeadsList lengths
822+ let rawHeads = if headless
823+ then replicate (length dashes) ""
824+ else map (intercalate " ") rawHeadsList
802825 return ((map removeLeadingTrailingSpace rawHeads), aligns, indices)
803826
804827-- Returns an alignment type for a table, based on a list of strings
@@ -820,7 +843,8 @@ alignType strLst len =
820843 (False, False) -> AlignDefault
821844
822845table :: GenParser Char ParserState Block
823−table = simpleTable <|> multilineTable <?> "table"
846+table = multilineTable False <|> simpleTable True <|>
847+ simpleTable False <|> multilineTable True <?> "table"
824848
825849--
826850-- inline