git.iko.soy/typeable/pandoc
on master help sign in
Allow markdown tables without headers.

Resolves Issue #50. The new syntax is described in README. Also allow optional line of dashes at bottom of simple tables. git-svn-id: https://pandoc.googlecode.com/svn/trunk@1652 788f1e2b-df1e-0410-8736-df70ead52e1b

commitad5450266ce29ff6ed9e238ca0cc14f08da862f7 authorfiddlosopher <fiddlosopher@788f1e2b-df1e-0410-8736-df70ead52e1b> dateSat 5 Dec 2009, 21:34 (17 years ago) parentde38adc
2 files changed+88−32
README+36−4 src/Text/Pandoc/Readers/Markdown.hs+52−28
README+36−4
@@ -705,9 +705,23 @@ to the dashed line below it:[^3]
705705[^3]: This scheme is due to Michel Fortin, who proposed it on the
706706 [Markdown discussion list](http://six.pairlist.net/pipermail/markdown-discuss/2005-March/001097.html).
707707
708−The table must end with a blank line. Optionally, a caption may be
709−provided (as illustrated in the example above). A caption is a paragraph
710−beginning with the string `Table:`, which will be stripped off.
708+The table must end with a blank line, or a line of dashes followed by
709+a blank line. A caption may optionally be provided (as illustrated in
710+the example above). A caption is a paragraph beginning with the string
711+`Table:`, which will be stripped off.
712+
713+The column headers may be omitted, provided a dashed line is used
714+to end the table. For example:
715+
716+ ------- ------ ---------- -------
717+ 12 12 12 12
718+ 123 123 123 123
719+ 1 1 1 1
720+ ------- ------ ---------- -------
721+
722+When headers are omitted, column alignments are determined on the basis
723+of the first line of the table body. So, in the tables above, the columns
724+would be right, left, center, and right aligned, respectively.
711725
712726Multiline tables allow headers and table rows to span multiple lines
713727of text. Here is an example:
@@ -729,7 +743,8 @@ of text. Here is an example:
729743
730744These work like simple tables, but with the following differences:
731745
732− - They must begin with a row of dashes, before the header text.
746+ - They must begin with a row of dashes, before the header text
747+ (unless the headers are omitted).
733748 - They must end with a row of dashes, then a blank line.
734749 - The rows must be separated by blank lines.
735750
@@ -738,6 +753,23 @@ the columns, and the writers try to reproduce these relative widths in
738753the output. So, if you find that one of the columns is too narrow in the
739754output, try widening it in the markdown source.
740755
756+Headers may be omitted in multiline tables as well as simple tables:
757+
758+ ----------- ------- --------------- -------------------------
759+ First row 12.0 Example of a row that
760+ spans multiple lines.
761+
762+ Second row 5.0 Here's another one. Note
763+ the blank line between
764+ rows.
765+ -------------------------------------------------------------
766+
767+ Table: Here's a multiline table without headers.
768+
769+It is possible for a multiline table to have just one row, but the row
770+should be followed by a blank line (and then the row of dashes that ends
771+the table), or the table may be interpreted as a simple table.
772+
741773Delimited Code blocks
742774---------------------
743775
src/Text/Pandoc/Readers/Markdown.hs+52−28
@@ -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