git.iko.soy/typeable/pandoc
on master help sign in
Added support for markdown-extra tables in the markdown parser
a922bd6François Gannaz
src/Tests/Old.hs+2
@@ -56,6 +56,8 @@ tests = [ testGroup "markdown"
56 "testsuite.txt" "testsuite.native"
56 "testsuite.txt" "testsuite.native"
57 , test "tables" ["-r", "markdown", "-w", "native", "--columns=80"]
57 , test "tables" ["-r", "markdown", "-w", "native", "--columns=80"]
58 "tables.txt" "tables.native"
58 "tables.txt" "tables.native"
59+ , test "extratables" ["-r", "markdown", "-w", "native", "--columns=80"]
60+ "markdown-tables.txt" "markdown-tables.native"
59 , test "more" ["-r", "markdown", "-w", "native", "-S"]
61 , test "more" ["-r", "markdown", "-w", "native", "-S"]
60 "markdown-reader-more.txt" "markdown-reader-more.native"
62 "markdown-reader-more.txt" "markdown-reader-more.native"
61 , lhsReaderTest "markdown+lhs"
63 , lhsReaderTest "markdown+lhs"
src/Text/Pandoc/Parsing.hs+97−1
@@ -56,6 +56,7 @@ module Text.Pandoc.Parsing ( (>>~),
56 orderedListMarker,
56 orderedListMarker,
57 charRef,
57 charRef,
58 tableWith,
58 tableWith,
59+ extraTableWith,
59 gridTableWith,
60 gridTableWith,
60 readWith,
61 readWith,
61 testStringWith,
62 testStringWith,
@@ -487,7 +488,9 @@ tableWith headerParser rowParser lineParser footerParser captionParser = try $ d
487 else return caption'
488 else return caption'
488 state <- getState
489 state <- getState
489 let numColumns = stateColumns state
490 let numColumns = stateColumns state
491+ let widths = if (indices == [])
492+ then replicate (length aligns) 0.0
490− let widths = widthsFromIndices numColumns indices
493+ else widthsFromIndices numColumns indices
491 return $ Table caption aligns widths heads lines'
494 return $ Table caption aligns widths heads lines'
492
495
493-- Calculate relative widths of table columns, based on indices
496-- Calculate relative widths of table columns, based on indices
@@ -515,6 +518,99 @@ widthsFromIndices numColumns' indices =
515 fracs = map (\l -> (fromIntegral l) / quotient) lengths in
518 fracs = map (\l -> (fromIntegral l) / quotient) lengths in
516 tail fracs
519 tail fracs
517
520
521+
522+-- Parse an extra table (php-markdown): each line starts and ends with '|',
523+-- with a mandatory line of '--' to separate the (optionnal) headers from content.
524+extraTableWith :: GenParser Char ParserState Block -- ^ Block parser
525+ -> GenParser Char ParserState [Inline] -- ^ Caption parser
526+ -> Bool -- ^ Headerless table
527+ -> GenParser Char ParserState Block
528+extraTableWith block tableCaption headless =
529+ tableWith (extraTableHeader headless block) (extraTableRow block) (extraTableSep '-') extraTableFooter tableCaption
530+
531+-- | Parse header for an extra table.
532+extraTableHeader :: Bool -- ^ Headerless table
533+ -> GenParser Char ParserState Block
534+ -> GenParser Char ParserState ([[Block]], [Alignment], [Int])
535+extraTableHeader headless block = try $ do
536+ optional blanklines
537+ rawContent <- if headless
538+ then return $ repeat ""
539+ else many1
540+ (notFollowedBy (extraTableHeaderSep) >> char '|' >>
541+ many1Till anyChar newline)
542+ aligns <- extraTableHeaderDashedLine
543+ let indices = []
544+ let rawHeads = if headless
545+ then replicate (length aligns) ""
546+ else map (intercalate " ") $ transpose
547+ $ map (extraTableSplitLine )
548+ $ map (trimOnceBy '|') rawContent
549+ heads <- mapM (parseFromString $ many block) $
550+ map removeLeadingTrailingSpace rawHeads
551+ return (heads, aligns, indices)
552+
553+extraTableHeaderPart :: GenParser Char st Alignment
554+extraTableHeaderPart = do
555+ left <- optionMaybe (char ':')
556+ many1 (char '-')
557+ right <- optionMaybe (char ':')
558+ char '|'
559+ return $
560+ case (left,right) of
561+ (Nothing,Nothing) -> AlignDefault
562+ (Just _,Nothing) -> AlignLeft
563+ (Nothing,Just _) -> AlignRight
564+ (Just _,Just _) -> AlignCenter
565+
566+extraTableHeaderDashedLine :: GenParser Char st [Alignment]
567+extraTableHeaderDashedLine = try $ char '|' >> many1 (extraTableHeaderPart) >>~ blankline
568+
569+extraTableHeaderSep :: GenParser Char ParserState Char
570+extraTableHeaderSep = try $ extraTableHeaderDashedLine >> return '\n'
571+
572+-- | Split a header or data line in an extra table.
573+-- | The line must contain only *inside* separators.
574+extraTableSplitLine :: String -> [String]
575+extraTableSplitLine line = map removeLeadingSpace $
576+ splitBy (== '|') $ removeTrailingSpace line
577+
578+-- Remove, if present, a character from both ends of a string
579+trimOnceBy :: Char -> String -> String
580+trimOnceBy ch s =
581+ if (head s == ch) && (last s == ch)
582+ then init $ tail s
583+ else s
584+trimEndOnceBy :: Char -> String -> String
585+trimEndOnceBy ch s =
586+ if (last s == ch)
587+ then init s
588+ else s
589+
590+-- | Parse row of an extra table.
591+extraTableRow :: GenParser Char ParserState Block
592+ -> [Int]
593+ -> GenParser Char ParserState [[Block]]
594+extraTableRow block indices = do
595+ cols <- extraTableRawLine
596+ mapM (liftM compactifyCell . parseFromString (many block)) cols
597+
598+extraTableRawLine :: GenParser Char ParserState [String]
599+extraTableRawLine = do
600+ char '|'
601+ line <- many1Till anyChar newline
602+ return (extraTableSplitLine $ trimEndOnceBy '|' line)
603+
604+-- | Separator between rows of an extra table.
605+extraTableSep :: Char -> GenParser Char ParserState Char
606+extraTableSep ch = do return '\n'
607+
608+-- | Parse footer for an extra table.
609+extraTableFooter :: GenParser Char ParserState [Char]
610+extraTableFooter = blanklines
611+
612+---
613+
518-- Parse a grid table: starts with row of '-' on top, then header
614-- Parse a grid table: starts with row of '-' on top, then header
519-- (which may be grid), then the rows,
615-- (which may be grid), then the rows,
520-- which may be grid, separated by blank lines, and
616-- which may be grid, separated by blank lines, and
src/Text/Pandoc/Readers/Markdown.hs+5
@@ -899,6 +899,10 @@ alignType strLst len =
899 (True, True) -> AlignCenter
899 (True, True) -> AlignCenter
900 (False, False) -> AlignDefault
900 (False, False) -> AlignDefault
901
901
902+extraTable :: Bool -- ^ Headerless table
903+ -> GenParser Char ParserState Block
904+extraTable = extraTableWith block tableCaption
905+
902gridTable :: Bool -- ^ Headerless table
906gridTable :: Bool -- ^ Headerless table
903 -> GenParser Char ParserState Block
907 -> GenParser Char ParserState Block
904gridTable = gridTableWith block tableCaption
908gridTable = gridTableWith block tableCaption
@@ -906,6 +910,7 @@ gridTable = gridTableWith block tableCaption
906table :: GenParser Char ParserState Block
910table :: GenParser Char ParserState Block
907table = multilineTable False <|> simpleTable True <|>
911table = multilineTable False <|> simpleTable True <|>
908 simpleTable False <|> multilineTable True <|>
912 simpleTable False <|> multilineTable True <|>
913+ extraTable False <|> extraTable True <|>
909 gridTable False <|> gridTable True <?> "table"
914 gridTable False <|> gridTable True <?> "table"
910
915
911--
916--