@@ -57,6 +57,7 @@ module Text.Pandoc.Parsing ( (>>~),
5757 orderedListMarker,
5858 charRef,
5959 tableWith,
60+ extraTableWith,
6061 gridTableWith,
6162 readWith,
6263 testStringWith,
@@ -542,7 +543,9 @@ tableWith headerParser rowParser lineParser footerParser captionParser = try $ d
542543 else return caption'
543544 state <- getState
544545 let numColumns = stateColumns state
545− let widths = widthsFromIndices numColumns indices
546+ let widths = if (indices == [])
547+ then replicate (length aligns) 0.0
548+ else widthsFromIndices numColumns indices
546549 return $ Table caption aligns widths heads lines'
547550
548551-- Calculate relative widths of table columns, based on indices
@@ -570,6 +573,99 @@ widthsFromIndices numColumns' indices =
570573 fracs = map (\l -> (fromIntegral l) / quotient) lengths in
571574 tail fracs
572575
576+
577+-- Parse an extra table (php-markdown): each line starts and ends with '|',
578+-- with a mandatory line of '--' to separate the (optionnal) headers from content.
579+extraTableWith :: GenParser Char ParserState Block -- ^ Block parser
580+ -> GenParser Char ParserState [Inline] -- ^ Caption parser
581+ -> Bool -- ^ Headerless table
582+ -> GenParser Char ParserState Block
583+extraTableWith block tableCaption headless =
584+ tableWith (extraTableHeader headless block) (extraTableRow block) (extraTableSep '-') extraTableFooter tableCaption
585+
586+-- | Parse header for an extra table.
587+extraTableHeader :: Bool -- ^ Headerless table
588+ -> GenParser Char ParserState Block
589+ -> GenParser Char ParserState ([[Block]], [Alignment], [Int])
590+extraTableHeader headless block = try $ do
591+ optional blanklines
592+ rawContent <- if headless
593+ then return $ repeat ""
594+ else many1
595+ (notFollowedBy (extraTableHeaderSep) >> char '|' >>
596+ many1Till anyChar newline)
597+ aligns <- extraTableHeaderDashedLine
598+ let indices = []
599+ let rawHeads = if headless
600+ then replicate (length aligns) ""
601+ else map (intercalate " ") $ transpose
602+ $ map (extraTableSplitLine )
603+ $ map (trimOnceBy '|') rawContent
604+ heads <- mapM (parseFromString $ many block) $
605+ map removeLeadingTrailingSpace rawHeads
606+ return (heads, aligns, indices)
607+
608+extraTableHeaderPart :: GenParser Char st Alignment
609+extraTableHeaderPart = do
610+ left <- optionMaybe (char ':')
611+ many1 (char '-')
612+ right <- optionMaybe (char ':')
613+ char '|'
614+ return $
615+ case (left,right) of
616+ (Nothing,Nothing) -> AlignDefault
617+ (Just _,Nothing) -> AlignLeft
618+ (Nothing,Just _) -> AlignRight
619+ (Just _,Just _) -> AlignCenter
620+
621+extraTableHeaderDashedLine :: GenParser Char st [Alignment]
622+extraTableHeaderDashedLine = try $ char '|' >> many1 (extraTableHeaderPart) >>~ blankline
623+
624+extraTableHeaderSep :: GenParser Char ParserState Char
625+extraTableHeaderSep = try $ extraTableHeaderDashedLine >> return '\n'
626+
627+-- | Split a header or data line in an extra table.
628+-- | The line must contain only *inside* separators.
629+extraTableSplitLine :: String -> [String]
630+extraTableSplitLine line = map removeLeadingSpace $
631+ splitBy (== '|') $ removeTrailingSpace line
632+
633+-- Remove, if present, a character from both ends of a string
634+trimOnceBy :: Char -> String -> String
635+trimOnceBy ch s =
636+ if (head s == ch) && (last s == ch)
637+ then init $ tail s
638+ else s
639+trimEndOnceBy :: Char -> String -> String
640+trimEndOnceBy ch s =
641+ if (last s == ch)
642+ then init s
643+ else s
644+
645+-- | Parse row of an extra table.
646+extraTableRow :: GenParser Char ParserState Block
647+ -> [Int]
648+ -> GenParser Char ParserState [[Block]]
649+extraTableRow block indices = do
650+ cols <- extraTableRawLine
651+ mapM (liftM compactifyCell . parseFromString (many block)) cols
652+
653+extraTableRawLine :: GenParser Char ParserState [String]
654+extraTableRawLine = do
655+ char '|'
656+ line <- many1Till anyChar newline
657+ return (extraTableSplitLine $ trimEndOnceBy '|' line)
658+
659+-- | Separator between rows of an extra table.
660+extraTableSep :: Char -> GenParser Char ParserState Char
661+extraTableSep ch = do return '\n'
662+
663+-- | Parse footer for an extra table.
664+extraTableFooter :: GenParser Char ParserState [Char]
665+extraTableFooter = blanklines
666+
667+---
668+
573669-- Parse a grid table: starts with row of '-' on top, then header
574670-- (which may be grid), then the rows,
575671-- which may be grid, separated by blank lines, and