git.iko.soy/typeable/pandoc
on master help sign in
Org reader: fix handling of empty table cells, rows

This fixes Org mode parsing of some corner cases regarding empty cells and rows. Empty cells weren't parsed correctly, e.g. `|||` should be two empty cells, but would be parsed as a single cell containing a pipe character. Empty rows where parsed as alignment rows and dropped from the output. This fixes #2616.

commit2d825603c684d6c7af6adb08f26ed34a078a5afe authorAlbert Krewinkel <albert@zeitkraut.de> dateWed 4 May 2016, 15:33 (10 years ago) parenta51e4e8
2 files changed+29−14
src/Text/Pandoc/Readers/Org.hs+17−13 tests/Tests/Readers/Org.hs+12−1
src/Text/Pandoc/Readers/Org.hs+17−13
@@ -35,6 +35,7 @@ import Text.Pandoc.Builder ( Inlines, Blocks, HasMeta(..),
3535 trimInlines )
3636import Text.Pandoc.Definition
3737import Text.Pandoc.Compat.Monoid ((<>))
38+import Text.Pandoc.Error
3839import Text.Pandoc.Options
3940import qualified Text.Pandoc.Parsing as P
4041import Text.Pandoc.Parsing hiding ( F, unF, askF, asksF, runF
@@ -57,8 +58,6 @@ import qualified Data.Set as Set
5758import Data.Maybe (fromMaybe, isJust)
5859import Network.HTTP (urlEncode)
5960
60−import Text.Pandoc.Error
61−
6261-- | Parse org-mode string and return a Pandoc document.
6362readOrg :: ReaderOptions -- ^ Reader options
6463 -> String -- ^ String to parse (assuming @'\n'@ line endings)
@@ -807,18 +806,19 @@ tableRows = try $ many (tableAlignRow <|> tableHline <|> tableContentRow)
807806
808807tableContentRow :: OrgParser OrgTableRow
809808tableContentRow = try $
810− OrgContentRow . sequence <$> (tableStart *> manyTill tableContentCell newline)
809+ OrgContentRow . sequence <$> (tableStart *> many1Till tableContentCell newline)
811810
812811tableContentCell :: OrgParser (F Blocks)
813812tableContentCell = try $
814− fmap B.plain . trimInlinesF . mconcat <$> many1Till inline endOfCell
815−
816−endOfCell :: OrgParser Char
817−endOfCell = try $ char '|' <|> lookAhead newline
813+ fmap B.plain . trimInlinesF . mconcat <$> manyTill inline endOfCell
818814
819815tableAlignRow :: OrgParser OrgTableRow
820−tableAlignRow = try $
821− OrgAlignRow <$> (tableStart *> manyTill tableAlignCell newline)
816+tableAlignRow = try $ do
817+ tableStart
818+ cells <- many1Till tableAlignCell newline
819+ -- Empty rows are regular (i.e. content) rows, not alignment rows.
820+ guard $ any (/= AlignDefault) cells
821+ return $ OrgAlignRow cells
822822
823823tableAlignCell :: OrgParser Alignment
824824tableAlignCell =
@@ -833,15 +833,19 @@ tableAlignCell =
833833 where emptyCell = try $ skipSpaces *> endOfCell
834834
835835tableAlignFromChar :: OrgParser Alignment
836−tableAlignFromChar = try $ choice [ char 'l' *> return AlignLeft
837− , char 'c' *> return AlignCenter
838− , char 'r' *> return AlignRight
839− ]
836+tableAlignFromChar = try $
837+ choice [ char 'l' *> return AlignLeft
838+ , char 'c' *> return AlignCenter
839+ , char 'r' *> return AlignRight
840+ ]
840841
841842tableHline :: OrgParser OrgTableRow
842843tableHline = try $
843844 OrgHlineRow <$ (tableStart *> char '-' *> anyLine)
844845
846+endOfCell :: OrgParser Char
847+endOfCell = try $ char '|' <|> lookAhead newline
848+
845849rowsToTable :: [OrgTableRow]
846850 -> F OrgTable
847851rowsToTable = foldM rowToContent emptyTable
tests/Tests/Readers/Org.hs+12−1
@@ -941,7 +941,7 @@ tests =
941941
942942 , "Empty table" =:
943943 "||" =?>
944− simpleTable' 1 mempty mempty
944+ simpleTable' 1 mempty [[mempty]]
945945
946946 , "Glider Table" =:
947947 unlines [ "| 1 | 0 | 0 |"
@@ -996,6 +996,17 @@ tests =
996996 , [ plain "dynamic", plain "Lisp" ]
997997 ]
998998
999+ , "Table with empty cells" =:
1000+ "|||c|" =?>
1001+ simpleTable' 3 mempty [[mempty, mempty, plain "c"]]
1002+
1003+ , "Table with empty rows" =:
1004+ unlines [ "| first |"
1005+ , "| |"
1006+ , "| third |"
1007+ ] =?>
1008+ simpleTable' 1 mempty [[plain "first"], [mempty], [plain "third"]]
1009+
9991010 , "Table with alignment row" =:
10001011 unlines [ "| Numbers | Text | More |"
10011012 , "| <c> | <r> | |"