{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ViewPatterns      #-}
{- |
   Module      : Text.Pandoc.Readers.CommonMark
   Copyright   : Copyright (C) 2015-2020 John MacFarlane
   License     : GNU GPL, version 2 or above

   Maintainer  : John MacFarlane <jgm@berkeley.edu>
   Stability   : alpha
   Portability : portable

Conversion of CommonMark-formatted plain text to 'Pandoc' document.

CommonMark is a strongly specified variant of Markdown: http://commonmark.org.
-}
module Text.Pandoc.Readers.CommonMark (readCommonMark)
where

import CMarkGFM
import Control.Monad.State
import qualified Data.Set as Set
import Data.Text (Text)
import qualified Data.Text as T
import Text.Pandoc.Class.PandocMonad (PandocMonad)
import Text.Pandoc.Definition
import Text.Pandoc.Emoji (emojiToInline)
import Text.Pandoc.Options
import Text.Pandoc.Shared (uniqueIdent, taskListItemFromAscii)
import Text.Pandoc.Walk (walkM)

-- | Parse a CommonMark formatted string into a 'Pandoc' structure.
readCommonMark :: PandocMonad m => ReaderOptions -> Text -> m Pandoc
readCommonMark :: ReaderOptions -> Text -> m Pandoc
readCommonMark ReaderOptions
opts Text
s = Pandoc -> m Pandoc
forall (m :: * -> *) a. Monad m => a -> m a
return (Pandoc -> m Pandoc) -> Pandoc -> m Pandoc
forall a b. (a -> b) -> a -> b
$
  (if Extension -> ReaderOptions -> Bool
forall a. HasSyntaxExtensions a => Extension -> a -> Bool
isEnabled Extension
Ext_auto_identifiers ReaderOptions
opts
      then ReaderOptions -> Pandoc -> Pandoc
addHeaderIdentifiers ReaderOptions
opts
      else Pandoc -> Pandoc
forall a. a -> a
id) (Pandoc -> Pandoc) -> Pandoc -> Pandoc
forall a b. (a -> b) -> a -> b
$
  ReaderOptions -> Node -> Pandoc
nodeToPandoc ReaderOptions
opts (Node -> Pandoc) -> Node -> Pandoc
forall a b. (a -> b) -> a -> b
$ [CMarkOption] -> [CMarkExtension] -> Text -> Node
commonmarkToNode [CMarkOption]
opts' [CMarkExtension]
exts Text
s
  where opts' :: [CMarkOption]
opts' = [ CMarkOption
optSmart | Extension -> ReaderOptions -> Bool
forall a. HasSyntaxExtensions a => Extension -> a -> Bool
isEnabled Extension
Ext_smart ReaderOptions
opts ]
        exts :: [CMarkExtension]
exts = [ CMarkExtension
extStrikethrough | Extension -> ReaderOptions -> Bool
forall a. HasSyntaxExtensions a => Extension -> a -> Bool
isEnabled Extension
Ext_strikeout ReaderOptions
opts ] [CMarkExtension] -> [CMarkExtension] -> [CMarkExtension]
forall a. [a] -> [a] -> [a]
++
               [ CMarkExtension
extTable | Extension -> ReaderOptions -> Bool
forall a. HasSyntaxExtensions a => Extension -> a -> Bool
isEnabled Extension
Ext_pipe_tables ReaderOptions
opts ] [CMarkExtension] -> [CMarkExtension] -> [CMarkExtension]
forall a. [a] -> [a] -> [a]
++
               [ CMarkExtension
extAutolink | Extension -> ReaderOptions -> Bool
forall a. HasSyntaxExtensions a => Extension -> a -> Bool
isEnabled Extension
Ext_autolink_bare_uris ReaderOptions
opts ]

convertEmojis :: Text -> [Inline]
convertEmojis :: Text -> [Inline]
convertEmojis s :: Text
s@(Text -> Maybe (Char, Text)
T.uncons -> Just (Char
':',Text
xs)) =
   case (Char -> Bool) -> Text -> (Text, Text)
T.break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
':') Text
xs of
        (Text
ys, Text -> Maybe (Char, Text)
T.uncons -> Just (Char
':',Text
zs)) ->
           case Text -> Maybe Inline
emojiToInline Text
ys of
                Just Inline
em -> Inline
em Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
: Text -> [Inline]
convertEmojis Text
zs
                Maybe Inline
Nothing -> Text -> Inline
Str (Text
":" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
ys) Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
: Text -> [Inline]
convertEmojis (Text
":" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
zs)
        (Text, Text)
_ -> [Text -> Inline
Str Text
s]
convertEmojis Text
s =
  case (Char -> Bool) -> Text -> (Text, Text)
T.break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
':') Text
s of
    (Text
"",Text
"") -> []
    (Text
_,Text
"") -> [Text -> Inline
Str Text
s]
    (Text
xs,Text
ys) -> Text -> Inline
Str Text
xs Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
: Text -> [Inline]
convertEmojis Text
ys

addHeaderIdentifiers :: ReaderOptions -> Pandoc -> Pandoc
addHeaderIdentifiers :: ReaderOptions -> Pandoc -> Pandoc
addHeaderIdentifiers ReaderOptions
opts Pandoc
doc = State (Set Text) Pandoc -> Set Text -> Pandoc
forall s a. State s a -> s -> a
evalState ((Block -> StateT (Set Text) Identity Block)
-> Pandoc -> State (Set Text) Pandoc
forall a b (m :: * -> *).
(Walkable a b, Monad m, Applicative m, Functor m) =>
(a -> m a) -> b -> m b
walkM (ReaderOptions -> Block -> StateT (Set Text) Identity Block
addHeaderId ReaderOptions
opts) Pandoc
doc) Set Text
forall a. Monoid a => a
mempty

addHeaderId :: ReaderOptions -> Block -> State (Set.Set Text) Block
addHeaderId :: ReaderOptions -> Block -> StateT (Set Text) Identity Block
addHeaderId ReaderOptions
opts (Header Int
lev (Text
_,[Text]
classes,[(Text, Text)]
kvs) [Inline]
ils) = do
  Set Text
ids <- StateT (Set Text) Identity (Set Text)
forall s (m :: * -> *). MonadState s m => m s
get
  let ident :: Text
ident = Extensions -> [Inline] -> Set Text -> Text
uniqueIdent (ReaderOptions -> Extensions
readerExtensions ReaderOptions
opts) [Inline]
ils Set Text
ids
  (Set Text -> Set Text) -> StateT (Set Text) Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (Text -> Set Text -> Set Text
forall a. Ord a => a -> Set a -> Set a
Set.insert Text
ident)
  Block -> StateT (Set Text) Identity Block
forall (m :: * -> *) a. Monad m => a -> m a
return (Block -> StateT (Set Text) Identity Block)
-> Block -> StateT (Set Text) Identity Block
forall a b. (a -> b) -> a -> b
$ Int -> (Text, [Text], [(Text, Text)]) -> [Inline] -> Block
Header Int
lev (Text
ident,[Text]
classes,[(Text, Text)]
kvs) [Inline]
ils
addHeaderId ReaderOptions
_ Block
x = Block -> StateT (Set Text) Identity Block
forall (m :: * -> *) a. Monad m => a -> m a
return Block
x

nodeToPandoc :: ReaderOptions -> Node -> Pandoc
nodeToPandoc :: ReaderOptions -> Node -> Pandoc
nodeToPandoc ReaderOptions
opts (Node Maybe PosInfo
_ NodeType
DOCUMENT [Node]
nodes) =
  Meta -> [Block] -> Pandoc
Pandoc Meta
nullMeta ([Block] -> Pandoc) -> [Block] -> Pandoc
forall a b. (a -> b) -> a -> b
$ (Node -> [Block] -> [Block]) -> [Block] -> [Node] -> [Block]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (ReaderOptions -> Node -> [Block] -> [Block]
addBlock ReaderOptions
opts) [] [Node]
nodes
nodeToPandoc ReaderOptions
opts Node
n =  -- shouldn't happen
  Meta -> [Block] -> Pandoc
Pandoc Meta
nullMeta ([Block] -> Pandoc) -> [Block] -> Pandoc
forall a b. (a -> b) -> a -> b
$ (Node -> [Block] -> [Block]) -> [Block] -> [Node] -> [Block]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (ReaderOptions -> Node -> [Block] -> [Block]
addBlock ReaderOptions
opts) [] [Node
n]

addBlocks :: ReaderOptions -> [Node] -> [Block]
addBlocks :: ReaderOptions -> [Node] -> [Block]
addBlocks ReaderOptions
opts = (Node -> [Block] -> [Block]) -> [Block] -> [Node] -> [Block]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (ReaderOptions -> Node -> [Block] -> [Block]
addBlock ReaderOptions
opts) []

addBlock :: ReaderOptions -> Node -> [Block] -> [Block]
addBlock :: ReaderOptions -> Node -> [Block] -> [Block]
addBlock ReaderOptions
opts (Node Maybe PosInfo
_ NodeType
PARAGRAPH [Node]
nodes) =
  ([Inline] -> Block
Para (ReaderOptions -> [Node] -> [Inline]
addInlines ReaderOptions
opts [Node]
nodes) Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
:)
addBlock ReaderOptions
_ (Node Maybe PosInfo
_ NodeType
THEMATIC_BREAK [Node]
_) =
  (Block
HorizontalRule Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
:)
addBlock ReaderOptions
opts (Node Maybe PosInfo
_ NodeType
BLOCK_QUOTE [Node]
nodes) =
  ([Block] -> Block
BlockQuote (ReaderOptions -> [Node] -> [Block]
addBlocks ReaderOptions
opts [Node]
nodes) Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
:)
addBlock ReaderOptions
opts (Node Maybe PosInfo
_ (HTML_BLOCK Text
t) [Node]
_)
  | Extension -> ReaderOptions -> Bool
forall a. HasSyntaxExtensions a => Extension -> a -> Bool
isEnabled Extension
Ext_raw_html ReaderOptions
opts = (Format -> Text -> Block
RawBlock (Text -> Format
Format Text
"html") Text
t Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
:)
  | Bool
otherwise                 = [Block] -> [Block]
forall a. a -> a
id
-- Note:  the cmark parser will never generate CUSTOM_BLOCK,
-- so we don't need to handle it:
addBlock ReaderOptions
_ (Node Maybe PosInfo
_ (CUSTOM_BLOCK Text
_onEnter Text
_onExit) [Node]
_nodes) =
  [Block] -> [Block]
forall a. a -> a
id
addBlock ReaderOptions
_ (Node Maybe PosInfo
_ (CODE_BLOCK Text
info Text
t) [Node]
_) =
  ((Text, [Text], [(Text, Text)]) -> Text -> Block
CodeBlock (Text
"", Int -> [Text] -> [Text]
forall a. Int -> [a] -> [a]
take Int
1 (Text -> [Text]
T.words Text
info), []) Text
t Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
:)
addBlock ReaderOptions
opts (Node Maybe PosInfo
_ (HEADING Int
lev) [Node]
nodes) =
  (Int -> (Text, [Text], [(Text, Text)]) -> [Inline] -> Block
Header Int
lev (Text
"",[],[]) (ReaderOptions -> [Node] -> [Inline]
addInlines ReaderOptions
opts [Node]
nodes) Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
:)
addBlock ReaderOptions
opts (Node Maybe PosInfo
_ (LIST ListAttributes
listAttrs) [Node]
nodes) =
  ([[Block]] -> Block
constructor ((Node -> [Block]) -> [Node] -> [[Block]]
forall a b. (a -> b) -> [a] -> [b]
map Node -> [Block]
listItem [Node]
nodes) Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
:)
  where constructor :: [[Block]] -> Block
constructor = case ListAttributes -> ListType
listType ListAttributes
listAttrs of
                       ListType
BULLET_LIST  -> [[Block]] -> Block
BulletList
                       ListType
ORDERED_LIST -> ListAttributes -> [[Block]] -> Block
OrderedList
                                         (Int
start, ListNumberStyle
DefaultStyle, ListNumberDelim
delim)
        start :: Int
start = ListAttributes -> Int
listStart ListAttributes
listAttrs
        listItem :: Node -> [Block]
listItem = Extensions -> [Block] -> [Block]
taskListItemFromAscii Extensions
exts ([Block] -> [Block]) -> (Node -> [Block]) -> Node -> [Block]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Block] -> [Block]
setTightness
                     ([Block] -> [Block]) -> (Node -> [Block]) -> Node -> [Block]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReaderOptions -> [Node] -> [Block]
addBlocks ReaderOptions
opts ([Node] -> [Block]) -> (Node -> [Node]) -> Node -> [Block]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Node -> [Node]
children
        setTightness :: [Block] -> [Block]
setTightness = if ListAttributes -> Bool
listTight ListAttributes
listAttrs
                           then (Block -> Block) -> [Block] -> [Block]
forall a b. (a -> b) -> [a] -> [b]
map Block -> Block
paraToPlain
                           else [Block] -> [Block]
forall a. a -> a
id
        paraToPlain :: Block -> Block
paraToPlain (Para [Inline]
xs) = [Inline] -> Block
Plain [Inline]
xs
        paraToPlain Block
x         = Block
x
        delim :: ListNumberDelim
delim = case ListAttributes -> DelimType
listDelim ListAttributes
listAttrs of
                     DelimType
PERIOD_DELIM -> ListNumberDelim
Period
                     DelimType
PAREN_DELIM  -> ListNumberDelim
OneParen
        exts :: Extensions
exts = ReaderOptions -> Extensions
readerExtensions ReaderOptions
opts
addBlock ReaderOptions
opts (Node Maybe PosInfo
_ (TABLE [TableCellAlignment]
alignments) [Node]
nodes) =
  ([Inline]
-> [Alignment] -> [Double] -> [[Block]] -> [[[Block]]] -> Block
Table [] [Alignment]
aligns [Double]
widths [[Block]]
headers [[[Block]]]
rows Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
:)
  where aligns :: [Alignment]
aligns = (TableCellAlignment -> Alignment)
-> [TableCellAlignment] -> [Alignment]
forall a b. (a -> b) -> [a] -> [b]
map TableCellAlignment -> Alignment
fromTableCellAlignment [TableCellAlignment]
alignments
        fromTableCellAlignment :: TableCellAlignment -> Alignment
fromTableCellAlignment TableCellAlignment
NoAlignment   = Alignment
AlignDefault
        fromTableCellAlignment TableCellAlignment
LeftAligned   = Alignment
AlignLeft
        fromTableCellAlignment TableCellAlignment
RightAligned  = Alignment
AlignRight
        fromTableCellAlignment TableCellAlignment
CenterAligned = Alignment
AlignCenter
        widths :: [Double]
widths = Int -> Double -> [Double]
forall a. Int -> a -> [a]
replicate Int
numcols Double
0.0
        numcols :: Int
numcols = if [[[Block]]] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[[Block]]]
rows'
                     then Int
0
                     else [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ([Int] -> Int) -> [Int] -> Int
forall a b. (a -> b) -> a -> b
$ ([[Block]] -> Int) -> [[[Block]]] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map [[Block]] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [[[Block]]]
rows'
        rows' :: [[[Block]]]
rows' = (Node -> [[Block]]) -> [Node] -> [[[Block]]]
forall a b. (a -> b) -> [a] -> [b]
map Node -> [[Block]]
toRow ([Node] -> [[[Block]]]) -> [Node] -> [[[Block]]]
forall a b. (a -> b) -> a -> b
$ (Node -> Bool) -> [Node] -> [Node]
forall a. (a -> Bool) -> [a] -> [a]
filter Node -> Bool
isRow [Node]
nodes
        ([[Block]]
headers, [[[Block]]]
rows) = case [[[Block]]]
rows' of
                               ([[Block]]
h:[[[Block]]]
rs) -> ([[Block]]
h, [[[Block]]]
rs)
                               []     -> ([], [])
        isRow :: Node -> Bool
isRow (Node Maybe PosInfo
_ NodeType
TABLE_ROW [Node]
_) = Bool
True
        isRow Node
_                    = Bool
False
        isCell :: Node -> Bool
isCell (Node Maybe PosInfo
_ NodeType
TABLE_CELL [Node]
_) = Bool
True
        isCell Node
_                     = Bool
False
        toRow :: Node -> [[Block]]
toRow (Node Maybe PosInfo
_ NodeType
TABLE_ROW [Node]
ns) = (Node -> [Block]) -> [Node] -> [[Block]]
forall a b. (a -> b) -> [a] -> [b]
map Node -> [Block]
toCell ([Node] -> [[Block]]) -> [Node] -> [[Block]]
forall a b. (a -> b) -> a -> b
$ (Node -> Bool) -> [Node] -> [Node]
forall a. (a -> Bool) -> [a] -> [a]
filter Node -> Bool
isCell [Node]
ns
        toRow (Node Maybe PosInfo
_ NodeType
t [Node]
_) = [Char] -> [[Block]]
forall a. HasCallStack => [Char] -> a
error ([Char] -> [[Block]]) -> [Char] -> [[Block]]
forall a b. (a -> b) -> a -> b
$ [Char]
"toRow encountered non-row " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ NodeType -> [Char]
forall a. Show a => a -> [Char]
show NodeType
t
        toCell :: Node -> [Block]
toCell (Node Maybe PosInfo
_ NodeType
TABLE_CELL []) = []
        toCell (Node Maybe PosInfo
_ NodeType
TABLE_CELL (Node
n:[Node]
ns))
          | Node -> Bool
isBlockNode Node
n = ReaderOptions -> [Node] -> [Block]
addBlocks ReaderOptions
opts (Node
nNode -> [Node] -> [Node]
forall a. a -> [a] -> [a]
:[Node]
ns)
          | Bool
otherwise     = [[Inline] -> Block
Plain (ReaderOptions -> [Node] -> [Inline]
addInlines ReaderOptions
opts (Node
nNode -> [Node] -> [Node]
forall a. a -> [a] -> [a]
:[Node]
ns))]
        toCell (Node Maybe PosInfo
_ NodeType
t [Node]
_) = [Char] -> [Block]
forall a. HasCallStack => [Char] -> a
error ([Char] -> [Block]) -> [Char] -> [Block]
forall a b. (a -> b) -> a -> b
$ [Char]
"toCell encountered non-cell " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ NodeType -> [Char]
forall a. Show a => a -> [Char]
show NodeType
t
addBlock ReaderOptions
_ (Node Maybe PosInfo
_ NodeType
TABLE_ROW [Node]
_) = [Block] -> [Block]
forall a. a -> a
id -- handled in TABLE
addBlock ReaderOptions
_ (Node Maybe PosInfo
_ NodeType
TABLE_CELL [Node]
_) = [Block] -> [Block]
forall a. a -> a
id -- handled in TABLE
addBlock ReaderOptions
_ Node
_ = [Block] -> [Block]
forall a. a -> a
id

isBlockNode :: Node -> Bool
isBlockNode :: Node -> Bool
isBlockNode (Node Maybe PosInfo
_ NodeType
nodetype [Node]
_) =
  case NodeType
nodetype of
       NodeType
DOCUMENT          -> Bool
True
       NodeType
THEMATIC_BREAK    -> Bool
True
       NodeType
PARAGRAPH         -> Bool
True
       NodeType
BLOCK_QUOTE       -> Bool
True
       HTML_BLOCK Text
_      -> Bool
True
       CUSTOM_BLOCK Text
_ Text
_  -> Bool
True
       CODE_BLOCK Text
_ Text
_    -> Bool
True
       HEADING Int
_         -> Bool
True
       LIST ListAttributes
_            -> Bool
True
       NodeType
ITEM              -> Bool
True
       TEXT Text
_            -> Bool
False
       NodeType
SOFTBREAK         -> Bool
False
       NodeType
LINEBREAK         -> Bool
False
       HTML_INLINE Text
_     -> Bool
False
       CUSTOM_INLINE Text
_ Text
_ -> Bool
False
       CODE Text
_            -> Bool
False
       NodeType
EMPH              -> Bool
False
       NodeType
STRONG            -> Bool
False
       LINK Text
_ Text
_          -> Bool
False
       IMAGE Text
_ Text
_         -> Bool
False
       NodeType
STRIKETHROUGH     -> Bool
False
       TABLE [TableCellAlignment]
_           -> Bool
False
       NodeType
TABLE_ROW         -> Bool
False
       NodeType
TABLE_CELL        -> Bool
False

children :: Node -> [Node]
children :: Node -> [Node]
children (Node Maybe PosInfo
_ NodeType
_ [Node]
ns) = [Node]
ns

addInlines :: ReaderOptions -> [Node] -> [Inline]
addInlines :: ReaderOptions -> [Node] -> [Inline]
addInlines ReaderOptions
opts = (Node -> [Inline] -> [Inline]) -> [Inline] -> [Node] -> [Inline]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (ReaderOptions -> Node -> [Inline] -> [Inline]
addInline ReaderOptions
opts) []

addInline :: ReaderOptions -> Node -> [Inline] -> [Inline]
addInline :: ReaderOptions -> Node -> [Inline] -> [Inline]
addInline ReaderOptions
opts (Node Maybe PosInfo
_ (TEXT Text
t) [Node]
_) = ((Text -> [Inline]) -> [Text] -> [Inline]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Text -> [Inline]
toinl [Text]
clumps [Inline] -> [Inline] -> [Inline]
forall a. [a] -> [a] -> [a]
++)
  where clumps :: [Text]
clumps = (Char -> Char -> Bool) -> Text -> [Text]
T.groupBy Char -> Char -> Bool
samekind Text
t
        samekind :: Char -> Char -> Bool
samekind Char
' ' Char
' ' = Bool
True
        samekind Char
' ' Char
_   = Bool
False
        samekind Char
_   Char
' ' = Bool
False
        samekind Char
_  Char
_    = Bool
True
        toinl :: Text -> [Inline]
toinl (Text -> Maybe (Char, Text)
T.uncons -> Just (Char
' ', Text
_)) = [Inline
Space]
        toinl Text
xs = if Extension -> ReaderOptions -> Bool
forall a. HasSyntaxExtensions a => Extension -> a -> Bool
isEnabled Extension
Ext_emoji ReaderOptions
opts
                   then Text -> [Inline]
convertEmojis Text
xs
                   else [Text -> Inline
Str Text
xs]
addInline ReaderOptions
_ (Node Maybe PosInfo
_ NodeType
LINEBREAK [Node]
_) = (Inline
LineBreak Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
:)
addInline ReaderOptions
opts (Node Maybe PosInfo
_ NodeType
SOFTBREAK [Node]
_)
  | Extension -> ReaderOptions -> Bool
forall a. HasSyntaxExtensions a => Extension -> a -> Bool
isEnabled Extension
Ext_hard_line_breaks ReaderOptions
opts = (Inline
LineBreak Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
:)
  | Bool
otherwise                           = (Inline
SoftBreak Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
:)
addInline ReaderOptions
opts (Node Maybe PosInfo
_ (HTML_INLINE Text
t) [Node]
_)
  | Extension -> ReaderOptions -> Bool
forall a. HasSyntaxExtensions a => Extension -> a -> Bool
isEnabled Extension
Ext_raw_html ReaderOptions
opts = (Format -> Text -> Inline
RawInline (Text -> Format
Format Text
"html") Text
t Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
:)
  | Bool
otherwise                 = [Inline] -> [Inline]
forall a. a -> a
id
-- Note:  the cmark parser will never generate CUSTOM_BLOCK,
-- so we don't need to handle it:
addInline ReaderOptions
_ (Node Maybe PosInfo
_ (CUSTOM_INLINE Text
_onEnter Text
_onExit) [Node]
_nodes) =
  [Inline] -> [Inline]
forall a. a -> a
id
addInline ReaderOptions
_ (Node Maybe PosInfo
_ (CODE Text
t) [Node]
_) =
  ((Text, [Text], [(Text, Text)]) -> Text -> Inline
Code (Text
"",[],[]) Text
t Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
:)
addInline ReaderOptions
opts (Node Maybe PosInfo
_ NodeType
EMPH [Node]
nodes) =
  ([Inline] -> Inline
Emph (ReaderOptions -> [Node] -> [Inline]
addInlines ReaderOptions
opts [Node]
nodes) Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
:)
addInline ReaderOptions
opts (Node Maybe PosInfo
_ NodeType
STRONG [Node]
nodes) =
  ([Inline] -> Inline
Strong (ReaderOptions -> [Node] -> [Inline]
addInlines ReaderOptions
opts [Node]
nodes) Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
:)
addInline ReaderOptions
opts (Node Maybe PosInfo
_ NodeType
STRIKETHROUGH [Node]
nodes) =
  ([Inline] -> Inline
Strikeout (ReaderOptions -> [Node] -> [Inline]
addInlines ReaderOptions
opts [Node]
nodes) Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
:)
addInline ReaderOptions
opts (Node Maybe PosInfo
_ (LINK Text
url Text
title) [Node]
nodes) =
  ((Text, [Text], [(Text, Text)])
-> [Inline] -> (Text, Text) -> Inline
Link (Text, [Text], [(Text, Text)])
nullAttr (ReaderOptions -> [Node] -> [Inline]
addInlines ReaderOptions
opts [Node]
nodes) (Text
url, Text
title) Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
:)
addInline ReaderOptions
opts (Node Maybe PosInfo
_ (IMAGE Text
url Text
title) [Node]
nodes) =
  ((Text, [Text], [(Text, Text)])
-> [Inline] -> (Text, Text) -> Inline
Image (Text, [Text], [(Text, Text)])
nullAttr (ReaderOptions -> [Node] -> [Inline]
addInlines ReaderOptions
opts [Node]
nodes) (Text
url, Text
title) Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
:)
addInline ReaderOptions
_ Node
_ = [Inline] -> [Inline]
forall a. a -> a
id