skylighting 0.4.4.1 → 0.5
raw patch · 7 files changed
+109/−38 lines, 7 filesdep ~aeson
Dependency ranges changed: aeson
Files
- changelog.md +27/−0
- skylighting.cabal +1/−1
- src/Skylighting/Format/HTML.hs +27/−12
- src/Skylighting/Format/LaTeX.hs +4/−1
- src/Skylighting/Styles.hs +9/−8
- src/Skylighting/Types.hs +38/−15
- test/test-skylighting.hs +3/−1
changelog.md view
@@ -1,5 +1,32 @@ # Revision history for skylighting +## 0.5 -- 2017-12-10++ * Fix line spacing and overflowing content in generated HTML+ (David Baynard, #25, see jgm/pandoc#4128).++ + Fix empty line height, explicitly+ + Ensure long lines scroll on screen+ + Only apply colour to the outer div+ + Don't reset line number colour+ + Fix borders on empty code lines+ + Collapse divs correctly.++ * Changes to Style types and JSON instances. Previously we could not+ successfully round-trip through JSON.++ + `tokenStyles` is now a map rather than an association list.+ + We now use `line-number-color` instead of `line-numbers` at+ the top level in the JSON instances, falling back to+ `line-numbers` in `editor-colors`, for KDE theme compatibility.+ + We use `line-number-background-color` at the top level, falling+ back to the text background color.+ + We use `text-color` at the top level, falling back to the `text-color`+ of the `Normal` token style if it exists, for KDE compatibility.+ + We use `background-color` at the top level, falling back to+ the `background-color` in `editor-colors`, for KDE compatibility.+ + A round-trip JSON test has been added.+ ## 0.4.4.1 -- 2017-11-27 * HTML formatting: fix color, bgcolor when numbering enabled.
skylighting.cabal view
@@ -1,5 +1,5 @@ name: skylighting-version: 0.4.4.1+version: 0.5 synopsis: syntax highlighting library description: Skylighting is a syntax highlighting library with support for over one hundred languages. It derives
src/Skylighting/Format/HTML.hs view
@@ -4,7 +4,8 @@ , styleToCss ) where -import Data.List (intersperse)+import Data.List (intersperse, sort)+import qualified Data.Map as Map import Data.Monoid ((<>)) import Data.String (fromString) import qualified Data.Text as Text@@ -60,6 +61,7 @@ -- tokens are encoded. formatHtmlBlock :: FormatOptions -> [SourceLine] -> Html formatHtmlBlock opts ls =+ H.div ! A.class_ (toValue "sourceCode") $ H.pre ! A.class_ (toValue $ Text.unwords classes) $ wrapCode opts $ mconcat . intersperse (toHtml "\n")@@ -137,16 +139,23 @@ -- | Returns CSS for styling highlighted code according to the given style. styleToCss :: Style -> String-styleToCss f = unlines $ divspec ++ numberspec ++ colorspec ++ linkspec ++ map toCss (tokenStyles f)- where colorspec = case (defaultColor f, backgroundColor f) of- (Nothing, Nothing) -> []- (Just c, Nothing) -> ["pre, code { color: " ++ fromColor c ++ "; }"]- (Nothing, Just c) -> ["pre, code { background-color: " ++ fromColor c ++ "; }"]- (Just c1, Just c2) -> ["pre, code { color: " ++ fromColor c1 ++ "; background-color: " ++- fromColor c2 ++ "; }"]+styleToCss f = unlines $+ divspec ++ numberspec ++ colorspec ++ linkspec +++ sort (map toCss (Map.toList (tokenStyles f)))+ where colorspec = [+ "div.sourceCode\n { "+ ++ case (defaultColor f, backgroundColor f) of+ (Nothing, Nothing) -> ""+ (Just c, Nothing) -> "color: " ++ fromColor c ++ ";"+ (Nothing, Just c) -> "background-color: " ++ fromColor c ++ ";"+ (Just c1, Just c2) -> "color: " ++ fromColor c1+ ++ "; background-color: " ++ fromColor c2 ++ ";"+ ++ " }"] numberspec = [ "pre.numberSource a.sourceLine" , " { position: relative; }"+ , "pre.numberSource a.sourceLine:empty"+ , " { position: absolute; }" , "pre.numberSource a.sourceLine::before" , " { content: attr(data-line-number);" , " position: absolute; left: -5em; text-align: right; vertical-align: baseline;"@@ -165,17 +174,23 @@ " padding-left: 4px; }" ] divspec = [- "a.sourceLine { display: inline-block; min-height: 1.25em; }"+ "a.sourceLine { display: inline-block; line-height: 1.25; }" , "a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }"- , ".sourceCode { overflow: visible; }"- , "code.sourceCode { white-space: pre; }"+ , "a.sourceLine:empty { height: 1.2em; position: absolute; }" -- correct empty line height+ , ".sourceCode { overflow: visible; }" -- needed for line numbers+ , "code.sourceCode { white-space: pre; position: relative; }" -- position relative needed for absolute contents+ , "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 {" , "code.sourceCode { white-space: pre-wrap; }" , "a.sourceLine { text-indent: -1em; padding-left: 1em; }" , "}" ] linkspec = [ "@media screen {"- , "a.sourceLine::before { text-decoration: underline; color: initial; }"+ , "a.sourceLine::before { text-decoration: underline; }" , "}" ]
src/Skylighting/Format/LaTeX.hs view
@@ -7,7 +7,9 @@ ) where import Control.Monad (mplus)+import qualified Data.Map as Map import Data.Char (isSpace)+import Data.List (sort) import Data.Monoid import Data.Text (Text) import qualified Data.Text as Text@@ -100,7 +102,8 @@ ,Text.pack (printf "\\definecolor{shadecolor}{RGB}{%d,%d,%d}" r g b) ,"\\newenvironment{Shaded}{\\begin{snugshade}}{\\end{snugshade}}"])- ++ map (macrodef (defaultColor f) (tokenStyles f)) (enumFromTo KeywordTok NormalTok)+ ++ sort (map (macrodef (defaultColor f) (Map.toList (tokenStyles f)))+ (enumFromTo KeywordTok NormalTok)) macrodef :: Maybe Color -> [(TokenType, TokenStyle)] -> TokenType -> Text macrodef defaultcol tokstyles tokt = "\\newcommand{\\"
src/Skylighting/Styles.hs view
@@ -9,6 +9,7 @@ , monochrome , zenburn) where +import qualified Data.Map as Map import Data.Aeson (eitherDecode) import Data.ByteString.Lazy (ByteString) import Skylighting.Types@@ -23,7 +24,7 @@ -- | Style based on kate's default colors. kate :: Style kate = Style{- tokenStyles =+ tokenStyles = Map.fromList [ ( KeywordTok, defStyle { tokenColor = Just (RGB 31 28 27), tokenBold = True }) , ( DataTypeTok, defStyle { tokenColor = Just (RGB 0 87 174) }) , ( DecValTok, defStyle { tokenColor = Just (RGB 176 128 0) })@@ -65,7 +66,7 @@ -- | Style from the breeze-dark KDE syntax highlighting theme. breezeDark :: Style breezeDark = Style- { tokenStyles =+ { tokenStyles = Map.fromList [ ( KeywordTok, defStyle { tokenColor = Just (RGB 207 207 194) }) , ( DataTypeTok, defStyle { tokenColor = Just (RGB 41 128 185) }) , ( DecValTok, defStyle { tokenColor = Just (RGB 246 116 0) })@@ -111,7 +112,7 @@ , defaultColor = Nothing , lineNumberColor = color 0xaaaaaa , lineNumberBackgroundColor = Nothing- , tokenStyles =+ , tokenStyles = Map.fromList [ (KeywordTok, defStyle{ tokenColor = color 0x007020, tokenBold = True }) , (DataTypeTok, defStyle{ tokenColor = color 0x902000 }) , (DecValTok, defStyle{ tokenColor = color 0x40a070 })@@ -152,7 +153,7 @@ , defaultColor = Nothing , lineNumberColor = color 0xaaaaaa , lineNumberBackgroundColor = Nothing- , tokenStyles =+ , tokenStyles = Map.fromList [ (KeywordTok, defStyle{ tokenColor = color 0x204a87, tokenBold = True }) , (DataTypeTok, defStyle{ tokenColor = color 0x204a87 }) , (DecValTok, defStyle{ tokenColor = color 0x0000cf })@@ -191,7 +192,7 @@ , defaultColor = color 0xBDAE9D , lineNumberColor = color 0xBDAE9D , lineNumberBackgroundColor = color 0x2A211C- , tokenStyles =+ , tokenStyles = Map.fromList [ (KeywordTok, defStyle{ tokenColor = color 0x43A8ED, tokenBold = True }) , (DataTypeTok, defStyle{ tokenUnderline = True }) , (DecValTok, defStyle{ tokenColor = color 0x44AA43 })@@ -230,7 +231,7 @@ , defaultColor = Nothing , lineNumberColor = color 0xaaaaaa , lineNumberBackgroundColor = Nothing- , tokenStyles =+ , tokenStyles = Map.fromList [ (KeywordTok, defStyle{ tokenColor = color 0x0000FF }) , (CharTok, defStyle{ tokenColor = color 0x008080 }) , (StringTok, defStyle{ tokenColor = color 0x008080 })@@ -265,7 +266,7 @@ , defaultColor = Nothing , lineNumberColor = Nothing , lineNumberBackgroundColor = Nothing- , tokenStyles =+ , tokenStyles = Map.fromList [ (KeywordTok, defStyle{ tokenBold = True }) , (DataTypeTok, defStyle{ tokenUnderline = True }) , (CommentTok, defStyle{ tokenItalic = True })@@ -288,7 +289,7 @@ , defaultColor = color 0xcccccc , lineNumberColor = Nothing , lineNumberBackgroundColor = Nothing- , tokenStyles =+ , tokenStyles = Map.fromList [ (KeywordTok, defStyle{ tokenColor = color 0xf0dfaf }) , (DataTypeTok, defStyle{ tokenColor = color 0xdfdfbf }) , (DecValTok, defStyle{ tokenColor = color 0xdcdccc })
src/Skylighting/Types.hs view
@@ -37,11 +37,14 @@ , defaultFormatOpts ) where +import Control.Monad (mplus)+import Data.Aeson.Types (toJSONKeyText) import Data.Aeson import Data.Bits import Data.CaseInsensitive (FoldCase(..)) import Data.Binary (Binary) import Data.Data (Data)+import Data.Maybe (fromMaybe) import qualified Data.Map as Map import qualified Data.Set as Set import Data.Text (Text)@@ -208,15 +211,25 @@ instance Binary TokenType instance ToJSON TokenType where- toEncoding t = toEncoding (Text.stripSuffix "Tok" $ Text.pack $ show t)+ toEncoding = toEncoding . Text.stripSuffix "Tok" . Text.pack . show --- | JSON @"Keyword"@ corresponds to 'KeywordTok', and so on.+instance ToJSONKey TokenType where+ toJSONKey = toJSONKeyText+ (fromMaybe "Unknown" . Text.stripSuffix "Tok" . Text.pack . show)+ instance FromJSON TokenType where parseJSON (String t) =+ case readMay (Text.unpack t ++ "Tok") of+ Just tt -> return tt+ Nothing -> fail "Not a token type"+ parseJSON _ = mempty++-- | JSON @"Keyword"@ corresponds to 'KeywordTok', and so on.+instance FromJSONKey TokenType where+ fromJSONKey = FromJSONKeyTextParser (\t -> case readMay (Text.unpack t ++ "Tok") of Just tt -> return tt- Nothing -> fail "Not a token type"- parseJSON _ = mempty+ Nothing -> fail "Not a token type") -- | A line of source: a list of labeled tokens. type SourceLine = [Token]@@ -327,7 +340,7 @@ -- color for normal tokens. Line numbers can have a different -- color and background color. data Style = Style {- tokenStyles :: [(TokenType, TokenStyle)]+ tokenStyles :: Map.Map TokenType TokenStyle , defaultColor :: Maybe Color , backgroundColor :: Maybe Color , lineNumberColor :: Maybe Color@@ -342,15 +355,23 @@ instance FromJSON Style where parseJSON (Object v) = do (tokstyles :: Map.Map Text TokenStyle) <- v .: "text-styles"- (editorColors :: Map.Map Text Color) <- v .: "editor-colors"- return Style{ defaultColor = case Map.lookup "Normal" tokstyles of- Nothing -> Nothing- Just ts -> tokenColor ts- , backgroundColor = Map.lookup "background-color" editorColors- , lineNumberColor = Map.lookup "line-numbers" editorColors- , lineNumberBackgroundColor = Map.lookup "background-color"- editorColors- , tokenStyles = Map.toList $+ (editorColors :: Map.Map Text Color) <- v .:? "editor-colors" .!= mempty+ mbBackgroundColor <- v .:? "background-color"+ mbLineNumberColor <- v .:? "line-number-color"+ mbDefaultColor <- v .:? "text-color"+ mbLineNumberBackgroundColor <- v .:? "line-number-background-color"+ return Style{ defaultColor = mbDefaultColor `mplus`+ (case Map.lookup "Normal" tokstyles of+ Nothing -> Nothing+ Just ts -> tokenColor ts)+ , backgroundColor = mbBackgroundColor `mplus`+ Map.lookup "background-color" editorColors+ , lineNumberColor = mbLineNumberColor `mplus`+ Map.lookup "line-numbers" editorColors+ , lineNumberBackgroundColor =+ mbLineNumberBackgroundColor `mplus`+ Map.lookup "background-color" editorColors+ , tokenStyles = Map.mapKeys (\s -> maybe OtherTok id $ readMay (Text.unpack s ++ "Tok")) tokstyles } parseJSON _ = mempty@@ -359,7 +380,9 @@ toJSON s = object [ "text-styles" .= toJSON (tokenStyles s) , "background-color" .= toJSON (backgroundColor s) , "text-color" .= toJSON (defaultColor s)- , "line-numbers" .= toJSON (lineNumberColor s)+ , "line-number-color" .= toJSON (lineNumberColor s)+ , "line-number-background-color" .=+ toJSON (lineNumberBackgroundColor s) ] -- | Options for formatting source code.
test/test-skylighting.hs view
@@ -2,7 +2,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} module Main where-import Data.Aeson (decode)+import Data.Aeson (decode, encode) import Data.Monoid ((<>)) import Data.Algorithm.Diff import qualified Data.ByteString.Lazy as BL@@ -58,6 +58,8 @@ decode "{ \"text-color\": \"#1f1c1b\", \"bold\": true }" , testCase "decode KDE theme to Style" $ Just kate @=? decode defaultTheme+ , testCase "round trip style -> theme -> style" $+ Just kate @=? decode (encode kate) ] , testGroup "Skylighting.Regex" $ [ testCase "convertOctalEscapes" $