commonmark-simple (empty) → 0.1.0.0
raw patch · 4 files changed
+224/−0 lines, 4 filesdep +aesondep +basedep +commonmark
Dependencies added: aeson, base, commonmark, commonmark-extensions, commonmark-pandoc, containers, megaparsec, pandoc-types, parsec, parser-combinators, relude, yaml
Files
- LICENSE +21/−0
- README.md +2/−0
- commonmark-simple.cabal +92/−0
- src/Commonmark/Simple.hs +109/−0
+ LICENSE view
@@ -0,0 +1,21 @@+MIT License++Copyright (c) 2021 Sridhar Ratnakumar++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+SOFTWARE.
+ README.md view
@@ -0,0 +1,2 @@+# commonmark-simple+
+ commonmark-simple.cabal view
@@ -0,0 +1,92 @@+cabal-version: 2.4+name: commonmark-simple+version: 0.1.0.0+license: MIT+copyright: 2022 Sridhar Ratnakumar+maintainer: srid@srid.ca+author: Sridhar Ratnakumar+category: Text++-- TODO: Before hackage release.+-- A short (one-line) description of the package.+synopsis: Simple interface to commonmark-hs++-- A longer description of the package.+description: Simple interface to parsing Markdown using commonmark-hs++-- A URL where users can report bugs.+bug-reports: https://github.com/srid/commonmark-simple++extra-source-files:+ LICENSE+ README.md++library+ build-depends:+ , aeson+ , base >=4.13.0.0 && <=4.18.0.0+ , commonmark+ , commonmark-extensions+ , commonmark-pandoc+ , containers+ , megaparsec+ , pandoc-types+ , parsec+ , parser-combinators+ , relude+ , yaml++ exposed-modules: Commonmark.Simple+ mixins:+ base hiding (Prelude),+ relude (Relude as Prelude, Relude.Container.One),+ relude++ ghc-options:+ -Wall -Wincomplete-record-updates -Wincomplete-uni-patterns+ -Wmissing-deriving-strategies -Wunused-foralls -Wunused-foralls+ -fprint-explicit-foralls -fprint-explicit-kinds++ default-extensions:+ NoStarIsType+ BangPatterns+ ConstraintKinds+ DataKinds+ DeriveDataTypeable+ DeriveFoldable+ DeriveFunctor+ DeriveGeneric+ DeriveLift+ DeriveTraversable+ DerivingStrategies+ DerivingVia+ EmptyCase+ EmptyDataDecls+ EmptyDataDeriving+ ExistentialQuantification+ ExplicitForAll+ FlexibleContexts+ FlexibleInstances+ GADTSyntax+ GeneralisedNewtypeDeriving+ ImportQualifiedPost+ KindSignatures+ LambdaCase+ MultiParamTypeClasses+ MultiWayIf+ NumericUnderscores+ OverloadedStrings+ PolyKinds+ PostfixOperators+ RankNTypes+ ScopedTypeVariables+ StandaloneDeriving+ StandaloneKindSignatures+ TupleSections+ TypeApplications+ TypeFamilies+ TypeOperators+ ViewPatterns++ hs-source-dirs: src+ default-language: Haskell2010
+ src/Commonmark/Simple.hs view
@@ -0,0 +1,109 @@+module Commonmark.Simple+ ( parseMarkdownWithFrontMatter,+ parseMarkdown,+ fullMarkdownSpec,+ )+where++import Commonmark qualified as CM+import Commonmark.Extensions qualified as CE+import Commonmark.Pandoc qualified as CP+import Control.Monad.Combinators (manyTill)+import Data.Aeson (FromJSON)+import Data.Yaml qualified as Y+import Text.Megaparsec qualified as M+import Text.Megaparsec.Char qualified as M+import Text.Pandoc.Builder qualified as B+import Text.Pandoc.Definition (Pandoc (..))++-- | Parse a Markdown file using commonmark-hs with all extensions enabled+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)+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)++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++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+ )++-- | GFM + official commonmark extensions+fullMarkdownSpec ::+ 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+ ]++-- | 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)+ where+ separatorP :: M.Parsec Void Text ()+ separatorP =+ 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)+ 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