mmark-ext 0.2.1.2 → 0.2.1.3
raw patch · 27 files changed
+445/−474 lines, 27 filesdep ~basedep ~modern-uridep ~skylightingPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base, modern-uri, skylighting
API changes (from Hackage documentation)
Files
- CHANGELOG.md +6/−0
- LICENSE.md +1/−1
- README.md +2/−2
- Text/MMark/Extension/Comment.hs +9/−9
- Text/MMark/Extension/Common.hs +13/−13
- Text/MMark/Extension/FontAwesome.hs +15/−17
- Text/MMark/Extension/Footnotes.hs +36/−37
- Text/MMark/Extension/GhcSyntaxHighlighter.hs +22/−49
- Text/MMark/Extension/Kbd.hs +7/−8
- Text/MMark/Extension/LinkTarget.hs +13/−12
- Text/MMark/Extension/MathJax.hs +18/−20
- Text/MMark/Extension/ObfuscateEmail.hs +21/−18
- Text/MMark/Extension/PunctuationPrettifier.hs +15/−16
- Text/MMark/Extension/Skylighting.hs +58/−59
- Text/MMark/Extension/TableOfContents.hs +27/−28
- data/toc.html +2/−2
- mmark-ext.cabal +92/−83
- tests/Text/MMark/Extension/FontAwesomeSpec.hs +1/−1
- tests/Text/MMark/Extension/FootnotesSpec.hs +10/−10
- tests/Text/MMark/Extension/GhcSyntaxHighlighterSpec.hs +2/−9
- tests/Text/MMark/Extension/LinkTargetSpec.hs +6/−6
- tests/Text/MMark/Extension/MathJaxSpec.hs +13/−13
- tests/Text/MMark/Extension/ObfuscateEmailSpec.hs +1/−1
- tests/Text/MMark/Extension/PunctuationPrettifierSpec.hs +20/−20
- tests/Text/MMark/Extension/SkylightingSpec.hs +4/−14
- tests/Text/MMark/Extension/TableOfContentsSpec.hs +12/−11
- tests/Text/MMark/Extension/TestUtils.hs +19/−15
CHANGELOG.md view
@@ -1,3 +1,9 @@+## MMark Ext 0.2.1.3++* The test suite passes with `modern-uri-0.3.4` and later.++* Dropped support for GHC 8.6 and older.+ ## MMark Ext 0.2.1.2 * Made the tests pass with `skylighting-0.7.6`.
LICENSE.md view
@@ -1,4 +1,4 @@-Copyright © 2017–2018 Mark Karpov+Copyright © 2017–present Mark Karpov All rights reserved.
README.md view
@@ -4,7 +4,7 @@ [](https://hackage.haskell.org/package/mmark-ext) [](http://stackage.org/nightly/package/mmark-ext) [](http://stackage.org/lts/package/mmark-ext)-[](https://travis-ci.org/mmark-md/mmark-ext)+ Commonly useful extensions for the [MMark](https://hackage.haskell.org/package/mmark) markdown processor.@@ -18,6 +18,6 @@ ## License -Copyright © 2017–2019 Mark Karpov+Copyright © 2017–present Mark Karpov Distributed under BSD 3 clause license.
Text/MMark/Extension/Comment.hs view
@@ -1,6 +1,6 @@ -- | -- Module : Text.MMark.Extension.Comment--- Copyright : © 2018–2019 Mark Karpov+-- Copyright : © 2018–present Mark Karpov -- License : BSD 3 clause -- -- Maintainer : Mark Karpov <markkarpov92@gmail.com>@@ -9,24 +9,24 @@ -- -- Turn paragraphs into comments by prefixing them with a certain sequence -- of characters.- module Text.MMark.Extension.Comment- ( commentParagraph )+ ( commentParagraph,+ ) where import Control.Monad import Data.List.NonEmpty (NonEmpty (..)) import Data.Text (Text)-import Text.MMark.Extension (Extension, Block (..), Inline (..))-import qualified Data.Text as T+import qualified Data.Text as T+import Text.MMark.Extension (Block (..), Extension, Inline (..)) import qualified Text.MMark.Extension as Ext -- | This extension removes top-level paragraphs starting with the given -- sequence of non-markup characters.--commentParagraph- :: Text -- ^ Sequence of characters that starts a comment- -> Extension+commentParagraph ::+ -- | Sequence of characters that starts a comment+ Text ->+ Extension commentParagraph commentPrefix = Ext.blockRender $ \old block -> case block of p@(Paragraph (ois, _)) ->
Text/MMark/Extension/Common.hs view
@@ -1,6 +1,6 @@ -- | -- Module : Text.MMark.Extension.Common--- Copyright : © 2017–2019 Mark Karpov+-- Copyright : © 2017–present Mark Karpov -- License : BSD 3 clause -- -- Maintainer : Mark Karpov <markkarpov92@gmail.com>@@ -43,19 +43,19 @@ -- > , Ext.punctuationPrettifier -- > , Ext.skylighting ] -- > $ r- module Text.MMark.Extension.Common- ( module Text.MMark.Extension.Comment- , module Text.MMark.Extension.FontAwesome- , module Text.MMark.Extension.Footnotes- , module Text.MMark.Extension.GhcSyntaxHighlighter- , module Text.MMark.Extension.Kbd- , module Text.MMark.Extension.LinkTarget- , module Text.MMark.Extension.MathJax- , module Text.MMark.Extension.ObfuscateEmail- , module Text.MMark.Extension.PunctuationPrettifier- , module Text.MMark.Extension.Skylighting- , module Text.MMark.Extension.TableOfContents )+ ( module Text.MMark.Extension.Comment,+ module Text.MMark.Extension.FontAwesome,+ module Text.MMark.Extension.Footnotes,+ module Text.MMark.Extension.GhcSyntaxHighlighter,+ module Text.MMark.Extension.Kbd,+ module Text.MMark.Extension.LinkTarget,+ module Text.MMark.Extension.MathJax,+ module Text.MMark.Extension.ObfuscateEmail,+ module Text.MMark.Extension.PunctuationPrettifier,+ module Text.MMark.Extension.Skylighting,+ module Text.MMark.Extension.TableOfContents,+ ) where import Text.MMark.Extension.Comment
Text/MMark/Extension/FontAwesome.hs view
@@ -1,6 +1,9 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE QuasiQuotes #-}+ -- | -- Module : Text.MMark.Extension.FontAwesome--- Copyright : © 2017–2019 Mark Karpov+-- Copyright : © 2017–present Mark Karpov -- License : BSD 3 clause -- -- Maintainer : Mark Karpov <markkarpov92@gmail.com>@@ -8,23 +11,19 @@ -- Portability : portable -- -- Turn links into Font Awesome icons.--{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE QuasiQuotes #-}- module Text.MMark.Extension.FontAwesome- ( fontAwesome )+ ( fontAwesome,+ ) where -import Data.Semigroup ((<>))+import qualified Data.Text as T import Lens.Micro ((^.)) import Lucid import Text.MMark.Extension (Extension, Inline (..))+import qualified Text.MMark.Extension as Ext+import qualified Text.URI as URI import Text.URI.Lens (uriPath) import Text.URI.QQ (scheme)-import qualified Data.Text as T-import qualified Text.MMark.Extension as Ext-import qualified Text.URI as URI -- | Allow to insert @span@s with font awesome icons using autolinks like -- this:@@ -48,18 +47,17 @@ -- > <fa:quote-left/3x/pull-left/border> -- -- See also: <http://fontawesome.io>.- fontAwesome :: Extension fontAwesome = Ext.inlineRender $ \old inline -> case inline of l@(Link _ uri _) -> if URI.uriScheme uri == Just [scheme|fa|] then case uri ^. uriPath of- [] -> old l- xs ->- let g x = "fa-" <> URI.unRText x- in span_- [ (class_ . T.intercalate " ") ("fa" : fmap g xs) ]- ""+ [] -> old l+ xs ->+ let g x = "fa-" <> URI.unRText x+ in span_+ [(class_ . T.intercalate " ") ("fa" : fmap g xs)]+ "" else old l other -> old other
Text/MMark/Extension/Footnotes.hs view
@@ -1,6 +1,9 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE QuasiQuotes #-}+ -- | -- Module : Text.MMark.Extension.Footnotes--- Copyright : © 2018–2019 Mark Karpov+-- Copyright : © 2018–present Mark Karpov -- License : BSD 3 clause -- -- Maintainer : Mark Karpov <markkarpov92@gmail.com>@@ -10,28 +13,24 @@ -- An extension to add footnotes to your documents. -- -- @since 0.1.1.0--{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE QuasiQuotes #-}- module Text.MMark.Extension.Footnotes- ( footnotes )+ ( footnotes,+ ) where import Control.Monad import Data.Char (isDigit) import Data.List.NonEmpty (NonEmpty (..))-import Data.Semigroup ((<>))+import qualified Data.List.NonEmpty as NE import Data.Text (Text)+import qualified Data.Text as T import Lens.Micro ((^.)) import Lucid-import Text.MMark.Extension (Extension, Inline (..), Block (..), getOis)+import Text.MMark.Extension (Block (..), Extension, Inline (..), getOis)+import qualified Text.MMark.Extension as Ext+import qualified Text.URI as URI import Text.URI.Lens (uriPath) import Text.URI.QQ (scheme)-import qualified Data.List.NonEmpty as NE-import qualified Data.Text as T-import qualified Text.MMark.Extension as Ext-import qualified Text.URI as URI -- | The extension performs two transformations: --@@ -50,53 +49,53 @@ -- that a footnote reference refers to an existing footnote and that -- footnotes have corresponding references, or that they are present in the -- document in the right order.- footnotes :: Extension footnotes = footnoteRefs <> footnoteSection -- | Create footnote references.- footnoteRefs :: Extension footnoteRefs = Ext.inlineRender $ \old inline -> case inline of l@(Link _ uri _) -> if URI.uriScheme uri == Just [scheme|footnote|] then case uri ^. uriPath of- [x'] ->- let x = URI.unRText x'- in if T.all isDigit x- then a_ [ fragmentHref (footnoteId x)- , id_ (referenceId x) ] $- sup_ (toHtml x)- else old l- _ -> old l+ [x'] ->+ let x = URI.unRText x'+ in if T.all isDigit x+ then+ a_+ [ fragmentHref (footnoteId x),+ id_ (referenceId x)+ ]+ $ sup_ (toHtml x)+ else old l+ _ -> old l else old l other -> old other -- | Create footnote section.- footnoteSection :: Extension footnoteSection = Ext.blockRender $ \old block -> case block of b@(Blockquote [Paragraph (pOis, _), OrderedList i items]) -> if getOis pOis == Plain "footnotes" :| []- then do let startIndex = [start_ (renderIx i) | i /= 1]- renderIx = T.pack . show- ol_ startIndex $ do- newline- forM_ (NE.zip (NE.iterate (+ 1) i) items) $ \(j, x) -> do- let j' = renderIx j- li_ [id_ (footnoteId j')] $ do- newline- mapM_ old x- a_ [fragmentHref (referenceId j')] "↩"- newline+ then do+ let startIndex = [start_ (renderIx i) | i /= 1]+ renderIx = T.pack . show+ ol_ startIndex $ do+ newline+ forM_ (NE.zip (NE.iterate (+ 1) i) items) $ \(j, x) -> do+ let j' = renderIx j+ li_ [id_ (footnoteId j')] $ do newline-+ mapM_ old x+ a_ [fragmentHref (referenceId j')] "↩"+ newline+ newline else old b other -> old other- where- newline = "\n"+ where+ newline = "\n" fragmentHref :: Text -> Attribute fragmentHref = href_ . URI.render . Ext.headerFragment
Text/MMark/Extension/GhcSyntaxHighlighter.hs view
@@ -1,54 +1,30 @@+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-}+ -- | -- Module : Text.MMark.Extension.GhcSyntaxHighlighter--- Copyright : © 2018–2019 Mark Karpov+-- Copyright : © 2018–present Mark Karpov -- License : BSD 3 clause -- -- Maintainer : Mark Karpov <markkarpov92@gmail.com> -- Stability : experimental -- Portability : portable ----- Use the @ghc-syntax-highlighter@ package to highlight Haskell code. This--- module only works with GHC 8.4.1 and newer (with older versions the--- extension just won't have any effect).+-- Use the @ghc-syntax-highlighter@ package to highlight Haskell code. -- -- @since 0.2.1.0--{-# LANGUAGE CPP #-}-{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE OverloadedStrings #-}- module Text.MMark.Extension.GhcSyntaxHighlighter- ( ghcSyntaxHighlighter )+ ( ghcSyntaxHighlighter,+ ) where import Data.Text (Text)+import qualified Data.Text as T+import GHC.SyntaxHighlighter import Lucid-import Text.MMark.Extension (Extension, Block (..))-import qualified Data.Text as T+import Text.MMark.Extension (Block (..), Extension) import qualified Text.MMark.Extension as Ext -#if __GLASGOW_HASKELL__ >= 804-import GHC.SyntaxHighlighter-#else-data Token- = KeywordTok- | PragmaTok- | SymbolTok- | VariableTok- | ConstructorTok- | OperatorTok- | CharTok- | StringTok- | IntegerTok- | RationalTok- | CommentTok- | SpaceTok- | OtherTok- deriving (Eq, Ord, Enum, Bounded, Show)-tokenizeHaskell :: Text -> Maybe [(Token, Text)]-tokenizeHaskell _ = Nothing-#endif- -- | Use the @ghc-syntax-highlighter@ package to highlight Haskell code. The -- extension is applied only to code blocks with info string @\"haskell\"@. --@@ -76,7 +52,6 @@ -- place it on the left hand side of @('<>')@ or above -- 'Text.MMark.Extension.Skylighting.skylighting' in the list passed to -- 'Text.MMark.useExtensions'.- ghcSyntaxHighlighter :: Extension ghcSyntaxHighlighter = Ext.blockRender $ \old block -> case block of@@ -95,7 +70,6 @@ newline = "\n" -- | Render a single 'Token'.- tokenToHtml :: (Token, Text) -> Html () tokenToHtml (tokenType, txt) = span_ [class_ rawClass | not (T.null rawClass)] (toHtml txt)@@ -103,19 +77,18 @@ rawClass = tokenClass tokenType -- | Return class corresponding to given 'TokenType'.- tokenClass :: Token -> Text tokenClass = \case- KeywordTok -> "kw"- PragmaTok -> "pr"- SymbolTok -> "sy"- VariableTok -> "va"+ KeywordTok -> "kw"+ PragmaTok -> "pr"+ SymbolTok -> "sy"+ VariableTok -> "va" ConstructorTok -> "cr"- OperatorTok -> "op"- CharTok -> "ch"- StringTok -> "st"- IntegerTok -> "it"- RationalTok -> "ra"- CommentTok -> "co"- SpaceTok -> ""- OtherTok -> "ot"+ OperatorTok -> "op"+ CharTok -> "ch"+ StringTok -> "st"+ IntegerTok -> "it"+ RationalTok -> "ra"+ CommentTok -> "co"+ SpaceTok -> ""+ OtherTok -> "ot"
Text/MMark/Extension/Kbd.hs view
@@ -1,6 +1,8 @@+{-# LANGUAGE QuasiQuotes #-}+ -- | -- Module : Text.MMark.Extension.Kbd--- Copyright : © 2018 Mark Karpov+-- Copyright : © 2018–present Mark Karpov -- License : BSD 3 clause -- -- Maintainer : Mark Karpov <markkarpov92@gmail.com>@@ -9,18 +11,16 @@ -- -- Introduce @kbd@ tags into resulting HTML document by wrapping content in -- links with URL with @kbd@ scheme.--{-# LANGUAGE QuasiQuotes #-}- module Text.MMark.Extension.Kbd- ( kbd )+ ( kbd,+ ) where import Lucid import Text.MMark.Extension (Extension, Inline (..))-import Text.URI.QQ (scheme) import qualified Text.MMark.Extension as Ext-import qualified Text.URI as URI+import qualified Text.URI as URI+import Text.URI.QQ (scheme) -- | Introduce @kbd@ tags into resulting HTML document by wrapping content -- in links with URL with @kbd@ scheme.@@ -35,7 +35,6 @@ -- author, but you can of course do somethnig like this instead: -- -- > To enable that mode press [Ctrl+A](kbd:).- kbd :: Extension kbd = Ext.inlineRender $ \old inline -> case inline of
Text/MMark/Extension/LinkTarget.hs view
@@ -1,6 +1,9 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TupleSections #-}+ -- | -- Module : Text.MMark.Extension.LinkTarget--- Copyright : © 2018 Mark Karpov+-- Copyright : © 2018–present Mark Karpov -- License : BSD 3 clause -- -- Maintainer : Mark Karpov <markkarpov92@gmail.com>@@ -9,19 +12,16 @@ -- -- Specify the @target@ attribute of links in link titles. This allows, e.g. -- make a link open in new tab.--{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TupleSections #-}- module Text.MMark.Extension.LinkTarget- ( linkTarget )+ ( linkTarget,+ ) where import Data.Foldable (asum) import Data.Maybe (fromMaybe)+import qualified Data.Text as T import Lucid import Text.MMark.Extension (Extension, Inline (..))-import qualified Data.Text as T import qualified Text.MMark.Extension as Ext -- | When title of a link starts with the word @\"_blank\"@, @\"_self\"@,@@ -32,15 +32,16 @@ -- For example: -- -- > This [link](/url '_blank My title') opens in new tab.- linkTarget :: Extension linkTarget = Ext.inlineRender $ \old inline -> case inline of l@(Link txt url (Just title)) -> fromMaybe (old l) $ do- let f prefix = (prefix,) . T.stripStart- <$> T.stripPrefix prefix title- (prefix, title') <- asum $- f <$> ["_blank", "_self", "_parent", "_top"]+ let f prefix =+ (prefix,) . T.stripStart+ <$> T.stripPrefix prefix title+ (prefix, title') <-+ asum $+ f <$> ["_blank", "_self", "_parent", "_top"] let mtitle = if T.null title' then Nothing else Just title' return $ with (old (Link txt url mtitle)) [target_ prefix] other -> old other
Text/MMark/Extension/MathJax.hs view
@@ -1,6 +1,8 @@+{-# LANGUAGE OverloadedStrings #-}+ -- | -- Module : Text.MMark.Extension.MathJax--- Copyright : © 2018 Mark Karpov+-- Copyright : © 2018–present Mark Karpov -- License : BSD 3 clause -- -- Maintainer : Mark Karpov <markkarpov92@gmail.com>@@ -10,19 +12,16 @@ -- Turn code spans and fenced code blocks into MathJax formulas. -- -- @since 0.1.1.0--{-# LANGUAGE OverloadedStrings #-}- module Text.MMark.Extension.MathJax- ( mathJax )+ ( mathJax,+ ) where import Control.Monad-import Data.Semigroup ((<>)) import Data.Text (Text)+import qualified Data.Text as T import Lucid-import Text.MMark.Extension (Extension, Inline (..), Block (..))-import qualified Data.Text as T+import Text.MMark.Extension (Block (..), Extension, Inline (..)) import qualified Text.MMark.Extension as Ext -- | The extension allows to transform inline code spans into MathJax inline@@ -36,16 +35,15 @@ -- 'Nothing' is passed instead of a char, we apply the transformation to all -- code spans (useful for more academic articles that do not deal with -- code).--mathJax- :: Maybe Char -- ^ Starting\/ending character in MathJax inline spans- -> Extension+mathJax ::+ -- | Starting\/ending character in MathJax inline spans+ Maybe Char ->+ Extension mathJax mch = mathJaxSpan mch <> mathJaxBlock -- | Turn code spans that start and end with a given character into MathJax -- inline spans. If 'Nothing' is provided instead of a char, apply the -- transformation to all code spans.- mathJaxSpan :: Maybe Char -> Extension mathJaxSpan mch = Ext.inlineRender $ \old inline -> case inline of@@ -59,21 +57,21 @@ other -> old other where spn :: Text -> Html ()- spn x = span_ [class_ "math inline"] $- "\\(" >> toHtml x >> "\\)"+ spn x =+ span_ [class_ "math inline"] $+ "\\(" >> toHtml x >> "\\)" -- | Turn code blocks with info string @\"mathjax\"@ into MathJax display -- spans.- mathJaxBlock :: Extension mathJaxBlock = Ext.blockRender $ \old block -> case block of b@(CodeBlock mlabel txt) -> if mlabel == Just "mathjax" then do- p_ . forM_ (T.lines txt) $ \x ->- span_ [class_ "math display"] $- "\\[" >> toHtml x >> "\\]"- "\n"+ p_ . forM_ (T.lines txt) $ \x ->+ span_ [class_ "math display"] $+ "\\[" >> toHtml x >> "\\]"+ "\n" else old b other -> old other
Text/MMark/Extension/ObfuscateEmail.hs view
@@ -1,6 +1,9 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE QuasiQuotes #-}+ -- | -- Module : Text.MMark.Extension.ObfuscateEmail--- Copyright : © 2018 Mark Karpov+-- Copyright : © 2018–present Mark Karpov -- License : BSD 3 clause -- -- Maintainer : Mark Karpov <markkarpov92@gmail.com>@@ -8,21 +11,18 @@ -- Portability : portable -- -- Obfuscate email addresses.--{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE QuasiQuotes #-}- module Text.MMark.Extension.ObfuscateEmail- ( obfuscateEmail )+ ( obfuscateEmail,+ ) where import Data.List.NonEmpty (NonEmpty (..)) import Data.Text (Text) import Lucid import Text.MMark.Extension (Extension, Inline (..))-import Text.URI.QQ (scheme, uri) import qualified Text.MMark.Extension as Ext import qualified Text.URI as URI+import Text.URI.QQ (scheme, uri) -- | This extension makes email addresses in autolinks be rendered as -- something like this:@@ -42,20 +42,23 @@ -- > item.html(email); -- > }); -- > });--obfuscateEmail- :: Text- -- ^ Name of class to assign to the links, e.g. @\"protected-email\"@- -> Extension+obfuscateEmail ::+ -- | Name of class to assign to the links, e.g. @\"protected-email\"@+ Text ->+ Extension obfuscateEmail class' = Ext.inlineRender $ \old inline -> case inline of l@(Link _ email mtitle) -> if URI.uriScheme email == Just [scheme|mailto|]- then let txt = Plain "Enable JavaScript to see this email" :| []- js = [uri|javascript:void(0)|]- in with (old (Link txt js mtitle))- [ class_ class'- , data_ "email"- (URI.render email { URI.uriScheme = Nothing }) ]+ then+ let txt = Plain "Enable JavaScript to see this email" :| []+ js = [uri|javascript:void(0)|]+ in with+ (old (Link txt js mtitle))+ [ class_ class',+ data_+ "email"+ (URI.render email {URI.uriScheme = Nothing})+ ] else old l other -> old other
Text/MMark/Extension/PunctuationPrettifier.hs view
@@ -1,6 +1,9 @@+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-}+ -- | -- Module : Text.MMark.Extension.PunctuationPrettifier--- Copyright : © 2018 Mark Karpov+-- Copyright : © 2018–present Mark Karpov -- License : BSD 3 clause -- -- Maintainer : Mark Karpov <markkarpov92@gmail.com>@@ -8,18 +11,15 @@ -- Portability : portable -- -- Punctuation prettifier.--{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE OverloadedStrings #-}- module Text.MMark.Extension.PunctuationPrettifier- ( punctuationPrettifier )+ ( punctuationPrettifier,+ ) where import Data.Char (isSpace) import Data.Text (Text)-import Text.MMark.Extension (Extension, Inline (..)) import qualified Data.Text as T+import Text.MMark.Extension (Extension, Inline (..)) import qualified Text.MMark.Extension as Ext -- | Prettify punctuation (only affects plain text in inlines):@@ -32,31 +32,30 @@ -- * Replace @'@ with left single quote @‘@ when previous character was -- a space character, otherwise replace it with right single quote @’@ -- aka apostrophe- punctuationPrettifier :: Extension punctuationPrettifier = Ext.inlineTrans $ \case Plain txt -> Plain (T.unfoldr gen (True, txt))- other -> other+ other -> other -gen- :: (Bool, Text)- -- ^ Whether the previous character was a space and remaining input- -> Maybe (Char, (Bool, Text))- -- ^ Next generated char and the state+gen ::+ -- | Whether the previous character was a space and remaining input+ (Bool, Text) ->+ -- | Next generated char and the state+ Maybe (Char, (Bool, Text)) gen (s, i) = case T.uncons i of Nothing -> Nothing Just ('.', i') -> case T.splitAt 2 i' of ("..", i'') -> Just ('…', (False, i''))- _ -> Just ('.', (False, i'))+ _ -> Just ('.', (False, i')) Just ('-', i') -> case T.splitAt 2 i' of ("--", i'') -> Just ('—', (False, i'')) _ -> case T.splitAt 1 i' of ("-", i'') -> Just ('–', (False, i''))- _ -> Just ('-', (False, i'))+ _ -> Just ('-', (False, i')) Just ('\"', i') -> if s -- whether previous character was a space character then Just ('“', (False, i'))
Text/MMark/Extension/Skylighting.hs view
@@ -1,6 +1,9 @@+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-}+ -- | -- Module : Text.MMark.Extension.Skylighting--- Copyright : © 2018 Mark Karpov+-- Copyright : © 2018–present Mark Karpov -- License : BSD 3 clause -- -- Maintainer : Mark Karpov <markkarpov92@gmail.com>@@ -8,22 +11,18 @@ -- Portability : portable -- -- Use the Skylighting library to highlight code snippets.--{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE OverloadedStrings #-}- module Text.MMark.Extension.Skylighting- ( skylighting )+ ( skylighting,+ ) where import Control.Monad-import Data.Semigroup ((<>)) import Data.Text (Text)+import qualified Data.Text as T import Lucid import Skylighting (Token, TokenType (..))-import Text.MMark.Extension (Extension, Block (..))-import qualified Data.Text as T-import qualified Skylighting as S+import qualified Skylighting as S+import Text.MMark.Extension (Block (..), Extension) import qualified Text.MMark.Extension as Ext -- | Use the @skylighting@ package to render code blocks with info strings@@ -62,35 +61,36 @@ -- * 'VariableTok' = @\"va\"@ -- * 'VerbatimStringTok' = @\"vs\"@ -- * 'WarningTok' = @\"wa\"@- skylighting :: Extension skylighting = Ext.blockRender $ \old block -> case block of cb@(CodeBlock (Just infoString') txt) ->- let tokenizerConfig = S.TokenizerConfig- { S.syntaxMap = S.defaultSyntaxMap- , S.traceOutput = False }+ let tokenizerConfig =+ S.TokenizerConfig+ { S.syntaxMap = S.defaultSyntaxMap,+ S.traceOutput = False+ } infoString = T.replace "-" " " infoString'- in case S.lookupSyntax infoString S.defaultSyntaxMap of- Nothing -> old cb- Just syntax ->- case S.tokenize tokenizerConfig syntax txt of- Left _ -> old cb- Right ls -> do- div_ [class_ "source-code"]- . pre_- . code_ [class_ ("language-" <> infoString)]- . forM_ ls $ \l -> do- mapM_ tokenToHtml l- newline- newline+ in case S.lookupSyntax infoString S.defaultSyntaxMap of+ Nothing -> old cb+ Just syntax ->+ case S.tokenize tokenizerConfig syntax txt of+ Left _ -> old cb+ Right ls -> do+ div_ [class_ "source-code"]+ . pre_+ . code_ [class_ ("language-" <> infoString)]+ . forM_ ls+ $ \l -> do+ mapM_ tokenToHtml l+ newline+ newline other -> old other where newline :: Html () newline = "\n" -- | Render a single 'Token'.- tokenToHtml :: Token -> Html () tokenToHtml (tokenType, txt) = span_ [class_ rawClass | not (T.null rawClass)] (toHtml txt)@@ -98,37 +98,36 @@ rawClass = tokenClass tokenType -- | Return class corresponding to given 'TokenType'.- tokenClass :: TokenType -> Text tokenClass = \case- KeywordTok -> "kw"- DataTypeTok -> "dt"- DecValTok -> "dv"- BaseNTok -> "bn"- FloatTok -> "fl"- CharTok -> "ch"- StringTok -> "st"- CommentTok -> "co"- OtherTok -> "ot"- AlertTok -> "al"- FunctionTok -> "fu"- RegionMarkerTok -> "re"- ErrorTok -> "er"- ConstantTok -> "cn"- SpecialCharTok -> "sc"+ KeywordTok -> "kw"+ DataTypeTok -> "dt"+ DecValTok -> "dv"+ BaseNTok -> "bn"+ FloatTok -> "fl"+ CharTok -> "ch"+ StringTok -> "st"+ CommentTok -> "co"+ OtherTok -> "ot"+ AlertTok -> "al"+ FunctionTok -> "fu"+ RegionMarkerTok -> "re"+ ErrorTok -> "er"+ ConstantTok -> "cn"+ SpecialCharTok -> "sc" VerbatimStringTok -> "vs"- SpecialStringTok -> "ss"- ImportTok -> "im"- DocumentationTok -> "do"- AnnotationTok -> "an"- CommentVarTok -> "cv"- VariableTok -> "va"- ControlFlowTok -> "cf"- OperatorTok -> "op"- BuiltInTok -> "bu"- ExtensionTok -> "ex"- PreprocessorTok -> "pp"- AttributeTok -> "at"- InformationTok -> "in"- WarningTok -> "wa"- NormalTok -> ""+ SpecialStringTok -> "ss"+ ImportTok -> "im"+ DocumentationTok -> "do"+ AnnotationTok -> "an"+ CommentVarTok -> "cv"+ VariableTok -> "va"+ ControlFlowTok -> "cf"+ OperatorTok -> "op"+ BuiltInTok -> "bu"+ ExtensionTok -> "ex"+ PreprocessorTok -> "pp"+ AttributeTok -> "at"+ InformationTok -> "in"+ WarningTok -> "wa"+ NormalTok -> ""
Text/MMark/Extension/TableOfContents.hs view
@@ -1,6 +1,8 @@+{-# LANGUAGE LambdaCase #-}+ -- | -- Module : Text.MMark.Extension.TableOfContents--- Copyright : © 2017–2018 Mark Karpov+-- Copyright : © 2017–present Mark Karpov -- License : BSD 3 clause -- -- Maintainer : Mark Karpov <markkarpov92@gmail.com>@@ -15,35 +17,31 @@ -- -- You may use something different than @\"toc\"@ as the info string of the -- code block.--{-# LANGUAGE LambdaCase #-}- module Text.MMark.Extension.TableOfContents- ( Toc- , tocScanner- , toc )+ ( Toc,+ tocScanner,+ toc,+ ) where +import qualified Control.Foldl as L import Data.List.NonEmpty (NonEmpty (..))+import qualified Data.List.NonEmpty as NE import Data.Maybe (maybeToList) import Data.Text (Text)-import Text.MMark.Extension (Extension, Block (..), Inline (..), Bni)-import qualified Control.Foldl as L-import qualified Data.List.NonEmpty as NE+import Text.MMark.Extension (Block (..), Bni, Extension, Inline (..)) import qualified Text.MMark.Extension as Ext -- | An opaque type representing table of contents produced by the -- 'tocScanner' scanner.- newtype Toc = Toc [(Int, NonEmpty Inline)] -- | The scanner builds table of contents 'Toc' that can then be passed to -- 'toc' to obtain an extension that renders the table of contents in HTML.--tocScanner- :: (Int -> Bool)- -- ^ Whether to include a header of this level (1–6)- -> L.Fold Bni Toc+tocScanner ::+ -- | Whether to include a header of this level (1–6)+ (Int -> Bool) ->+ L.Fold Bni Toc tocScanner p = fmap (Toc . ($ [])) . Ext.scanner id $ \xs block -> case block of Heading1 x -> f 1 x xs@@ -52,20 +50,21 @@ Heading4 x -> f 4 x xs Heading5 x -> f 5 x xs Heading6 x -> f 6 x xs- _ -> xs+ _ -> xs where f n a as = if p n- then as . ((n, a):)+ then as . ((n, a) :) else as -- | Create an extension that replaces a certain code block with previously -- constructed table of contents.--toc- :: Text -- ^ Label of the code block to replace by the table of contents- -> Toc -- ^ Previously generated by 'tocScanner'- -> Extension+toc ::+ -- | Label of the code block to replace by the table of contents+ Text ->+ -- | Previously generated by 'tocScanner'+ Toc ->+ Extension toc label (Toc xs) = Ext.blockTrans $ \case old@(CodeBlock mlabel _) -> case NE.nonEmpty xs of@@ -78,13 +77,13 @@ -- | Construct 'Bni' for a table of contents from given collection of -- headers. This is a non-public helper.- renderToc :: NonEmpty (Int, NonEmpty Inline) -> Bni renderToc = UnorderedList . NE.unfoldr f where- f ((n,x) :| xs) =+ f ((n, x) :| xs) = let (sitems, fitems) = span ((> n) . fst) xs url = Ext.headerFragment (Ext.headerId x)- in ( Naked (Link x url Nothing :| [])- : maybeToList (renderToc <$> NE.nonEmpty sitems)- , NE.nonEmpty fitems )+ in ( Naked (Link x url Nothing :| []) :+ maybeToList (renderToc <$> NE.nonEmpty sitems),+ NE.nonEmpty fitems+ )
data/toc.html view
@@ -9,7 +9,7 @@ Vestibulum nec ornare leo. Cras pharetra, ex sed dapibus pretium, diam lectus accumsan enim, at malesuada tellus lorem et orci. Sed condimentum varius ex in mollis.</p>-<p><a href="https://example.org/">https://example.org/</a></p>+<p><a href="https://example.org">https://example.org</a></p> <p>Ut in imperdiet neque. Etiam iaculis rhoncus nisl vel porta. Praesent velit orci, laoreet suscipit bibendum eu, ornare et orci. Fusce feugiat, felis a vehicula pulvinar, nulla purus dictum arcu, et varius urna purus et nibh.@@ -57,7 +57,7 @@ risus. Maecenas vehicula, leo vitae semper tristique, libero urna consectetur massa, eget pharetra magna est nec massa. Vestibulum malesuada lobortis lacinia.</p>-<p><img src="https://example.org/image.png" alt="My image"></p>+<p><img alt="My image" src="https://example.org/image.png"></p> <p>Phasellus tincidunt metus quam, vel mollis turpis ultrices et. Phasellus consequat diam eu turpis sollicitudin tempus. Fusce suscipit bibendum nisl, quis rutrum eros volutpat in. Fusce tempor nisi eu ligula volutpat, eu
mmark-ext.cabal view
@@ -1,94 +1,103 @@-name: mmark-ext-version: 0.2.1.2-cabal-version: 1.18-tested-with: GHC==8.0.2, GHC==8.2.2, GHC==8.4.4, GHC==8.6.3-license: BSD3-license-file: LICENSE.md-author: Mark Karpov <markkarpov92@gmail.com>-maintainer: Mark Karpov <markkarpov92@gmail.com>-homepage: https://github.com/mmark-md/mmark-ext-bug-reports: https://github.com/mmark-md/mmark-ext/issues-category: Text-synopsis: Commonly useful extensions for the MMark markdown processor-build-type: Simple+cabal-version: 1.18+name: mmark-ext+version: 0.2.1.3+license: BSD3+license-file: LICENSE.md+maintainer: Mark Karpov <markkarpov92@gmail.com>+author: Mark Karpov <markkarpov92@gmail.com>+tested-with: ghc ==8.8.4 ghc ==8.10.4 ghc ==9.0.1+homepage: https://github.com/mmark-md/mmark-ext+bug-reports: https://github.com/mmark-md/mmark-ext/issues+synopsis: Commonly useful extensions for the MMark markdown processor description:+ Commonly useful extensions for the MMark markdown processor. Click on+ "Text.MMark.Extension.Common" to get started. - Commonly useful extensions for the MMark markdown processor. Click on- "Text.MMark.Extension.Common" to get started.+category: Text+build-type: Simple+data-files:+ data/*.md+ data/*.html -extra-doc-files: CHANGELOG.md- , README.md-data-files: data/*.md- , data/*.html+extra-doc-files:+ CHANGELOG.md+ README.md source-repository head- type: git- location: https://github.com/mmark-md/mmark-ext.git+ type: git+ location: https://github.com/mmark-md/mmark-ext.git flag dev- description: Turn on development settings.- manual: True- default: False+ description: Turn on development settings.+ default: False+ manual: True library- build-depends: base >= 4.9 && < 5.0- , foldl >= 1.2 && < 1.5- , lucid >= 2.6 && < 3.0- , microlens >= 0.4 && < 0.5- , mmark >= 0.0.4 && <= 0.1- , modern-uri >= 0.2 && < 0.4- , skylighting >= 0.5 && < 0.8- , text >= 0.2 && < 1.3- if impl(ghc >= 8.4)- build-depends: ghc-syntax-highlighter >= 0.0.1 && < 0.1- exposed-modules: Text.MMark.Extension.Common- , Text.MMark.Extension.Comment- , Text.MMark.Extension.FontAwesome- , Text.MMark.Extension.Footnotes- , Text.MMark.Extension.GhcSyntaxHighlighter- , Text.MMark.Extension.Kbd- , Text.MMark.Extension.LinkTarget- , Text.MMark.Extension.MathJax- , Text.MMark.Extension.ObfuscateEmail- , Text.MMark.Extension.PunctuationPrettifier- , Text.MMark.Extension.Skylighting- , Text.MMark.Extension.TableOfContents- if flag(dev)- ghc-options: -O0 -Wall -Werror -Wcompat- -Wincomplete-record-updates- -Wincomplete-uni-patterns- -Wnoncanonical-monad-instances- -Wnoncanonical-monadfail-instances- else- ghc-options: -O2 -Wall- default-language: Haskell2010+ exposed-modules:+ Text.MMark.Extension.Common+ Text.MMark.Extension.Comment+ Text.MMark.Extension.FontAwesome+ Text.MMark.Extension.Footnotes+ Text.MMark.Extension.GhcSyntaxHighlighter+ Text.MMark.Extension.Kbd+ Text.MMark.Extension.LinkTarget+ Text.MMark.Extension.MathJax+ Text.MMark.Extension.ObfuscateEmail+ Text.MMark.Extension.PunctuationPrettifier+ Text.MMark.Extension.Skylighting+ Text.MMark.Extension.TableOfContents + default-language: Haskell2010+ build-depends:+ base >=4.13 && <5.0,+ foldl >=1.2 && <1.5,+ ghc-syntax-highlighter >=0.0.1 && <0.1,+ lucid >=2.6 && <3.0,+ microlens >=0.4 && <0.5,+ mmark >=0.0.4 && <=0.1,+ modern-uri >=0.3.4 && <0.4,+ skylighting >=0.7.6 && <0.11,+ text >=0.2 && <1.3++ if flag(dev)+ ghc-options:+ -O0 -Wall -Werror -Wcompat -Wincomplete-record-updates+ -Wincomplete-uni-patterns -Wnoncanonical-monad-instances++ else+ ghc-options: -O2 -Wall+ test-suite tests- main-is: Spec.hs- hs-source-dirs: tests- type: exitcode-stdio-1.0- build-depends: base >= 4.9 && < 5.0- , hspec >= 2.0 && < 3.0- , lucid >= 2.6 && < 3.0- , mmark >= 0.0.4 && <= 0.1- , mmark-ext- , skylighting >= 0.5 && < 0.8- , text >= 0.2 && < 1.3- build-tools: hspec-discover >= 2.0 && < 3.0- if flag(dev)- ghc-options: -O0 -Wall -Werror- else- ghc-options: -O2 -Wall- other-modules: Text.MMark.Extension.CommentSpec- , Text.MMark.Extension.FontAwesomeSpec- , Text.MMark.Extension.FootnotesSpec- , Text.MMark.Extension.GhcSyntaxHighlighterSpec- , Text.MMark.Extension.KbdSpec- , Text.MMark.Extension.LinkTargetSpec- , Text.MMark.Extension.MathJaxSpec- , Text.MMark.Extension.ObfuscateEmailSpec- , Text.MMark.Extension.PunctuationPrettifierSpec- , Text.MMark.Extension.SkylightingSpec- , Text.MMark.Extension.TableOfContentsSpec- , Text.MMark.Extension.TestUtils- default-language: Haskell2010+ type: exitcode-stdio-1.0+ main-is: Spec.hs+ build-tools: hspec-discover >=2.0 && <3.0+ hs-source-dirs: tests+ other-modules:+ Text.MMark.Extension.CommentSpec+ Text.MMark.Extension.FontAwesomeSpec+ Text.MMark.Extension.FootnotesSpec+ Text.MMark.Extension.GhcSyntaxHighlighterSpec+ Text.MMark.Extension.KbdSpec+ Text.MMark.Extension.LinkTargetSpec+ Text.MMark.Extension.MathJaxSpec+ Text.MMark.Extension.ObfuscateEmailSpec+ Text.MMark.Extension.PunctuationPrettifierSpec+ Text.MMark.Extension.SkylightingSpec+ Text.MMark.Extension.TableOfContentsSpec+ Text.MMark.Extension.TestUtils++ default-language: Haskell2010+ build-depends:+ base >=4.13 && <5.0,+ hspec >=2.0 && <3.0,+ lucid >=2.6 && <3.0,+ mmark >=0.0.4 && <=0.1,+ mmark-ext,+ skylighting >=0.7.6 && <0.11,+ text >=0.2 && <1.3++ if flag(dev)+ ghc-options: -O0 -Wall -Werror++ else+ ghc-options: -O2 -Wall
tests/Text/MMark/Extension/FontAwesomeSpec.hs view
@@ -18,7 +18,7 @@ "<fa:quote-left/3x/pull-left/border>" `to` "<p><span class=\"fa fa-quote-left fa-3x fa-pull-left fa-border\"></span></p>\n" context "when URI has some other scheme" $ it "produces the correct HTML" $- "<https://example.org>" `to` "<p><a href=\"https://example.org/\">https://example.org/</a></p>\n"+ "<https://example.org>" `to` "<p><a href=\"https://example.org\">https://example.org</a></p>\n" context "other elements" $ it "not affected" $ "Something." `to` "<p>Something.</p>\n"
tests/Text/MMark/Extension/FootnotesSpec.hs view
@@ -12,21 +12,21 @@ let to = withExt footnotes context "when link has no scheme" $ it "has no effect" $- "Link [link](1)." `to`- "<p>Link <a href=\"1\">link</a>.</p>\n"+ "Link [link](1)."+ `to` "<p>Link <a href=\"1\">link</a>.</p>\n" context "when link has not \"footnote\" scheme" $ it "has no effect" $- "Link [link](https:1)" `to`- "<p>Link <a href=\"https:1\">link</a></p>\n"+ "Link [link](https:1)"+ `to` "<p>Link <a href=\"https:1\">link</a></p>\n" context "when link has \"footnote\" scheme" $ it "transforms the link correctly" $- "Link [link](footnote:1)" `to`- "<p>Link <a href=\"#fn1\" id=\"fnref1\"><sup>1</sup></a></p>\n"+ "Link [link](footnote:1)"+ `to` "<p>Link <a href=\"#fn1\" id=\"fnref1\"><sup>1</sup></a></p>\n" context "when block quotes are not formatted correctly" $ it "has no effect" $- "> blah" `to`- "<blockquote>\n<p>blah</p>\n</blockquote>\n"+ "> blah"+ `to` "<blockquote>\n<p>blah</p>\n</blockquote>\n" context "when block quotes are formatted correctly" $ it "transforms them into footnotes" $- "> footnotes\n\n 1. Something.\n" `to`- "<ol>\n<li id=\"fn1\">\nSomething.\n<a href=\"#fnref1\">↩</a></li>\n</ol>\n"+ "> footnotes\n\n 1. Something.\n"+ `to` "<ol>\n<li id=\"fn1\">\nSomething.\n<a href=\"#fnref1\">↩</a></li>\n</ol>\n"
tests/Text/MMark/Extension/GhcSyntaxHighlighterSpec.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} module Text.MMark.Extension.GhcSyntaxHighlighterSpec (spec) where@@ -11,13 +10,7 @@ spec = describe "ghcSyntaxHighlighter" $ do let to = withExt ghcSyntaxHighlighter- context "when info string is not \"haskell\"" $- it "has no effect" $- "```foo\nmain :: IO ()\nmain = return ()\n```\n" `to`- "<pre><code class=\"language-foo\">main :: IO ()\nmain = return ()\n</code></pre>\n"-#if __GLASGOW_HASKELL__ >= 804 context "with info string is \"haskell\"" $ it "renders it correctly" $- "```haskell\nmain :: IO ()\nmain = return ()\n```\n" `to`- "<div class=\"source-code\"><pre><code class=\"language-haskell\"><span class=\"va\">main</span><span> </span><span class=\"sy\">::</span><span> </span><span class=\"cr\">IO</span><span> </span><span class=\"sy\">(</span><span class=\"sy\">)</span><span>\n</span><span class=\"va\">main</span><span> </span><span class=\"sy\">=</span><span> </span><span class=\"va\">return</span><span> </span><span class=\"sy\">(</span><span class=\"sy\">)</span><span>\n</span></code></pre></div>\n"-#endif+ "```haskell\nmain :: IO ()\nmain = return ()\n```\n"+ `to` "<div class=\"source-code\"><pre><code class=\"language-haskell\"><span class=\"va\">main</span><span> </span><span class=\"sy\">::</span><span> </span><span class=\"cr\">IO</span><span> </span><span class=\"sy\">(</span><span class=\"sy\">)</span><span>\n</span><span class=\"va\">main</span><span> </span><span class=\"sy\">=</span><span> </span><span class=\"va\">return</span><span> </span><span class=\"sy\">(</span><span class=\"sy\">)</span><span>\n</span></code></pre></div>\n"
tests/Text/MMark/Extension/LinkTargetSpec.hs view
@@ -15,14 +15,14 @@ "[link](/url)" `to` "<p><a href=\"/url\">link</a></p>\n" context "when link title does not start with a target" $ it "has no effect" $- "[link](/url 'something _blank')" `to`- "<p><a href=\"/url\" title=\"something _blank\">link</a></p>\n"+ "[link](/url 'something _blank')"+ `to` "<p><a href=\"/url\" title=\"something _blank\">link</a></p>\n" context "when link title starts with a target" $ do context "when there is nothing but the target in title" $ it "works as intended, no title attribute produced" $- "[link](/url '_blank')" `to`- "<p><a href=\"/url\" target=\"_blank\">link</a></p>\n"+ "[link](/url '_blank')"+ `to` "<p><a href=\"/url\" target=\"_blank\">link</a></p>\n" context "when there is also a title" $ it "works as intended, target is stripped from the title" $- "[link](/url '_blank something')" `to`- "<p><a href=\"/url\" title=\"something\" target=\"_blank\">link</a></p>\n"+ "[link](/url '_blank something')"+ `to` "<p><a href=\"/url\" title=\"something\" target=\"_blank\">link</a></p>\n"
tests/Text/MMark/Extension/MathJaxSpec.hs view
@@ -9,29 +9,29 @@ spec :: Spec spec = describe "mathJax" $ do- let to = withExt (mathJax Nothing)+ let to = withExt (mathJax Nothing) to' = withExt (mathJax (Just '$')) context "when span char is not specified" $ it "transforms all code spans correctly" $- "I've got `foo`." `to`- "<p>I've got <span class=\"math inline\">\\(foo\\)</span>.</p>\n"+ "I've got `foo`."+ `to` "<p>I've got <span class=\"math inline\">\\(foo\\)</span>.</p>\n" context "when span char is specified" $ do it "does not affect mismatching code spans" $- "I've got `foo`." `to'`- "<p>I've got <code>foo</code>.</p>\n"+ "I've got `foo`."+ `to'` "<p>I've got <code>foo</code>.</p>\n" it "transforms matching code spans correctly" $- "I've got `$foo$`." `to'`- "<p>I've got <span class=\"math inline\">\\(foo\\)</span>.</p>\n"+ "I've got `$foo$`."+ `to'` "<p>I've got <span class=\"math inline\">\\(foo\\)</span>.</p>\n" context "when code block is not labelled with \"mathjax\"" $ it "does not affect it" $- "```\nfoo\n```\n" `to`- "<pre><code>foo\n</code></pre>\n"+ "```\nfoo\n```\n"+ `to` "<pre><code>foo\n</code></pre>\n" context "when code block is labelled with \"mathjax\"" $ do context "when code block contains a single line" $ it "renders it correctly" $- "```mathjax\nfoo\n```\n" `to`- "<p><span class=\"math display\">\\[foo\\]</span></p>\n"+ "```mathjax\nfoo\n```\n"+ `to` "<p><span class=\"math display\">\\[foo\\]</span></p>\n" context "when code block contains multiple lines" $ it "renders it correctly" $- "```mathjax\nfoo\nbar\n```\n" `to`- "<p><span class=\"math display\">\\[foo\\]</span><span class=\"math display\">\\[bar\\]</span></p>\n"+ "```mathjax\nfoo\nbar\n```\n"+ `to` "<p><span class=\"math display\">\\[foo\\]</span><span class=\"math display\">\\[bar\\]</span></p>\n"
tests/Text/MMark/Extension/ObfuscateEmailSpec.hs view
@@ -12,7 +12,7 @@ let to = withExt (obfuscateEmail "foo") context "when URI has the mailto scheme" $ it "produces the correct HTML" $- "<mailto:me@example.org>" `to` "<p><a href=\"javascript:void(0)\" class=\"foo\" data-email=\"me@example.org\">Enable JavaScript to see this email</a></p>\n"+ "<mailto:me@example.org>" `to` "<p><a href=\"javascript:void(0)\" data-email=\"me@example.org\" class=\"foo\">Enable JavaScript to see this email</a></p>\n" context "when URI has some other scheme" $ it "produces the correct HTML" $ "<https:example.org>" `to` "<p><a href=\"https:example.org\">https:example.org</a></p>\n"
tests/Text/MMark/Extension/PunctuationPrettifierSpec.hs view
@@ -11,26 +11,26 @@ describe "punctuationPrettifier" $ do let to = withExt punctuationPrettifier context "on plain inlines" $ do- it "replaces ... with ellipsis" $- "He forgot where he came from..." `to` "<p>He forgot where he came from…</p>\n"- it "replaces --- with em dash" $- "Here we go---at last." `to` "<p>Here we go—at last.</p>\n"- it "replaces -- with en dash" $- "Here we go -- at last." `to` "<p>Here we go – at last.</p>\n"- it "replaces double quotes intelligently" $- "\"Something\"" `to` "<p>“Something”</p>\n"- it "replaces double quotes intelligently (empty)" $- "\"\"" `to` "<p>“”</p>\n"- it "replaces single quotes intelligently" $ do- "'Something'" `to` "<p>‘Something’</p>\n"- "I'm doin' well, 'cause I care 'bout 'Big Jim'."- `to` "<p>I’m doin’ well, ‘cause I care ‘bout ‘Big Jim’.</p>\n"- it "replaces single quotes intelligently (empty)" $- "''" `to` "<p>‘’</p>\n"- it "a tricky test 1" $- "Something-\"foo\"." `to` "<p>Something-”foo”.</p>\n"- it "a tricky test 2" $- "Something.--" `to` "<p>Something.–</p>\n"+ it "replaces ... with ellipsis" $+ "He forgot where he came from..." `to` "<p>He forgot where he came from…</p>\n"+ it "replaces --- with em dash" $+ "Here we go---at last." `to` "<p>Here we go—at last.</p>\n"+ it "replaces -- with en dash" $+ "Here we go -- at last." `to` "<p>Here we go – at last.</p>\n"+ it "replaces double quotes intelligently" $+ "\"Something\"" `to` "<p>“Something”</p>\n"+ it "replaces double quotes intelligently (empty)" $+ "\"\"" `to` "<p>“”</p>\n"+ it "replaces single quotes intelligently" $ do+ "'Something'" `to` "<p>‘Something’</p>\n"+ "I'm doin' well, 'cause I care 'bout 'Big Jim'."+ `to` "<p>I’m doin’ well, ‘cause I care ‘bout ‘Big Jim’.</p>\n"+ it "replaces single quotes intelligently (empty)" $+ "''" `to` "<p>‘’</p>\n"+ it "a tricky test 1" $+ "Something-\"foo\"." `to` "<p>Something-”foo”.</p>\n"+ it "a tricky test 2" $+ "Something.--" `to` "<p>Something.–</p>\n" context "on other inlines" $ it "has no effect" $ "`code -- span`" `to` "<p><code>code -- span</code></p>\n"
tests/Text/MMark/Extension/SkylightingSpec.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} module Text.MMark.Extension.SkylightingSpec (spec) where@@ -13,18 +12,9 @@ let to = withExt skylighting context "when info string does not result in a successful lookup" $ it "has no effect" $- "```foo\nmain :: IO ()\nmain = return ()\n```\n" `to`- "<pre><code class=\"language-foo\">main :: IO ()\nmain = return ()\n</code></pre>\n"+ "```foo\nmain :: IO ()\nmain = return ()\n```\n"+ `to` "<pre><code class=\"language-foo\">main :: IO ()\nmain = return ()\n</code></pre>\n" context "with info string results in a successful lookup" $ it "renders it correctly" $- "```haskell\nmain :: IO ()\nmain = return ()\n```\n" `to`-#if MIN_VERSION_skylighting(0,7,6)- -- version 0.7.6 and later- "<div class=\"source-code\"><pre><code class=\"language-haskell\"><span class=\"ot\">main ::</span><span> </span><span class=\"dt\">IO</span><span> ()</span>\n<span>main </span><span class=\"ot\">=</span><span> </span><span class=\"fu\">return</span><span> ()</span>\n</code></pre></div>\n"-#elif MIN_VERSION_skylighting(0,7,4)- -- versions 0.7.4 and 0.7.5- "<div class=\"source-code\"><pre><code class=\"language-haskell\"><span class=\"ot\">main ::</span><span> </span><span class=\"dt\">IO</span><span> ()</span>\n<span>main </span><span class=\"fu\">=</span><span> </span><span class=\"fu\">return</span><span> ()</span>\n</code></pre></div>\n"-#else- -- versions older than 0.7.4- "<div class=\"source-code\"><pre><code class=\"language-haskell\"><span class=\"ot\">main ::</span><span> </span><span class=\"dt\">IO</span><span> ()</span>\n<span>main </span><span class=\"fu\">=</span><span> return ()</span>\n</code></pre></div>\n"-#endif+ "```haskell\nmain :: IO ()\nmain = return ()\n```\n"+ `to` "<div class=\"source-code\"><pre><code class=\"language-haskell\"><span class=\"ot\">main ::</span><span> </span><span class=\"dt\">IO</span><span> ()</span>\n<span>main </span><span class=\"ot\">=</span><span> </span><span class=\"fu\">return</span><span> ()</span>\n</code></pre></div>\n"
tests/Text/MMark/Extension/TableOfContentsSpec.hs view
@@ -2,24 +2,25 @@ module Text.MMark.Extension.TableOfContentsSpec (spec) where +import qualified Data.Text.IO as TIO+import qualified Data.Text.Lazy as TL+import qualified Lucid as L import Test.Hspec+import qualified Text.MMark as MMark import Text.MMark.Extension.TableOfContents-import qualified Data.Text.IO as TIO-import qualified Data.Text.Lazy as TL-import qualified Lucid as L-import qualified Text.MMark as MMark spec :: Spec spec = describe "toc" $ it "works" $ do- input <- TIO.readFile "data/toc.md"+ input <- TIO.readFile "data/toc.md" expected <- TIO.readFile "data/toc.html" let Right doc = MMark.parse "" input- headings = MMark.runScanner doc (tocScanner (> 1))- actual = TL.toStrict- . L.renderText- . MMark.render- . MMark.useExtension (toc "toc" headings)- $ doc+ headings = MMark.runScanner doc (tocScanner (> 1))+ actual =+ TL.toStrict+ . L.renderText+ . MMark.render+ . MMark.useExtension (toc "toc" headings)+ $ doc actual `shouldBe` expected
tests/Text/MMark/Extension/TestUtils.hs view
@@ -1,26 +1,30 @@ module Text.MMark.Extension.TestUtils- ( withExt )+ ( withExt,+ ) where import Data.Text (Text)-import Test.Hspec import qualified Data.Text.Lazy as TL-import qualified Lucid as L-import qualified Text.MMark as MMark+import qualified Lucid as L+import Test.Hspec+import qualified Text.MMark as MMark -- | Feed input into MMark parser, apply an extension, render the parsed -- document and demand that it matches the given example.--withExt- :: MMark.Extension -- ^ MMark extension to use- -> Text -- ^ Input for the parser- -> Text -- ^ Expected output of the render- -> Expectation+withExt ::+ -- | MMark extension to use+ MMark.Extension ->+ -- | Input for the parser+ Text ->+ -- | Expected output of the render+ Text ->+ Expectation withExt ext input expected = do let Right doc = MMark.parse "" input- actual = TL.toStrict- . L.renderText- . MMark.render- . MMark.useExtension ext- $ doc+ actual =+ TL.toStrict+ . L.renderText+ . MMark.render+ . MMark.useExtension ext+ $ doc actual `shouldBe` expected