{-# LANGUAGE GHC2021 #-}
{-# LANGUAGE OverloadedStrings #-}
-- | Typographic refinements applied to the Pandoc AST.
--
--   Currently: expands common Latin abbreviations to @<abbr>@ elements
--   (e.g. → exempli gratia, i.e. → id est, etc.).  Pandoc's @smart@
--   reader extension already handles em-dashes, en-dashes, ellipses,
--   and curly quotes, so those are not repeated here.
module Filters.Typography (apply) where

import           Data.Text    (Text)
import qualified Data.Text    as T
import           Text.Pandoc.Definition
import           Text.Pandoc.Walk (walk)

-- | Apply all typographic transformations to the document.
apply :: Pandoc -> Pandoc
apply = walk expandAbbrev

-- ---------------------------------------------------------------------------
-- Abbreviation expansion
-- ---------------------------------------------------------------------------

-- | Abbreviations that should be wrapped in @<abbr title="…">@.
--   Each entry is (verbatim text as it appears in the Pandoc Str token,
--   long-form title for the tooltip).
abbrevMap :: [(Text, Text)]
abbrevMap =
    [ ("e.g.",    "exempli gratia")
    , ("i.e.",    "id est")
    , ("cf.",     "confer")
    , ("viz.",    "videlicet")
    , ("ibid.",   "ibidem")
    , ("op.",     "opere")      -- usually followed by "cit." in a separate token
    , ("NB",      "nota bene")
    , ("NB:",     "nota bene")
    ]

-- | If the Str token exactly matches a known abbreviation, replace it with
--   a @RawInline "html"@ @<abbr>@ element; otherwise leave it unchanged.
expandAbbrev :: Inline -> Inline
expandAbbrev (Str t) =
    case lookup t abbrevMap of
        Just title ->
            RawInline "html" $
                "<abbr title=\"" <> title <> "\">" <> escHtml t <> "</abbr>"
        Nothing -> Str t
expandAbbrev x = x

-- | Minimal HTML escaping for the abbr content (should be plain text).
escHtml :: Text -> Text
escHtml = T.concatMap esc
  where
    esc '<'  = "&lt;"
    esc '>'  = "&gt;"
    esc '&'  = "&amp;"
    esc '"'  = "&quot;"
    esc c    = T.singleton c
