packages feed

commonmark-simple 0.1.0.0 → 0.2.0.0

raw patch · 3 files changed

+91/−82 lines, 3 filesdep ~basedep ~commonmark-extensionsdep ~commonmark-pandocPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base, commonmark-extensions, commonmark-pandoc

API changes (from Hackage documentation)

- Commonmark.Simple: fullMarkdownSpec :: SyntaxSpec' m il bl => SyntaxSpec m il bl
+ Commonmark.Simple: fullMarkdownSpec :: forall (m :: Type -> Type) il bl. SyntaxSpec' m il bl => SyntaxSpec m il bl
- Commonmark.Simple: parseMarkdownWithFrontMatter :: forall meta m il bl. (FromJSON meta, m ~ Either ParseError, bl ~ Cm () Blocks, il ~ Cm () Inlines) => SyntaxSpec m il bl -> FilePath -> Text -> Either Text (Maybe meta, Pandoc)
+ Commonmark.Simple: parseMarkdownWithFrontMatter :: forall meta (m :: Type -> Type) il bl. (FromJSON meta, m ~ Either ParseError, bl ~ Cm () Blocks, il ~ Cm () Inlines) => SyntaxSpec m il bl -> FilePath -> Text -> Either Text (Maybe meta, Pandoc)

Files

README.md view
@@ -1,2 +1,3 @@ # commonmark-simple +Wraps [`commonmark-hs`](https://github.com/jgm/commonmark-hs) to give a simple API for parsing real-world Markdown.
commonmark-simple.cabal view
@@ -1,6 +1,6 @@ cabal-version:      2.4 name:               commonmark-simple-version:            0.1.0.0+version:            0.2.0.0 license:            MIT copyright:          2022 Sridhar Ratnakumar maintainer:         srid@srid.ca@@ -9,14 +9,15 @@  -- TODO: Before hackage release. -- A short (one-line) description of the package.-synopsis: Simple interface to commonmark-hs+synopsis:+  Simple interface to commonmark-hs for parsing real-world Markdown.  -- A longer description of the package.-description: Simple interface to parsing Markdown using commonmark-hs+description:+  Simple interface to parsing real-world Markdown using commonmark-hs  -- A URL where users can report bugs.-bug-reports: https://github.com/srid/commonmark-simple-+bug-reports:        https://github.com/srid/commonmark-simple extra-source-files:   LICENSE   README.md@@ -24,10 +25,10 @@ library   build-depends:     , aeson-    , base                   >=4.13.0.0 && <=4.18.0.0+    , base                   >=4.13.0.0 && <5     , commonmark-    , commonmark-extensions-    , commonmark-pandoc+    , commonmark-extensions  >=0.2.5+    , commonmark-pandoc      >=0.2.2     , containers     , megaparsec     , pandoc-types@@ -48,7 +49,6 @@     -fprint-explicit-foralls -fprint-explicit-kinds    default-extensions:-    NoStarIsType     BangPatterns     ConstraintKinds     DataKinds@@ -74,6 +74,7 @@     LambdaCase     MultiParamTypeClasses     MultiWayIf+    NoStarIsType     NumericUnderscores     OverloadedStrings     PolyKinds
src/Commonmark/Simple.hs view
@@ -1,8 +1,12 @@-module Commonmark.Simple-  ( parseMarkdownWithFrontMatter,+{- | A simple interface to the `commonmark` package for parsing real-world Markdown++Where 'real-world' means the kind of syntax used in the likes of Obsidian Markdown.+-}+module Commonmark.Simple (+    parseMarkdownWithFrontMatter,     parseMarkdown,     fullMarkdownSpec,-  )+) where  import Commonmark qualified as CM@@ -16,94 +20,97 @@ import Text.Pandoc.Builder qualified as B import Text.Pandoc.Definition (Pandoc (..)) --- | Parse a Markdown file using commonmark-hs with all extensions enabled+-- | Like `parseMarkdown` but also parses the YAML frontmatter parseMarkdownWithFrontMatter ::-  forall meta m il bl.-  ( FromJSON meta,-    m ~ Either CM.ParseError,-    bl ~ CP.Cm () B.Blocks,-    il ~ CP.Cm () B.Inlines-  ) =>-  CM.SyntaxSpec m il bl ->-  -- | Path to file associated with this Markdown-  FilePath ->-  -- | Markdown text to parse-  Text ->-  Either Text (Maybe meta, Pandoc)+    forall meta m il bl.+    ( FromJSON meta+    , m ~ Either CM.ParseError+    , bl ~ CP.Cm () B.Blocks+    , il ~ CP.Cm () B.Inlines+    ) =>+    CM.SyntaxSpec m il bl ->+    -- | Path to file associated with this Markdown+    FilePath ->+    -- | Markdown text to parse+    Text ->+    Either Text (Maybe meta, Pandoc) parseMarkdownWithFrontMatter spec fn s = do-  (mMeta, markdown) <- partitionMarkdown fn s-  mMetaVal <- first show $ (Y.decodeEither' . encodeUtf8) `traverse` mMeta-  blocks <- first show $ join $ CM.commonmarkWith @(Either CM.ParseError) spec fn markdown-  let doc = Pandoc mempty $ B.toList . CP.unCm @() @B.Blocks $ blocks-  pure (mMetaVal, doc)+    (mMeta, markdown) <- partitionMarkdown fn s+    mMetaVal <- first show $ (Y.decodeEither' . encodeUtf8) `traverse` mMeta+    blocks <- first show $ join $ CM.commonmarkWith @(Either CM.ParseError) spec fn markdown+    let doc = Pandoc mempty $ B.toList . CP.unCm @() @B.Blocks $ blocks+    pure (mMetaVal, doc) +-- | Parse a Markdown file using commonmark-hs with all extensions enabled parseMarkdown :: FilePath -> Text -> Either Text Pandoc parseMarkdown fn s = do-  cmBlocks <- first show $ join $ CM.commonmarkWith @(Either CM.ParseError) fullMarkdownSpec fn s-  let blocks = B.toList . CP.unCm @() @B.Blocks $ cmBlocks-  pure $ Pandoc mempty blocks+    cmBlocks <- first show $ join $ CM.commonmarkWith @(Either CM.ParseError) fullMarkdownSpec fn s+    let blocks = B.toList . CP.unCm @() @B.Blocks $ cmBlocks+    pure $ Pandoc mempty blocks  type SyntaxSpec' m il bl =-  ( Monad m,-    CM.IsBlock il bl,-    CM.IsInline il,-    Typeable m,-    Typeable il,-    Typeable bl,-    CE.HasEmoji il,-    CE.HasStrikethrough il,-    CE.HasPipeTable il bl,-    CE.HasTaskList il bl,-    CM.ToPlainText il,-    CE.HasFootnote il bl,-    CE.HasMath il,-    CE.HasDefinitionList il bl,-    CE.HasDiv bl,-    CE.HasQuoted il,-    CE.HasSpan il-  )+    ( Monad m+    , CM.IsBlock il bl+    , CM.IsInline il+    , Typeable m+    , Typeable il+    , Typeable bl+    , CE.HasEmoji il+    , CE.HasStrikethrough il+    , CE.HasPipeTable il bl+    , CE.HasTaskList il bl+    , CM.ToPlainText il+    , CE.HasFootnote il bl+    , CE.HasMath il+    , CE.HasDefinitionList il bl+    , CE.HasDiv bl+    , CE.HasQuoted il+    , CE.HasSpan il+    , CE.HasAlerts il bl+    )  -- | GFM + official commonmark extensions fullMarkdownSpec ::-  SyntaxSpec' m il bl =>-  CM.SyntaxSpec m il bl+    (SyntaxSpec' m il bl) =>+    CM.SyntaxSpec m il bl fullMarkdownSpec =-  mconcat-    [ CE.gfmExtensions,-      CE.fancyListSpec,-      CE.footnoteSpec,-      CE.mathSpec,-      CE.smartPunctuationSpec,-      CE.definitionListSpec,-      CE.attributesSpec,-      CE.rawAttributeSpec,-      CE.fencedDivSpec,-      CE.bracketedSpanSpec,-      CE.autolinkSpec,-      CM.defaultSyntaxSpec,-      -- as the commonmark documentation states, pipeTableSpec should be placed after-      -- fancyListSpec and defaultSyntaxSpec to avoid bad results when parsing-      -- non-table lines-      CE.pipeTableSpec-    ]+    mconcat+        [ CE.gfmExtensions+        , CE.fancyListSpec+        , CE.footnoteSpec+        , CE.mathSpec+        , CE.smartPunctuationSpec+        , CE.definitionListSpec+        , CE.attributesSpec+        , CE.rawAttributeSpec+        , CE.fencedDivSpec+        , CE.bracketedSpanSpec+        , CE.autolinkSpec+        , CM.defaultSyntaxSpec+        , -- as the commonmark documentation states, pipeTableSpec should be placed after+          -- fancyListSpec and defaultSyntaxSpec to avoid bad results when parsing+          -- non-table lines+          CE.pipeTableSpec+        ] --- | Identify metadata block at the top, and split it from markdown body.------ FIXME: https://github.com/srid/neuron/issues/175+{- | Identify metadata block at the top, and split it from markdown body.++FIXME: https://github.com/srid/neuron/issues/175+-} partitionMarkdown :: FilePath -> Text -> Either Text (Maybe Text, Text) partitionMarkdown =-  parse (M.try splitP <|> fmap (Nothing,) M.takeRest)+    parse (M.try splitP <|> fmap (Nothing,) M.takeRest)   where     separatorP :: M.Parsec Void Text ()     separatorP =-      void $ M.string "---" <* M.eol+        void $ M.string "---" <* M.eol     splitP :: M.Parsec Void Text (Maybe Text, Text)     splitP = do-      separatorP-      a <- toText <$> manyTill M.anySingle (M.try $ M.eol *> separatorP)-      b <- M.takeRest-      pure (Just a, b)+        separatorP+        a <- toText <$> manyTill M.anySingle (M.try $ M.eol *> separatorP)+        b <- M.takeRest+        pure (Just a, b)     parse :: M.Parsec Void Text a -> String -> Text -> Either Text a     parse p fn s =-      first (toText . M.errorBundlePretty) $-        M.parse (p <* M.eof) fn s+        first (toText . M.errorBundlePretty) $+            M.parse (p <* M.eof) fn s