@@ -56,6 +56,7 @@ module Text.Pandoc.Parsing ( (>>~),
5656 orderedListMarker,
5757 charRef,
5858 tableWith,
59+ extraTableWith,
5960 gridTableWith,
6061 readWith,
6162 testStringWith,
@@ -487,7 +488,9 @@ tableWith headerParser rowParser lineParser footerParser captionParser = try $ d
487488 else return caption'
488489 state <- getState
489490 let numColumns = stateColumns state
490− let widths = widthsFromIndices numColumns indices
491+ let widths = if (indices == [])
492+ then replicate (length aligns) 0.0
493+ else widthsFromIndices numColumns indices
491494 return $ Table caption aligns widths heads lines'
492495
493496-- Calculate relative widths of table columns, based on indices
@@ -515,6 +518,99 @@ widthsFromIndices numColumns' indices =
515518 fracs = map (\l -> (fromIntegral l) / quotient) lengths in
516519 tail fracs
517520
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+
518614-- Parse a grid table: starts with row of '-' on top, then header
519615-- (which may be grid), then the rows,
520616-- which may be grid, separated by blank lines, and