content: {-# LANGUAGE CPP #-}
  --------------------------------------------------------------------------------
  -- | Module exporting convenient pandoc bindings
  module Hakyll.Web.Pandoc
      ( -- * The basic building blocks
        readPandoc
      , readPandocWith
      , writePandoc
      , writePandocWith
      , renderPandoc
      , renderPandocWith
      , renderPandocWithTransform
      , renderPandocWithTransformM
      , renderPandocItemWithTransformM
  
        -- * Derived compilers
      , pandocCompiler
      , pandocCompilerWith
      , pandocCompilerWithTransform
      , pandocCompilerWithTransformM
      , pandocItemCompilerWithTransformM
  
        -- * Default options
      , defaultHakyllReaderOptions
      , defaultHakyllWriterOptions
      ) where
  
  
  --------------------------------------------------------------------------------
  import qualified Data.Text                  as T
  import           Text.Pandoc
  import           Text.Pandoc.Highlighting   (pygments)
  
  
  --------------------------------------------------------------------------------
  import           Hakyll.Core.Compiler
  import           Hakyll.Core.Item
  import           Hakyll.Web.Pandoc.FileType
  
  
  --------------------------------------------------------------------------------
  -- | Read a string using pandoc, with the default options
  readPandoc
      :: Item String             -- ^ String to read
      -> Compiler (Item Pandoc)  -- ^ Resulting document
  readPandoc = readPandocWith defaultHakyllReaderOptions
  
  
  --------------------------------------------------------------------------------
  -- | Read a string using pandoc, with the supplied options
  readPandocWith
      :: ReaderOptions           -- ^ Parser options
      -> Item String             -- ^ String to read
      -> Compiler (Item Pandoc)  -- ^ Resulting document
  readPandocWith ropt item =
      case runPure $ traverse (reader ropt (itemFileType item)) (fmap T.pack item) of
          Left err    -> fail $
              "Hakyll.Web.Pandoc.readPandocWith: parse failed: " ++ show err
          Right item' -> return item'
    where
      reader ro t = case t of
          DocBook            -> readDocBook ro
          Html               -> readHtml ro
          Jupyter            -> readIpynb ro
          LaTeX              -> readLaTeX ro
          LiterateHaskell t' -> reader (addExt ro Ext_literate_haskell) t'
          Markdown           -> readMarkdown ro
          MediaWiki          -> readMediaWiki ro
          OrgMode            -> readOrg ro
          Rst                -> readRST ro
  -- This preprocessing instruction can be dropped
  -- once the minimum supported GHC version is 8.10
  #if MIN_VERSION_pandoc(3,1,3)
          Typst              -> readTypst ro
  #endif
          Textile            -> readTextile ro
          _                  -> error $
              "Hakyll.Web.readPandocWith: I don't know how to read a file of " ++
              "the type " ++ show t ++ " for: " ++ show (itemIdentifier item)
  
      addExt ro e = ro {readerExtensions = enableExtension e $ readerExtensions ro}
  
  
  --------------------------------------------------------------------------------
  -- | Write a document (as HTML) using pandoc, with the default options
  writePandoc :: Item Pandoc  -- ^ Document to write
              -> Item String  -- ^ Resulting HTML
  writePandoc = writePandocWith defaultHakyllWriterOptions
  
  
  --------------------------------------------------------------------------------
  -- | Write a document (as HTML) using pandoc, with the supplied options
  writePandocWith :: WriterOptions  -- ^ Writer options for pandoc
                  -> Item Pandoc    -- ^ Document to write
                  -> Item String    -- ^ Resulting HTML
  writePandocWith wopt (Item itemi doc) =
      case runPure $ writeHtml5String wopt doc of
          Left err    -> error $ "Hakyll.Web.Pandoc.writePandocWith: " ++ show err
          Right item' -> Item itemi $ T.unpack item'
  
  
  --------------------------------------------------------------------------------
  -- | Render the resource using pandoc
  renderPandoc :: Item String -> Compiler (Item String)
  renderPandoc =
      renderPandocWith defaultHakyllReaderOptions defaultHakyllWriterOptions
  
  
  --------------------------------------------------------------------------------
  -- | Render the resource using pandoc
  renderPandocWith
      :: ReaderOptions -> WriterOptions -> Item String -> Compiler (Item String)
  renderPandocWith ropt wopt item =
      writePandocWith wopt <$> readPandocWith ropt item
  
  
  --------------------------------------------------------------------------------
  -- | An extension of `renderPandocWith`, which allows you to specify a custom
  -- Pandoc transformation on the input `Item`.
  -- Useful if you want to do your own transformations before running
  -- custom Pandoc transformations, e.g. using a `funcField` to transform raw content.
  renderPandocWithTransform :: ReaderOptions -> WriterOptions
                      -> (Pandoc -> Pandoc)
                      -> Item String
                      -> Compiler (Item String)
  renderPandocWithTransform ropt wopt f =
      renderPandocWithTransformM ropt wopt (return . f)
  
  
  --------------------------------------------------------------------------------
  -- | Similar to 'renderPandocWithTransform', but the Pandoc transformation is
  -- monadic. This is useful when you want the pandoc
  -- transformation to use the 'Compiler' information such as routes,
  -- metadata, etc. along with your own transformations beforehand.
  --
  -- @since 4.16.3.0
  renderPandocWithTransformM :: ReaderOptions -> WriterOptions
                      -> (Pandoc -> Compiler Pandoc)
                      -> Item String
                      -> Compiler (Item String)
  renderPandocWithTransformM ropt wopt f i =
      writePandocWith wopt <$> (traverse f =<< readPandocWith ropt i)
  
  
  --------------------------------------------------------------------------------
  -- | Like 'renderPandocWithTransformM', but work on an @'Item' 'Pandoc'@ instead
  -- of just a 'Pandoc'. This allows for more seamless composition of functions
  -- that require the extra information that an 'Item' provides, like
  -- bibliographic transformations with
  -- 'Hakyll.Web.Pandoc.Biblio.processPandocBiblio'.
  --
  -- @since 4.16.3.0
  renderPandocItemWithTransformM
    :: ReaderOptions -> WriterOptions
    -> (Item Pandoc -> Compiler (Item Pandoc))
    -> Item String
    -> Compiler (Item String)
  renderPandocItemWithTransformM ropt wopt f i =
      writePandocWith wopt <$> (f =<< readPandocWith ropt i)
  
  
  --------------------------------------------------------------------------------
  -- | Read a page render using pandoc
  pandocCompiler :: Compiler (Item String)
  pandocCompiler =
      pandocCompilerWith defaultHakyllReaderOptions defaultHakyllWriterOptions
  
  
  --------------------------------------------------------------------------------
  -- | A version of 'pandocCompiler' which allows you to specify your own pandoc
  -- options
  pandocCompilerWith :: ReaderOptions -> WriterOptions -> Compiler (Item String)
  pandocCompilerWith ropt wopt =
      cached "Hakyll.Web.Pandoc.pandocCompilerWith" $
          pandocCompilerWithTransform ropt wopt id
  
  
  --------------------------------------------------------------------------------
  -- | An extension of 'pandocCompilerWith' which allows you to specify a custom
  -- pandoc transformation for the content
  pandocCompilerWithTransform :: ReaderOptions -> WriterOptions
                              -> (Pandoc -> Pandoc)
                              -> Compiler (Item String)
  pandocCompilerWithTransform ropt wopt f =
      pandocCompilerWithTransformM ropt wopt (return . f)
  
  
  --------------------------------------------------------------------------------
  -- | Similar to 'pandocCompilerWithTransform', but the transformation
  -- function is monadic. This is useful when you want the pandoc
  -- transformation to use the 'Compiler' information such as routes,
  -- metadata, etc
  pandocCompilerWithTransformM :: ReaderOptions -> WriterOptions
                      -> (Pandoc -> Compiler Pandoc)
                      -> Compiler (Item String)
  pandocCompilerWithTransformM ropt wopt f =
      getResourceBody >>= renderPandocWithTransformM ropt wopt f
  
  
  --------------------------------------------------------------------------------
  -- | Like 'pandocCompilerWithTransformM', but work on an 'Item' 'Pandoc'
  -- instead of just a 'Pandoc'. This allows for more seamless composition of
  -- functions that require the extra information that an 'Item' provides, like
  -- bibliographic transformations with
  -- 'Hakyll.Web.Pandoc.Biblio.processPandocBiblio'.
  pandocItemCompilerWithTransformM
    :: ReaderOptions -> WriterOptions
    -> (Item Pandoc -> Compiler (Item Pandoc))
    -> Compiler (Item String)
  pandocItemCompilerWithTransformM ropt wopt f =
      getResourceBody >>= renderPandocItemWithTransformM ropt wopt f
  
  
  --------------------------------------------------------------------------------
  -- | The default reader options for pandoc parsing in hakyll
  defaultHakyllReaderOptions :: ReaderOptions
  defaultHakyllReaderOptions = def
      { -- The following option causes pandoc to read smart typography, a nice
        -- and free bonus.
        readerExtensions = enableExtension Ext_smart pandocExtensions
      }
  
  
  --------------------------------------------------------------------------------
  -- | The default writer options for pandoc rendering in hakyll
  defaultHakyllWriterOptions :: WriterOptions
  defaultHakyllWriterOptions = def
      { -- This option causes literate haskell to be written using '>' marks in
        -- html, which I think is a good default.
        writerExtensions = enableExtension Ext_smart pandocExtensions
      , -- We want to have hightlighting by default, to be compatible with earlier
        -- Hakyll releases
  #if MIN_VERSION_pandoc(3,8,0)
        -- Starting with pandoc 3.8, the highlighting
        -- system was overhauled to have more than just Skylighting
        -- styles
        writerHighlightMethod = Skylighting pygments
  #else
        writerHighlightStyle = Just pygments
  #endif
      , -- Do not word-wrap produced HTML, and do not undo any word-wrapping
        -- that's already present in the markup. This is how Pandoc operated
        -- prior to 2.17, but the behaviour was changed for consistency with
        -- other Pandoc writers. We retain the old behaviour because it spares us
        -- the trouble of updating our golden tests.
        writerWrapText = WrapPreserve
      }
  