skylighting-format-blaze-html-0.1.1.1/ 0000755 0000000 0000000 00000000000 07346545000 015720 5 ustar 00 0000000 0000000 skylighting-format-blaze-html-0.1.1.1/LICENSE 0000644 0000000 0000000 00000002730 07346545000 016727 0 ustar 00 0000000 0000000 Copyright (c) 2016-2018, John MacFarlane.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* The names of the contributors may not be used to endorse or
promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
skylighting-format-blaze-html-0.1.1.1/README.md 0000644 0000000 0000000 00000000323 07346545000 017175 0 ustar 00 0000000 0000000 # skylighting-format-blaze-html
This package provides functions to render syntax-highlighting as HTML
using the [blaze-html](https://hackage.haskell.org/package/blaze-html)
HTML combinator library for Haskell.
skylighting-format-blaze-html-0.1.1.1/changelog.md 0000644 0000000 0000000 00000000453 07346545000 020173 0 ustar 00 0000000 0000000 # Changelog for skylighting-format-blaze-html
## 0.1.1.1
* Remove `display: inline-block` from the code line spans. This
caused odd size changes in iOS. Closes #7248.
## 0.1.1
* Export `formatHtml4Block`, which should be used instead of
`formatHtmlBlock` if HTML4 compliance is required.
skylighting-format-blaze-html-0.1.1.1/skylighting-format-blaze-html.cabal 0000644 0000000 0000000 00000002414 07346545000 024564 0 ustar 00 0000000 0000000 name: skylighting-format-blaze-html
version: 0.1.1.1
synopsis: HTML formatter for skylighting syntax highlighting library
description: This module allows tokens produced by skylighting-core
to be rendered as HTML.
homepage: https://github.com/jgm/skylighting
license: BSD3
license-file: LICENSE
author: John MacFarlane
maintainer: jgm@berkeley.edu
copyright: (C) 2016-2022 John MacFarlane
category: Text
build-type: Simple
extra-source-files: README.md, changelog.md
cabal-version: >=1.10
source-repository head
type: git
location: https://github.com/jgm/skylighting.git
library
exposed-modules: Skylighting.Format.HTML
other-extensions: CPP
build-depends: base >= 4.8 && < 5.0,
skylighting-core,
text,
containers,
blaze-html >= 0.5
hs-source-dirs: src
ghc-prof-options: -fprof-auto-exported
default-language: Haskell2010
ghc-options: -Wall
if impl(ghc >= 8.4)
ghc-options: -fhide-source-paths
if impl(ghc >= 8.10)
ghc-options: -Wunused-packages
skylighting-format-blaze-html-0.1.1.1/src/Skylighting/Format/ 0000755 0000000 0000000 00000000000 07346545000 022233 5 ustar 00 0000000 0000000 skylighting-format-blaze-html-0.1.1.1/src/Skylighting/Format/HTML.hs 0000644 0000000 0000000 00000023034 07346545000 023335 0 ustar 00 0000000 0000000 {-# 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 opts = wrapCode opts
. mconcat . intersperse (toHtml "\n")
. map (mapM_ (tokenToHtml 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 = formatHtmlBlockFor 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 = formatHtmlBlockFor Html4
data HtmlVersion = Html4 | Html5
deriving (Show, Eq)
formatHtmlBlockFor :: HtmlVersion -> FormatOptions -> [SourceLine] -> Html
formatHtmlBlockFor htmlVersion opts ls =
H.div ! A.class_ (toValue "sourceCode") $
H.pre ! A.class_ (toValue $ Text.unwords classes)
$ wrapCode opts
$ mconcat . intersperse (toHtml "\n")
$ zipWith (sourceLineToHtml htmlVersion opts) [startNum..] ls
where classes = Text.pack "sourceCode" :
[Text.pack "numberSource" | numberLines opts] ++
[x | x <- containerClasses opts
, x /= Text.pack "sourceCode"]
startNum = LineNo $ startNumber opts
wrapCode :: FormatOptions -> Html -> Html
wrapCode opts h = H.code ! A.class_ (toValue $ Text.unwords
$ Text.pack "sourceCode"
: codeClasses opts)
!? (startZero /= 0, A.style (toValue counterOverride))
$ h
where counterOverride = "counter-reset: source-line " <> show startZero <> ";"
startZero = startNumber opts - 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 opts lno cont =
H.span ! A.id lineNum
$ do
H.a ! A.href lineRef
! (if numberLines opts || htmlVersion == Html4
then mempty
else customAttribute (fromString "aria-hidden")
(fromString "true")) -- see jgm/pandoc#6352
! (if numberLines opts
then mempty
else customAttribute (fromString "tabindex")
(fromString "-1"))
$ mempty
mapM_ (tokenToHtml opts) cont
where lineNum = toValue prefixedLineNo
lineRef = toValue ('#':prefixedLineNo)
prefixedLineNo = Text.unpack (lineIdPrefix opts) <> show (lineNo lno)
tokenToHtml :: FormatOptions -> Token -> Html
tokenToHtml _ (NormalTok, txt) = toHtml txt
tokenToHtml opts (toktype, txt) =
if titleAttributes opts
then sp ! A.title (toValue $ show toktype)
else sp
where sp = H.span ! A.class_ (toValue $ short toktype) $ toHtml txt
short :: TokenType -> String
short KeywordTok = "kw"
short DataTypeTok = "dt"
short DecValTok = "dv"
short BaseNTok = "bn"
short FloatTok = "fl"
short CharTok = "ch"
short StringTok = "st"
short CommentTok = "co"
short OtherTok = "ot"
short AlertTok = "al"
short FunctionTok = "fu"
short RegionMarkerTok = "re"
short ErrorTok = "er"
short ConstantTok = "cn"
short SpecialCharTok = "sc"
short VerbatimStringTok = "vs"
short SpecialStringTok = "ss"
short ImportTok = "im"
short DocumentationTok = "do"
short AnnotationTok = "an"
short CommentVarTok = "cv"
short VariableTok = "va"
short ControlFlowTok = "cf"
short OperatorTok = "op"
short BuiltInTok = "bu"
short ExtensionTok = "ex"
short PreprocessorTok = "pp"
short AttributeTok = "at"
short InformationTok = "in"
short WarningTok = "wa"
short NormalTok = ""
-- | Returns CSS for styling highlighted code according to the given style.
styleToCss :: Style -> String
styleToCss f = unlines $
divspec ++ numberspec ++ colorspec ++ linkspec ++
sort (map toCss (Map.toList (tokenStyles f)))
where colorspec = pure . unwords $ [
"div.sourceCode\n {"
, maybe "" (\c -> "color: " ++ fromColor c ++ ";") (defaultColor f)
, maybe "" (\c -> "background-color: " ++ fromColor c ++ ";") (backgroundColor f)
, "}"
]
numberspec = [
"pre.numberSource code"
, " { counter-reset: source-line 0; }"
, "pre.numberSource code > span"
, " { position: relative; left: -4em; counter-increment: source-line; }"
, "pre.numberSource code > span > a:first-child::before"
, " { content: counter(source-line);"
, " position: relative; left: -1em; text-align: right; vertical-align: baseline;"
, " border: none; display: inline-block;"
, " -webkit-touch-callout: none; -webkit-user-select: none;"
, " -khtml-user-select: none; -moz-user-select: none;"
, " -ms-user-select: none; user-select: none;"
, " padding: 0 4px; width: 4em;"
, maybe "" (\c -> " background-color: " ++ fromColor c ++ ";\n")
(lineNumberBackgroundColor f) ++
maybe "" (\c -> " color: " ++ fromColor c ++ ";\n")
(lineNumberColor f) ++
" }"
, "pre.numberSource { margin-left: 3em; " ++
maybe "" (\c -> "border-left: 1px solid " ++ fromColor c ++ "; ") (lineNumberColor f) ++
" padding-left: 4px; }"
]
divspec = [
"pre > code.sourceCode { white-space: pre; position: relative; }" -- position relative needed for relative contents
, "pre > code.sourceCode > span { line-height: 1.25; }"
, "pre > code.sourceCode > span:empty { height: 1.2em; }" -- correct empty line height
, ".sourceCode { overflow: visible; }" -- needed for line numbers
, "code.sourceCode > span { color: inherit; text-decoration: inherit; }"
, "div.sourceCode { margin: 1em 0; }" -- Collapse neighbours correctly
, "pre.sourceCode { margin: 0; }" -- Collapse neighbours correctly
, "@media screen {"
, "div.sourceCode { overflow: auto; }" -- do not overflow on screen
, "}"
, "@media print {"
, "pre > code.sourceCode { white-space: pre-wrap; }"
, "pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }"
, "}"
]
linkspec = [ "@media screen {"
, "pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }"
, "}"
]
toCss :: (TokenType, TokenStyle) -> String
toCss (t,tf) = "code span" ++ (if null (short t) then "" else ('.' : short t)) ++ " { "
++ colorspec ++ backgroundspec ++ weightspec ++ stylespec
++ decorationspec ++ "} /* " ++ showTokenType t ++ " */"
where colorspec = maybe "" (\col -> "color: " ++ fromColor col ++ "; ") $ tokenColor tf
backgroundspec = maybe "" (\col -> "background-color: " ++ fromColor col ++ "; ") $ tokenBackground tf
weightspec = if tokenBold tf then "font-weight: bold; " else ""
stylespec = if tokenItalic tf then "font-style: italic; " else ""
decorationspec = if tokenUnderline tf then "text-decoration: underline; " else ""
showTokenType t' = case reverse (show t') of
'k':'o':'T':xs -> reverse xs
_ -> ""