From 925c70f52bff3a488208ab12263a73d5513975fa Mon Sep 17 00:00:00 2001 From: Pagwin Date: Fri, 9 May 2025 20:32:43 -0400 Subject: [PATCH] realizing I should just use cmark and come back if I still don't like something later --- app/Markdown/Data.hs | 39 ++++++++++++++++++++++++++------------- app/Markdown/Parser.hs | 42 +++++++++++------------------------------- 2 files changed, 37 insertions(+), 44 deletions(-) diff --git a/app/Markdown/Data.hs b/app/Markdown/Data.hs index 91168dd..8be03a3 100644 --- a/app/Markdown/Data.hs +++ b/app/Markdown/Data.hs @@ -1,30 +1,43 @@ -{-# LANGUAGE RankNTypes, FlexibleContexts #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE RankNTypes #-} module Markdown.Data - ( MarkDownElement, - MListItem, + ( MListItem, Parser, + MarkdownElement + ( MHeading, + MParagraph, + MBold, + MItalic, + MBoldItalic, + MLink, + MLine, + MUnorderedList, + MOrderedList, + Only + ), ) where import Data.Text import Text.Parsec --- modified version of https://github.com/tusharad/markdown-parser -data MarkDownElement - = MHeading Int MarkDownElement - | MParagraph MarkDownElement - | MBold MarkDownElement - | MItalic MarkDownElement - | MBoldItalic MarkDownElement - | MLink MarkDownElement Text - | MLine [MarkDownElement] +-- very slightly modified version of https://github.com/tusharad/markdown-parser +data MarkdownElement + = MHeading Int MarkdownElement + | MParagraph MarkdownElement + | MBold MarkdownElement + | MItalic MarkdownElement + | MBoldItalic MarkdownElement + | MLink MarkdownElement Text + | MLine [MarkdownElement] | MUnorderedList [MListItem] | MOrderedList [MListItem] + | Raw Text -- HTML contained in the markdown | Only Text -- Bottom of all types deriving (Eq, Show) -data MListItem = MListItem MarkDownElement [MarkDownElement] +data MListItem = MListItem MarkdownElement [MarkdownElement] deriving (Eq, Show) type Parser v = forall s u m. (Monad m, Stream s m Char) => ParsecT s u m v diff --git a/app/Markdown/Parser.hs b/app/Markdown/Parser.hs index 552075e..28d9722 100644 --- a/app/Markdown/Parser.hs +++ b/app/Markdown/Parser.hs @@ -1,44 +1,24 @@ {-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} module Markdown.Parser - ( Markdown.Parser.lines, + ( heading, ) where -import Data.Functor (void) -import Data.Text (Text, pack) +import Markdown.Data import Text.Parsec -- https://spec.commonmark.org/0.31.2/ -- https://hackage.haskell.org/package/parsec -linebreak :: - (Monad m, Stream s m Char) => - ParsecT s u m () --- 2 newlines due to mark -linebreak = void (newline *> newline) - -emptyParse :: - (Monad m, Stream s m Char) => - ParsecT s u m String -emptyParse = "" <$ notFollowedBy anyChar - -line :: - (Monad m, Stream s m Char) => - ParsecT s u m Text -line = fmap pack $ many $ notFollowedBy linebreak *> anyChar - -lines :: - (Monad m, Stream s m Char) => - ParsecT s u m [Text] -lines = line `sepBy` linebreak - -heading :: - (Monad m, Stream s m Char) => - ParsecT s u m (Int, Text) +-- only ATX headings +heading :: Parser MarkdownElement heading = do - level <- fmap length $ many1 $ char '#' - text <- line - pure (level, text) + -- technically this can lead to illegal heading levels but + -- all the input is written by me so who cares + level <- fmap length $ try $ many1 $ char '#' --- TODO: blockquote, single backticks, triple backticks, links, arb HTML + return $ MHeading level $ Only "TODO" + +rawHTML