Skip to content

Instantly share code, notes, and snippets.

@HirotoShioi
Created December 25, 2018 05:23
Show Gist options
  • Save HirotoShioi/8bd3585e6333c6bf40e012fe99172728 to your computer and use it in GitHub Desktop.
Save HirotoShioi/8bd3585e6333c6bf40e012fe99172728 to your computer and use it in GitHub Desktop.
Markdown table parser
{-# LANGUAGE OverloadedStrings #-}
module Table where
import Control.Monad
import Data.Attoparsec.Text as P
import Data.Text (Text)
import qualified Data.Text as T
data Table = Table [Column]
deriving Show
data Column = Column [Text]
deriving Show
columnParser :: Parser Column
columnParser = do
rest <- takeText
go mempty rest
where
go :: [Text] -> Text -> Parser Column
go currList curr =
flip either
(\(currList', rest') -> do
let symbolCount = T.length $ T.filter (== '|') rest'
if T.null rest' || symbolCount < 2
then return $ Column currList'
else go currList' rest'
)
(\err -> fail err)
(parseOnly (getElem currList) curr)
getElem :: [Text] -> Parser ([Text], Text)
getElem currList = do
void $ P.char '|'
element <- T.strip <$> P.takeWhile (/= '|')
rest <- takeText
return $ ((currList ++ [element]), rest)
testColumnParser :: Either String Column
testColumnParser = parseOnly columnParser "| hello | this is | test |"
testTable :: [Text]
testTable =
[ "| hello | this is | test |"
, "| 1 | 2 | 3 |"
, "| a | b | c |"
]
parseTable :: [Text] -> Either String Table
parseTable texts = go (Table mempty) texts
where
go :: Table -> [Text] -> Either String Table
go table [] = return table
go (Table currList) (t:ts) =
either
(\a -> Left a) -- ????????
(\column -> go (Table (currList <> [column])) ts)
(parseOnly columnParser t)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment