content: {-# LANGUAGE LambdaCase #-}
  {-# LANGUAGE OverloadedStrings #-}
  
  -- |
  -- Module      :  Text.MMark.Util
  -- Copyright   :  © 2017–present Mark Karpov
  -- License     :  BSD 3 clause
  --
  -- Maintainer  :  Mark Karpov <markkarpov92@gmail.com>
  -- Stability   :  experimental
  -- Portability :  portable
  --
  -- Misc utilities.
  --
  -- @since 0.0.8.0
  module Text.MMark.Util
    ( asPlainText,
      headerId,
      headerFragment,
    )
  where
  
  import Data.Char (isAlphaNum, isSpace)
  import Data.List.NonEmpty (NonEmpty (..))
  import Data.Text (Text)
  import Data.Text qualified as T
  import Text.MMark.Internal.Type
  import Text.URI (URI (..))
  import Text.URI qualified as URI
  
  -- | Convert a non-empty collection of 'Inline's into their plain text
  -- representation. This is used e.g. to render image descriptions.
  --
  -- @since 0.0.8.0
  asPlainText :: NonEmpty Inline -> Text
  asPlainText = foldMap $ \case
    Plain txt -> txt
    LineBreak -> "\n"
    Emphasis xs -> asPlainText xs
    Strong xs -> asPlainText xs
    Strikeout xs -> asPlainText xs
    Subscript xs -> asPlainText xs
    Superscript xs -> asPlainText xs
    CodeSpan txt -> txt
    Link xs _ _ -> asPlainText xs
    Image xs _ _ -> asPlainText xs
  
  -- | Generate value of id attribute for a given header. This is used during
  -- rendering and also can be used to get id of a header for linking to it in
  -- extensions.
  --
  -- See also: 'headerFragment'.
  --
  -- @since 0.0.8.0
  headerId :: NonEmpty Inline -> Text
  headerId =
    T.intercalate "-"
      . T.words
      . T.filter (\x -> isAlphaNum x || isSpace x)
      . T.toLower
      . asPlainText
  
  -- | Generate a 'URI' containing only a fragment from its textual
  -- representation. Useful for getting URL from id of a header.
  --
  -- @since 0.0.8.0
  headerFragment :: Text -> URI
  headerFragment fragment =
    URI
      { uriScheme = Nothing,
        uriAuthority = Left False,
        uriPath = Nothing,
        uriQuery = [],
        uriFragment = URI.mkFragment fragment
      }
  