    {-# LANGUAGE CPP #-}
    {-# LANGUAGE NoOverloadedStrings #-}
    module Skylighting.Format.HTML (
          formatHtmlInline
        , formatHtmlBlock
        , formatHtml4Block
        , styleToCss
        ) where

    import Data.List (intersperse, sort)
    import qualified Data.Map as Map
    import qualified Data.Text as Text
    import Skylighting.Types
    import Text.Blaze.Html
    import qualified Text.Blaze.Html5 as H
    import qualified Text.Blaze.Html5.Attributes as A
    import Data.String (fromString)
    #if !MIN_VERSION_base(4,11,0)
    import Data.Semigroup
    #endif

    -- | Format tokens using HTML spans inside @code@ tags. For example,
    -- A @KeywordTok@ is rendered as a span with class @kw@.
    -- Short class names correspond to 'TokenType's as follows:
    -- '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@.
    -- A 'NormalTok' is not marked up at all.
    formatHtmlInline :: FormatOptions -> [SourceLine] -> Html
    formatHtmlInline :: FormatOptions -> [SourceLine] -> Html
    formatHtmlInline FormatOptions
    opts = FormatOptions -> Html -> Html
    wrapCode FormatOptions
    opts
                          (Html -> Html) -> ([SourceLine] -> Html) -> [SourceLine] -> Html
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Html] -> Html
    forall a. Monoid a => [a] -> a
    mconcat ([Html] -> Html)
    -> ([SourceLine] -> [Html]) -> [SourceLine] -> Html
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Html -> [Html] -> [Html]
    forall a. a -> [a] -> [a]
    intersperse (String -> Html
    forall a. ToMarkup a => a -> Html
    toHtml String
    "\n")
                          ([Html] -> [Html])
    -> ([SourceLine] -> [Html]) -> [SourceLine] -> [Html]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (SourceLine -> Html) -> [SourceLine] -> [Html]
    forall a b. (a -> b) -> [a] -> [b]
    map ((Token -> Html) -> SourceLine -> Html
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ (FormatOptions -> Token -> Html
    tokenToHtml FormatOptions
    opts))

    -- | Format tokens as an HTML @pre@ block. Each line is wrapped in an a
    -- element with the class ‘source-line’. If line numbering
    -- is selected, the surrounding pre is given the class ‘numberSource’,
    -- and the resulting html will display line numbers thanks to the included
    -- CSS.  See the documentation for 'formatHtmlInline' for information about how
    -- tokens are encoded.
    formatHtmlBlock :: FormatOptions -> [SourceLine] -> Html
    formatHtmlBlock :: FormatOptions -> [SourceLine] -> Html
    formatHtmlBlock = HtmlVersion -> FormatOptions -> [SourceLine] -> Html
    formatHtmlBlockFor HtmlVersion
    Html5

    -- | Like 'formatHtmlBlock' but uses only attributes valid in HTML 4
    -- (so, @aria-hidden@ is not used in empty line number spans).
    formatHtml4Block :: FormatOptions -> [SourceLine] -> Html
    formatHtml4Block :: FormatOptions -> [SourceLine] -> Html
    formatHtml4Block = HtmlVersion -> FormatOptions -> [SourceLine] -> Html
    formatHtmlBlockFor HtmlVersion
    Html4

    data HtmlVersion = Html4 | Html5
      deriving (Int -> HtmlVersion -> ShowS
    [HtmlVersion] -> ShowS
    HtmlVersion -> String
    (Int -> HtmlVersion -> ShowS)
    -> (HtmlVersion -> String)
    -> ([HtmlVersion] -> ShowS)
    -> Show HtmlVersion
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> HtmlVersion -> ShowS
    showsPrec :: Int -> HtmlVersion -> ShowS
    $cshow :: HtmlVersion -> String
    show :: HtmlVersion -> String
    $cshowList :: [HtmlVersion] -> ShowS
    showList :: [HtmlVersion] -> ShowS
    Show, HtmlVersion -> HtmlVersion -> Bool
    (HtmlVersion -> HtmlVersion -> Bool)
    -> (HtmlVersion -> HtmlVersion -> Bool) -> Eq HtmlVersion
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: HtmlVersion -> HtmlVersion -> Bool
    == :: HtmlVersion -> HtmlVersion -> Bool
    $c/= :: HtmlVersion -> HtmlVersion -> Bool
    /= :: HtmlVersion -> HtmlVersion -> Bool
    Eq)

    formatHtmlBlockFor :: HtmlVersion -> FormatOptions -> [SourceLine] -> Html
    formatHtmlBlockFor :: HtmlVersion -> FormatOptions -> [SourceLine] -> Html
    formatHtmlBlockFor HtmlVersion
    htmlVersion FormatOptions
    opts [SourceLine]
    ls =
      Html -> Html
    H.div (Html -> Html) -> Attribute -> Html -> Html
    forall h. Attributable h => h -> Attribute -> h
    ! AttributeValue -> Attribute
    A.class_ (String -> AttributeValue
    forall a. ToValue a => a -> AttributeValue
    toValue String
    "sourceCode") (Html -> Html) -> Html -> Html
    forall a b. (a -> b) -> a -> b
    $
      Html -> Html
    H.pre (Html -> Html) -> Attribute -> Html -> Html
    forall h. Attributable h => h -> Attribute -> h
    ! AttributeValue -> Attribute
    A.class_ (Text -> AttributeValue
    forall a. ToValue a => a -> AttributeValue
    toValue (Text -> AttributeValue) -> Text -> AttributeValue
    forall a b. (a -> b) -> a -> b
    $ [Text] -> Text
    Text.unwords [Text]
    classes)
            (Html -> Html) -> Html -> Html
    forall a b. (a -> b) -> a -> b
    $ FormatOptions -> Html -> Html
    wrapCode FormatOptions
    opts
            (Html -> Html) -> Html -> Html
    forall a b. (a -> b) -> a -> b
    $ [Html] -> Html
    forall a. Monoid a => [a] -> a
    mconcat ([Html] -> Html) -> ([Html] -> [Html]) -> [Html] -> Html
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Html -> [Html] -> [Html]
    forall a. a -> [a] -> [a]
    intersperse (String -> Html
    forall a. ToMarkup a => a -> Html
    toHtml String
    "\n")
            ([Html] -> Html) -> [Html] -> Html
    forall a b. (a -> b) -> a -> b
    $ (LineNo -> SourceLine -> Html)
    -> [LineNo] -> [SourceLine] -> [Html]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith (HtmlVersion -> FormatOptions -> LineNo -> SourceLine -> Html
    sourceLineToHtml HtmlVersion
    htmlVersion FormatOptions
    opts) [LineNo
    startNum..] [SourceLine]
    ls
      where  classes :: [Text]
    classes = String -> Text
    Text.pack String
    "sourceCode" Text -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :
                       [String -> Text
    Text.pack String
    "numberSource" | FormatOptions -> Bool
    numberLines FormatOptions
    opts] [Text] -> [Text] -> [Text]
    forall a. [a] -> [a] -> [a]
    ++
                       [Text
    x | Text
    x <- FormatOptions -> [Text]
    containerClasses FormatOptions
    opts
                          , Text
    x Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    /= String -> Text
    Text.pack String
    "sourceCode"]
             startNum :: LineNo
    startNum = Int -> LineNo
    LineNo (Int -> LineNo) -> Int -> LineNo
    forall a b. (a -> b) -> a -> b
    $ FormatOptions -> Int
    startNumber FormatOptions
    opts

    wrapCode :: FormatOptions -> Html -> Html
    wrapCode :: FormatOptions -> Html -> Html
    wrapCode FormatOptions
    opts Html
    h = Html -> Html
    H.code (Html -> Html) -> Attribute -> Html -> Html
    forall h. Attributable h => h -> Attribute -> h
    ! AttributeValue -> Attribute
    A.class_ (Text -> AttributeValue
    forall a. ToValue a => a -> AttributeValue
    toValue (Text -> AttributeValue) -> Text -> AttributeValue
    forall a b. (a -> b) -> a -> b
    $ [Text] -> Text
    Text.unwords
                                                 ([Text] -> Text) -> [Text] -> Text
    forall a b. (a -> b) -> a -> b
    $ String -> Text
    Text.pack String
    "sourceCode"
                                                   Text -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    : FormatOptions -> [Text]
    codeClasses FormatOptions
    opts)
                             (Html -> Html) -> (Bool, Attribute) -> Html -> Html
    forall h. Attributable h => h -> (Bool, Attribute) -> h
    !? (Int
    startZero Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Int
    0, AttributeValue -> Attribute
    A.style (String -> AttributeValue
    forall a. ToValue a => a -> AttributeValue
    toValue String
    counterOverride))
                             (Html -> Html) -> Html -> Html
    forall a b. (a -> b) -> a -> b
    $ Html
    h
      where  counterOverride :: String
    counterOverride = String
    "counter-reset: source-line " String -> ShowS
    forall a. Semigroup a => a -> a -> a
    <> Int -> String
    forall a. Show a => a -> String
    show Int
    startZero String -> ShowS
    forall a. Semigroup a => a -> a -> a
    <> String
    ";"
             startZero :: Int
    startZero = FormatOptions -> Int
    startNumber FormatOptions
    opts Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    1

    -- | Each line of source is wrapped in an (inline-block) anchor that makes
    -- subsequent per-line processing (e.g. adding line numnbers) possible.
    sourceLineToHtml :: HtmlVersion -> FormatOptions -> LineNo -> SourceLine -> Html
    sourceLineToHtml :: HtmlVersion -> FormatOptions -> LineNo -> SourceLine -> Html
    sourceLineToHtml HtmlVersion
    htmlVersion FormatOptions
    opts LineNo
    lno SourceLine
    cont =
      Html -> Html
    H.span (Html -> Html) -> Attribute -> Html -> Html
    forall h. Attributable h => h -> Attribute -> h
    ! AttributeValue -> Attribute
    A.id AttributeValue
    lineNum
             (Html -> Html) -> Html -> Html
    forall a b. (a -> b) -> a -> b
    $ do
               Html -> Html
    H.a (Html -> Html) -> Attribute -> Html -> Html
    forall h. Attributable h => h -> Attribute -> h
    ! AttributeValue -> Attribute
    A.href AttributeValue
    lineRef
                   (Html -> Html) -> Attribute -> Html -> Html
    forall h. Attributable h => h -> Attribute -> h
    ! (if FormatOptions -> Bool
    numberLines FormatOptions
    opts Bool -> Bool -> Bool
    || HtmlVersion
    htmlVersion HtmlVersion -> HtmlVersion -> Bool
    forall a. Eq a => a -> a -> Bool
    == HtmlVersion
    Html4
                         then Attribute
    forall a. Monoid a => a
    mempty
                         else Tag -> AttributeValue -> Attribute
    customAttribute (String -> Tag
    forall a. IsString a => String -> a
    fromString String
    "aria-hidden")
                               (String -> AttributeValue
    forall a. IsString a => String -> a
    fromString String
    "true")) -- see jgm/pandoc#6352
                   (Html -> Html) -> Attribute -> Html -> Html
    forall h. Attributable h => h -> Attribute -> h
    ! (if FormatOptions -> Bool
    numberLines FormatOptions
    opts
                         then Attribute
    forall a. Monoid a => a
    mempty
                         else Tag -> AttributeValue -> Attribute
    customAttribute (String -> Tag
    forall a. IsString a => String -> a
    fromString String
    "tabindex")
                               (String -> AttributeValue
    forall a. IsString a => String -> a
    fromString String
    "-1"))
                   (Html -> Html) -> Html -> Html
    forall a b. (a -> b) -> a -> b
    $ Html
    forall a. Monoid a => a
    mempty
               (Token -> Html) -> SourceLine -> Html
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ (FormatOptions -> Token -> Html
    tokenToHtml FormatOptions
    opts) SourceLine
    cont
      where  lineNum :: AttributeValue
    lineNum = String -> AttributeValue
    forall a. ToValue a => a -> AttributeValue
    toValue String
    prefixedLineNo
             lineRef :: AttributeValue
    lineRef = String -> AttributeValue
    forall a. ToValue a => a -> AttributeValue
    toValue (Char
    '#'Char -> ShowS
    forall a. a -> [a] -> [a]
    :String
    prefixedLineNo)
             prefixedLineNo :: String
    prefixedLineNo = Text -> String
    Text.unpack (FormatOptions -> Text
    lineIdPrefix FormatOptions
    opts) String -> ShowS
    forall a. Semigroup a => a -> a -> a
    <> Int -> String
    forall a. Show a => a -> String
    show (LineNo -> Int
    lineNo LineNo
    lno)

    tokenToHtml :: FormatOptions -> Token -> Html
    tokenToHtml :: FormatOptions -> Token -> Html
    tokenToHtml FormatOptions
    _ (TokenType
    NormalTok, Text
    txt)  = Text -> Html
    forall a. ToMarkup a => a -> Html
    toHtml Text
    txt
    tokenToHtml FormatOptions
    opts (TokenType
    toktype, Text
    txt) =
      if FormatOptions -> Bool
    titleAttributes FormatOptions
    opts
         then Html
    sp Html -> Attribute -> Html
    forall h. Attributable h => h -> Attribute -> h
    ! AttributeValue -> Attribute
    A.title (String -> AttributeValue
    forall a. ToValue a => a -> AttributeValue
    toValue (String -> AttributeValue) -> String -> AttributeValue
    forall a b. (a -> b) -> a -> b
    $ TokenType -> String
    forall a. Show a => a -> String
    show TokenType
    toktype)
         else Html
    sp
       where sp :: Html
    sp = Html -> Html
    H.span (Html -> Html) -> Attribute -> Html -> Html
    forall h. Attributable h => h -> Attribute -> h
    ! AttributeValue -> Attribute
    A.class_ (String -> AttributeValue
    forall a. ToValue a => a -> AttributeValue
    toValue (String -> AttributeValue) -> String -> AttributeValue
    forall a b. (a -> b) -> a -> b
    $ TokenType -> String
    short TokenType
    toktype) (Html -> Html) -> Html -> Html
    forall a b. (a -> b) -> a -> b
    $ Text -> Html
    forall a. ToMarkup a => a -> Html
    toHtml Text
    txt

    short :: TokenType -> String
    short :: TokenType -> String
    short TokenType
    KeywordTok        = String
    "kw"
    short TokenType
    DataTypeTok       = String
    "dt"
    short TokenType
    DecValTok         = String
    "dv"
    short TokenType
    BaseNTok          = String
    "bn"
    short TokenType
    FloatTok          = String
    "fl"
    short TokenType
    CharTok           = String
    "ch"
    short TokenType
    StringTok         = String
    "st"
    short TokenType
    CommentTok        = String
    "co"
    short TokenType
    OtherTok          = String
    "ot"
    short TokenType
    AlertTok          = String
    "al"
    short TokenType
    FunctionTok       = String
    "fu"
    short TokenType
    RegionMarkerTok   = String
    "re"
    short TokenType
    ErrorTok          = String
    "er"
    short TokenType
    ConstantTok       = String
    "cn"
    short TokenType
    SpecialCharTok    = String
    "sc"
    short TokenType
    VerbatimStringTok = String
    "vs"
    short TokenType
    SpecialStringTok  = String
    "ss"
    short TokenType
    ImportTok         = String
    "im"
    short TokenType
    DocumentationTok  = String
    "do"
    short TokenType
    AnnotationTok     = String
    "an"
    short TokenType
    CommentVarTok     = String
    "cv"
    short TokenType
    VariableTok       = String
    "va"
    short TokenType
    ControlFlowTok    = String
    "cf"
    short TokenType
    OperatorTok       = String
    "op"
    short TokenType
    BuiltInTok        = String
    "bu"
    short TokenType
    ExtensionTok      = String
    "ex"
    short TokenType
    PreprocessorTok   = String
    "pp"
    short TokenType
    AttributeTok      = String
    "at"
    short TokenType
    InformationTok    = String
    "in"
    short TokenType
    WarningTok        = String
    "wa"
    short TokenType
    NormalTok         = String
    ""

    -- | Returns CSS for styling highlighted code according to the given style.
    styleToCss :: Style -> String
    styleToCss :: Style -> String
    styleToCss Style
    f = [String] -> String
    unlines ([String] -> String) -> [String] -> String
    forall a b. (a -> b) -> a -> b
    $
      [String]
    divspec [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String]
    numberspec [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String]
    colorspec [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String]
    linkspec [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++
        [String] -> [String]
    forall a. Ord a => [a] -> [a]
    sort (((TokenType, TokenStyle) -> String)
    -> [(TokenType, TokenStyle)] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (TokenType, TokenStyle) -> String
    toCss (Map TokenType TokenStyle -> [(TokenType, TokenStyle)]
    forall k a. Map k a -> [(k, a)]
    Map.toList (Style -> Map TokenType TokenStyle
    tokenStyles Style
    f)))
       where colorspec :: [String]
    colorspec = String -> [String]
    forall a. a -> [a]
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (String -> [String])
    -> ([String] -> String) -> [String] -> [String]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [String] -> String
    unwords ([String] -> [String]) -> [String] -> [String]
    forall a b. (a -> b) -> a -> b
    $ [
                String
    "div.sourceCode\n  {"
              , String -> (Color -> String) -> Maybe Color -> String
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe String
    "" (\Color
    c -> String
    "color: "            String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Color -> String
    forall a. FromColor a => Color -> a
    fromColor Color
    c String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    ";") (Style -> Maybe Color
    defaultColor Style
    f)
              , String -> (Color -> String) -> Maybe Color -> String
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe String
    "" (\Color
    c -> String
    "background-color: " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Color -> String
    forall a. FromColor a => Color -> a
    fromColor Color
    c String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    ";") (Style -> Maybe Color
    backgroundColor Style
    f)
              , String
    "}"
              ]
             numberspec :: [String]
    numberspec = [
                String
    "pre.numberSource code"
              , String
    "  { counter-reset: source-line 0; }"
              , String
    "pre.numberSource code > span"
              , String
    "  { position: relative; left: -4em; counter-increment: source-line; }"
              , String
    "pre.numberSource code > span > a:first-child::before"
              , String
    "  { content: counter(source-line);"
              , String
    "    position: relative; left: -1em; text-align: right; vertical-align: baseline;"
              , String
    "    border: none; display: inline-block;"
              , String
    "    -webkit-touch-callout: none; -webkit-user-select: none;"
              , String
    "    -khtml-user-select: none; -moz-user-select: none;"
              , String
    "    -ms-user-select: none; user-select: none;"
              , String
    "    padding: 0 4px; width: 4em;"
              , String -> (Color -> String) -> Maybe Color -> String
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe String
    "" (\Color
    c -> String
    "    background-color: " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Color -> String
    forall a. FromColor a => Color -> a
    fromColor Color
    c String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    ";\n")
                  (Style -> Maybe Color
    lineNumberBackgroundColor Style
    f) String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
                String -> (Color -> String) -> Maybe Color -> String
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe String
    "" (\Color
    c -> String
    "    color: " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Color -> String
    forall a. FromColor a => Color -> a
    fromColor Color
    c String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    ";\n")
                  (Style -> Maybe Color
    lineNumberColor Style
    f) String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
                String
    "  }"
              , String
    "pre.numberSource { margin-left: 3em; " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
                  String -> (Color -> String) -> Maybe Color -> String
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe String
    "" (\Color
    c -> String
    "border-left: 1px solid " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Color -> String
    forall a. FromColor a => Color -> a
    fromColor Color
    c String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    "; ") (Style -> Maybe Color
    lineNumberColor Style
    f) String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
                  String
    " padding-left: 4px; }"
              ]
             divspec :: [String]
    divspec = [
                String
    "html { -webkit-text-size-adjust: 100%; }" -- Work around iOS bug, see https://github.com/jgm/pandoc/issues/7248
              , String
    "pre > code.sourceCode { white-space: pre; position: relative; }" -- position relative needed for relative contents
              , String
    "pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }"
              , String
    "pre > code.sourceCode > span:empty { height: 1.2em; }" -- correct empty line height
              , String
    ".sourceCode { overflow: visible; }" -- needed for line numbers
              , String
    "code.sourceCode > span { color: inherit; text-decoration: inherit; }"
              , String
    "div.sourceCode { margin: 1em 0; }" -- Collapse neighbours correctly
              , String
    "pre.sourceCode { margin: 0; }" -- Collapse neighbours correctly
              , String
    "@media screen {"
              , String
    "div.sourceCode { overflow: auto; }" -- do not overflow on screen
              , String
    "}"
              , String
    "@media print {"
              , String
    "pre > code.sourceCode { white-space: pre-wrap; }"
              , String
    "pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }"
              , String
    "}"
              ]
             linkspec :: [String]
    linkspec = [ String
    "@media screen {"
              , String
    "pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }"
              , String
    "}"
              ]

    toCss :: (TokenType, TokenStyle) -> String
    toCss :: (TokenType, TokenStyle) -> String
    toCss (TokenType
    t,TokenStyle
    tf) = String
    "code span" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ (if String -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (TokenType -> String
    short TokenType
    t) then String
    "" else (Char
    '.' Char -> ShowS
    forall a. a -> [a] -> [a]
    : TokenType -> String
    short TokenType
    t)) String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " { "
                    String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    colorspec String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    backgroundspec String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    weightspec String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    stylespec
                    String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    decorationspec String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    "} /* " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ TokenType -> String
    forall a. Show a => a -> String
    showTokenType TokenType
    t String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " */"
      where colorspec :: String
    colorspec = String -> (Color -> String) -> Maybe Color -> String
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe String
    "" (\Color
    col -> String
    "color: " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Color -> String
    forall a. FromColor a => Color -> a
    fromColor Color
    col String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    "; ") (Maybe Color -> String) -> Maybe Color -> String
    forall a b. (a -> b) -> a -> b
    $ TokenStyle -> Maybe Color
    tokenColor TokenStyle
    tf
            backgroundspec :: String
    backgroundspec = String -> (Color -> String) -> Maybe Color -> String
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe String
    "" (\Color
    col -> String
    "background-color: " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Color -> String
    forall a. FromColor a => Color -> a
    fromColor Color
    col String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    "; ") (Maybe Color -> String) -> Maybe Color -> String
    forall a b. (a -> b) -> a -> b
    $ TokenStyle -> Maybe Color
    tokenBackground TokenStyle
    tf
            weightspec :: String
    weightspec = if TokenStyle -> Bool
    tokenBold TokenStyle
    tf then String
    "font-weight: bold; " else String
    ""
            stylespec :: String
    stylespec  = if TokenStyle -> Bool
    tokenItalic TokenStyle
    tf then String
    "font-style: italic; " else String
    ""
            decorationspec :: String
    decorationspec = if TokenStyle -> Bool
    tokenUnderline TokenStyle
    tf then String
    "text-decoration: underline; " else String
    ""
            showTokenType :: a -> String
    showTokenType a
    t' = case ShowS
    forall a. [a] -> [a]
    reverse (a -> String
    forall a. Show a => a -> String
    show a
    t') of
                                 Char
    'k':Char
    'o':Char
    'T':String
    xs -> ShowS
    forall a. [a] -> [a]
    reverse String
    xs
                                 String
    _              -> String
    ""