skylighting-format-latex (empty) → 0.1
raw patch · 4 files changed
+223/−0 lines, 4 filesdep +basedep +containersdep +skylighting-core
Dependencies added: base, containers, skylighting-core, text
Files
- LICENSE +30/−0
- README.md +5/−0
- skylighting-format-latex.cabal +36/−0
- src/Skylighting/Format/LaTeX.hs +152/−0
+ LICENSE view
@@ -0,0 +1,30 @@+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.
+ README.md view
@@ -0,0 +1,5 @@+# skylighting-format-ansi++This package provides functions to render syntax-highlighting+as ANSI text.+
+ skylighting-format-latex.cabal view
@@ -0,0 +1,36 @@+name: skylighting-format-latex+version: 0.1+synopsis: LaTeX formatter for skylighting syntax highlighting library+description: This module allows tokens produced by skylighting-core+ to be rendered as LaTeX macros.+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++cabal-version: >=1.10++source-repository head+ type: git+ location: https://github.com/jgm/skylighting.git++library+ exposed-modules: Skylighting.Format.LaTeX+ other-extensions: CPP+ build-depends: base >= 4.8 && < 5.0,+ skylighting-core,+ text,+ containers+ 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
+ src/Skylighting/Format/LaTeX.hs view
@@ -0,0 +1,152 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+module Skylighting.Format.LaTeX (+ formatLaTeXInline+ , formatLaTeXBlock+ , styleToLaTeX+ ) where++import Control.Monad (mplus)+import Data.Char (isSpace)+import Data.List (sort)+import qualified Data.Map as Map+import Data.Text (Text)+import qualified Data.Text as Text+import Skylighting.Types+import Text.Printf+#if !MIN_VERSION_base(4,11,0)+import Data.Semigroup+#endif++formatLaTeX :: Bool -> [SourceLine] -> Text+formatLaTeX inline = Text.intercalate (Text.singleton '\n')+ . map (sourceLineToLaTeX inline)++-- | Formats tokens as LaTeX using custom commands inside+-- @|@ characters. Assumes that @|@ is defined as a short verbatim+-- command by the macros produced by 'styleToLaTeX'.+-- A @KeywordTok@ is rendered using @\\KeywordTok{..}@, and so on.+formatLaTeXInline :: FormatOptions -> [SourceLine] -> Text+formatLaTeXInline _opts ls = "\\VERB|" <> formatLaTeX True ls <> "|"++sourceLineToLaTeX :: Bool -> SourceLine -> Text+sourceLineToLaTeX inline = mconcat . map (tokenToLaTeX inline)++tokenToLaTeX :: Bool -> Token -> Text+tokenToLaTeX inline (NormalTok, txt)+ | Text.all isSpace txt = escapeLaTeX inline txt+tokenToLaTeX inline (toktype, txt) = Text.cons '\\'+ (Text.pack (show toktype) <> "{" <> escapeLaTeX inline txt <> "}")++escapeLaTeX :: Bool -> Text -> Text+escapeLaTeX inline = Text.concatMap escapeLaTeXChar+ where escapeLaTeXChar c =+ case c of+ '\\' -> "\\textbackslash{}"+ '{' -> "\\{"+ '}' -> "\\}"+ '|' | inline -> "\\VerbBar{}" -- used in inline verbatim+ '_' -> "\\_"+ '&' -> "\\&"+ '%' -> "\\%"+ '#' -> "\\#"+ '`' -> "\\textasciigrave{}"+ '\'' -> "\\textquotesingle{}"+ '-' -> "{-}" -- prevent ligatures+ '~' -> "\\textasciitilde{}"+ '^' -> "\\^{}"+ '>' -> "\\textgreater{}"+ '<' -> "\\textless{}"+ _ -> Text.singleton c++-- LaTeX++-- | Format tokens as a LaTeX @Highlighting@ environment inside a+-- @Shaded@ environment. @Highlighting@ and @Shaded@ are+-- defined by the macros produced by 'styleToLaTeX'. @Highlighting@+-- is a verbatim environment using @fancyvrb@; @\\@, @{@, and @}@+-- have their normal meanings inside this environment, so that+-- formatting commands work. @Shaded@ is either nothing+-- (if the style's background color is default) or a @snugshade@+-- environment from @framed@, providing a background color+-- for the whole code block, even if it spans multiple pages.+formatLaTeXBlock :: FormatOptions -> [SourceLine] -> Text+formatLaTeXBlock opts ls = Text.unlines+ ["\\begin{Shaded}"+ ,"\\begin{Highlighting}[" <>+ (if numberLines opts+ then "numbers=left," <>+ (if startNumber opts == 1+ then ""+ else ",firstnumber=" <>+ Text.pack (show (startNumber opts))) <> ","+ else Text.empty) <> "]"+ ,formatLaTeX False ls+ ,"\\end{Highlighting}"+ ,"\\end{Shaded}"]++-- | Converts a 'Style' to a set of LaTeX macro definitions,+-- which should be placed in the document's preamble.+-- Note: default LaTeX setup doesn't allow boldface typewriter font.+-- To make boldface work in styles, you need to use a different typewriter+-- font. This will work for computer modern:+--+-- > \DeclareFontShape{OT1}{cmtt}{bx}{n}{<5><6><7><8><9><10><10.95><12><14.4><17.28><20.74><24.88>cmttb10}{}+--+-- Or, with xelatex:+--+-- > \usepackage{fontspec}+-- > \setmainfont[SmallCapsFont={* Caps}]{Latin Modern Roman}+-- > \setsansfont{Latin Modern Sans}+-- > \setmonofont[SmallCapsFont={Latin Modern Mono Caps}]{Latin Modern Mono Light}+--+styleToLaTeX :: Style -> Text+styleToLaTeX f = Text.unlines $+ [ "\\usepackage{color}"+ , "\\usepackage{fancyvrb}"+ , "\\newcommand{\\VerbBar}{|}"+ , "\\newcommand{\\VERB}{\\Verb[commandchars=\\\\\\{\\}]}"+ , "\\DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\\\\{\\}}"+ , "% Add ',fontsize=\\small' for more characters per line"+ ] +++ (case backgroundColor f of+ Nothing -> ["\\newenvironment{Shaded}{}{}"]+ Just (RGB r g b) -> ["\\usepackage{framed}"+ ,Text.pack+ (printf "\\definecolor{shadecolor}{RGB}{%d,%d,%d}" r g b)+ ,"\\newenvironment{Shaded}{\\begin{snugshade}}{\\end{snugshade}}"])+ ++ sort (map (macrodef (defaultColor f) (Map.toList (tokenStyles f)))+ (enumFromTo KeywordTok NormalTok))++macrodef :: Maybe Color -> [(TokenType, TokenStyle)] -> TokenType -> Text+macrodef defaultcol tokstyles tokt = "\\newcommand{\\"+ <> Text.pack (show tokt)+ <> "}[1]{"+ <> Text.pack (co . ul . bf . it . bg $ "#1")+ <> "}"+ where tokf = case lookup tokt tokstyles of+ Nothing -> defStyle+ Just x -> x+ ul x = if tokenUnderline tokf+ then "\\underline{" <> x <> "}"+ else x+ it x = if tokenItalic tokf+ then "\\textit{" <> x <> "}"+ else x+ bf x = if tokenBold tokf+ then "\\textbf{" <> x <> "}"+ else x+ bcol = fromColor `fmap` tokenBackground tokf+ :: Maybe (Double, Double, Double)+ bg x = case bcol of+ Nothing -> x+ Just (r, g, b) ->+ printf "\\colorbox[rgb]{%0.2f,%0.2f,%0.2f}{%s}" r g b x+ col = fromColor `fmap` (tokenColor tokf `mplus` defaultcol)+ :: Maybe (Double, Double, Double)+ co x = case col of+ Nothing -> x+ Just (r, g, b) ->+ printf "\\textcolor[rgb]{%0.2f,%0.2f,%0.2f}{%s}" r g b x+