mmark-ext 0.1.1.0 → 0.2.0.0
raw patch · 5 files changed
+125/−15 lines, 5 filesdep −blaze-htmldep ~foldldep ~skylightingPVP ok
version bump matches the API change (PVP)
Dependencies removed: blaze-html
Dependency ranges changed: foldl, skylighting
API changes (from Hackage documentation)
- Text.MMark.Extension.Skylighting: skylighting :: FormatOptions -> Extension
+ Text.MMark.Extension.Skylighting: skylighting :: Extension
Files
- CHANGELOG.md +6/−0
- Text/MMark/Extension/Common.hs +1/−2
- Text/MMark/Extension/Skylighting.hs +96/−11
- mmark-ext.cabal +2/−2
- tests/Text/MMark/Extension/SkylightingSpec.hs +20/−0
CHANGELOG.md view
@@ -1,3 +1,9 @@+## MMark Ext 0.2.0.0++* The `skylighting` extension no longer accepts any arguments. Skylighting+ built-in facilities for rendering to HTML are not acceptable as they+ produce invalid HTML (with duplicate ids), so they were re-implemented.+ ## MMark Ext 0.1.1.0 * Added the `Text.MMark.Extension.MathJax` module.
Text/MMark/Extension/Common.hs view
@@ -20,7 +20,6 @@ -- > -- > module Main (main) where -- >--- > import Skylighting (defaultFormatOpts) -- > import qualified Data.Text.IO as T -- > import qualified Data.Text.Lazy.IO as TL -- > import qualified Lucid as L@@ -41,7 +40,7 @@ -- > . MMark.useExtensions -- > [ Ext.toc "toc" toc -- > , Ext.punctuationPrettifier--- > , Ext.skylighting defaultFormatOpts ]+-- > , Ext.skylighting ] -- > $ r module Text.MMark.Extension.Common
Text/MMark/Extension/Skylighting.hs view
@@ -9,14 +9,18 @@ -- -- Use the Skylighting library to highlight code snippets. +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} module Text.MMark.Extension.Skylighting ( skylighting ) where -import Lucid (toHtmlRaw)-import Text.Blaze.Html.Renderer.Text+import Control.Monad+import Data.Semigroup ((<>))+import Data.Text (Text)+import Lucid+import Skylighting (Token, TokenType (..)) import Text.MMark.Extension (Extension, Block (..)) import qualified Data.Text as T import qualified Skylighting as S@@ -25,13 +29,42 @@ -- | Use the @skylighting@ package to render code blocks with info strings -- that result in a successful lookup from 'S.defaultSyntaxMap'. ----- The resulting markup is wrapped with spans as described in the docs for--- 'S.formatHtmlInline'.+-- The resulting code block will be wrapped in a @div@ with class+-- @\"source-code\"@. The following @span@ classes can be used for styling:+--+-- * 'AlertTok' = @\"al\"@+-- * 'AnnotationTok' = @\"an\"@+-- * 'AttributeTok' = @\"at\"@+-- * 'BaseNTok' = @\"bn\"@+-- * 'BuiltInTok' = @\"bu\"@+-- * 'CharTok' = @\"ch\"@+-- * 'CommentTok' = @\"co\"@+-- * 'CommentVarTok' = @\"cv\"@+-- * 'ConstantTok' = @\"cn\"@+-- * 'ControlFlowTok' = @\"cf\"@+-- * 'DataTypeTok' = @\"dt\"@+-- * 'DecValTok' = @\"dv\"@+-- * 'DocumentationTok' = @\"do\"@+-- * 'ErrorTok' = @\"er\"@+-- * 'ExtensionTok' = @\"ex\"@+-- * 'FloatTok' = @\"fl\"@+-- * 'FunctionTok' = @\"fu\"@+-- * 'ImportTok' = @\"im\"@+-- * 'InformationTok' = @\"in\"@+-- * 'KeywordTok' = @\"kw\"@+-- * 'OperatorTok' = @\"op\"@+-- * 'OtherTok' = @\"ot\"@+-- * 'PreprocessorTok' = @\"pp\"@+-- * 'RegionMarkerTok' = @\"re\"@+-- * 'SpecialCharTok' = @\"sc\"@+-- * 'SpecialStringTok' = @\"ss\"@+-- * 'StringTok' = @\"st\"@+-- * 'VariableTok' = @\"va\"@+-- * 'VerbatimStringTok' = @\"vs\"@+-- * 'WarningTok' = @\"wa\"@ -skylighting- :: S.FormatOptions -- ^ Skylighting formatting options- -> Extension-skylighting fmtOpts = Ext.blockRender $ \old block ->+skylighting :: Extension+skylighting = Ext.blockRender $ \old block -> case block of cb@(CodeBlock (Just infoString') txt) -> let tokenizerConfig = S.TokenizerConfig@@ -43,7 +76,59 @@ Just syntax -> case S.tokenize tokenizerConfig syntax txt of Left _ -> old cb- Right sourceLines -> do- toHtmlRaw . renderHtml $ S.formatHtmlBlock fmtOpts sourceLines- "\n"+ 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)+ where+ 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"+ 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 -> ""
mmark-ext.cabal view
@@ -1,5 +1,5 @@ name: mmark-ext-version: 0.1.1.0+version: 0.2.0.0 cabal-version: >= 1.18 tested-with: GHC==8.0.2, GHC==8.2.2 license: BSD3@@ -32,7 +32,6 @@ library build-depends: base >= 4.9 && < 5.0- , blaze-html >= 0.9 && < 0.10 , foldl >= 1.2 && < 1.4 , lucid >= 2.6 && < 3.0 , microlens >= 0.4 && < 0.5@@ -81,6 +80,7 @@ , 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
+ tests/Text/MMark/Extension/SkylightingSpec.hs view
@@ -0,0 +1,20 @@+{-# LANGUAGE OverloadedStrings #-}++module Text.MMark.Extension.SkylightingSpec (spec) where++import Test.Hspec+import Text.MMark.Extension.Skylighting+import Text.MMark.Extension.TestUtils++spec :: Spec+spec =+ describe "skylighting" $ do+ 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"+ context "with info string results in a successful lookup" $+ it "renders it correctly" $+ "```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=\"fu\">=</span><span> return ()</span>\n</code></pre></div>\n"