git.iko.soy/typeable/pandoc
on master help sign in
Merge pull request #510 from mytskine/markdown-extra

Markdown extra tables [part of the multi-markdown syntax for tables]

commit511f5e891dcba126bf6159bb1f816a3d25895f00 authorJohn MacFarlane <jgm@berkeley.edu> dateSun 22 Jul 2012, 18:40 (14 years ago) parent1d19400a922bd6
5 files changed+198−1
src/Tests/Old.hs+2 src/Text/Pandoc/Parsing.hs+97−1 src/Text/Pandoc/Readers/Markdown.hs+5 tests/markdown-tables.native+60 tests/markdown-tables.txt+34
src/Tests/Old.hs+2
@@ -56,6 +56,8 @@ tests = [ testGroup "markdown"
5656 "testsuite.txt" "testsuite.native"
5757 , test "tables" ["-r", "markdown", "-w", "native", "--columns=80"]
5858 "tables.txt" "tables.native"
59+ , test "extratables" ["-r", "markdown", "-w", "native", "--columns=80"]
60+ "markdown-tables.txt" "markdown-tables.native"
5961 , test "more" ["-r", "markdown", "-w", "native", "-S"]
6062 "markdown-reader-more.txt" "markdown-reader-more.native"
6163 , lhsReaderTest "markdown+lhs"
src/Text/Pandoc/Parsing.hs+97−1
@@ -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
src/Text/Pandoc/Readers/Markdown.hs+5
@@ -901,6 +901,10 @@ alignType strLst len =
901901 (True, True) -> AlignCenter
902902 (False, False) -> AlignDefault
903903
904+extraTable :: Bool -- ^ Headerless table
905+ -> GenParser Char ParserState Block
906+extraTable = extraTableWith block tableCaption
907+
904908gridTable :: Bool -- ^ Headerless table
905909 -> Parser [Char] ParserState Block
906910gridTable = gridTableWith block tableCaption
@@ -908,6 +912,7 @@ gridTable = gridTableWith block tableCaption
908912table :: Parser [Char] ParserState Block
909913table = multilineTable False <|> simpleTable True <|>
910914 simpleTable False <|> multilineTable True <|>
915+ extraTable False <|> extraTable True <|>
911916 gridTable False <|> gridTable True <?> "table"
912917
913918--
tests/markdown-tables.nativenew file+60
@@ -0,0 +1,60 @@
1+[Para [Str "Simplest",Space,Str "table",Space,Str "without",Space,Str "caption",Str ":"]
2+,Table [] [AlignDefault,AlignDefault,AlignDefault] [0.0,0.0,0.0]
3+ [[Plain [Str "Default1"]]
4+ ,[Plain [Str "Default2"]]
5+ ,[Plain [Str "Default3"]]]
6+ [[[Plain [Str "12"]]
7+ ,[Plain [Str "12"]]
8+ ,[Plain [Str "12"]]]
9+ ,[[Plain [Str "123"]]
10+ ,[Plain [Str "123"]]
11+ ,[Plain [Str "123"]]]
12+ ,[[Plain [Str "1"]]
13+ ,[Plain [Str "1"]]
14+ ,[Plain [Str "1"]]]]
15+,Para [Str "Simple",Space,Str "table",Space,Str "with",Space,Str "caption",Str ":"]
16+,Table [Str "Demonstration",Space,Str "of",Space,Str "simple",Space,Str "table",Space,Str "syntax",Str "."] [AlignRight,AlignLeft,AlignDefault,AlignCenter] [0.0,0.0,0.0,0.0]
17+ [[Plain [Str "Right"]]
18+ ,[Plain [Str "Left"]]
19+ ,[Plain [Str "Default"]]
20+ ,[Plain [Str "Center"]]]
21+ [[[Plain [Str "12"]]
22+ ,[Plain [Str "12"]]
23+ ,[Plain [Str "12"]]
24+ ,[Plain [Str "12"]]]
25+ ,[[Plain [Str "123"]]
26+ ,[Plain [Str "123"]]
27+ ,[Plain [Str "123"]]
28+ ,[Plain [Str "123"]]]
29+ ,[[Plain [Str "1"]]
30+ ,[Plain [Str "1"]]
31+ ,[Plain [Str "1"]]
32+ ,[Plain [Str "1"]]]]
33+,Para [Str "Simple",Space,Str "table",Space,Str "without",Space,Str "caption",Str ":"]
34+,Table [] [AlignRight,AlignLeft,AlignCenter] [0.0,0.0,0.0]
35+ [[Plain [Str "Right"]]
36+ ,[Plain [Str "Left"]]
37+ ,[Plain [Str "Center"]]]
38+ [[[Plain [Str "12"]]
39+ ,[Plain [Str "12"]]
40+ ,[Plain [Str "12"]]]
41+ ,[[Plain [Str "123"]]
42+ ,[Plain [Str "123"]]
43+ ,[Plain [Str "123"]]]
44+ ,[[Plain [Str "1"]]
45+ ,[Plain [Str "1"]]
46+ ,[Plain [Str "1"]]]]
47+,Para [Str "Headerless",Space,Str "table",Space,Str "without",Space,Str "caption",Str ":"]
48+,Table [] [AlignRight,AlignLeft,AlignCenter] [0.0,0.0,0.0]
49+ [[]
50+ ,[]
51+ ,[]]
52+ [[[Plain [Str "12"]]
53+ ,[Plain [Str "12"]]
54+ ,[Plain [Str "12"]]]
55+ ,[[Plain [Str "123"]]
56+ ,[Plain [Str "123"]]
57+ ,[Plain [Str "123"]]]
58+ ,[[Plain [Str "1"]]
59+ ,[Plain [Str "1"]]
60+ ,[Plain [Str "1"]]]]]
tests/markdown-tables.txtnew file+34
@@ -0,0 +1,34 @@
1+Simplest table without caption:
2+
3+| Default1 | Default2 | Default3 |
4+|----------|----------|----------|
5+|12|12|12|
6+|123|123|123|
7+|1|1|1|
8+
9+Simple table with caption:
10+
11+| Right | Left | Default | Center |
12+|------:|:-----|---------|:------:|
13+| 12 | 12 | 12 | 12 |
14+| 123 | 123 | 123 | 123 |
15+| 1 | 1 | 1 | 1 |
16+
17+ : Demonstration of simple table syntax.
18+
19+Simple table without caption:
20+
21+| Right | Left | Center |
22+|------:|:-----|:------:|
23+|12|12|12|
24+|123|123|123|
25+|1|1|1|
26+
27+
28+Headerless table without caption:
29+
30+|------:|:-----|:------:|
31+|12|12|12|
32+|123|123|123|
33+|1|1|1|
34+