packages feed

hpygments (empty) → 0.1.0

raw patch · 9 files changed

+370/−0 lines, 9 filesdep +aesondep +basedep +bytestringsetup-changed

Dependencies added: aeson, base, bytestring, process, process-extras

Files

+ LICENSE view
@@ -0,0 +1,19 @@+Copyright (c) 2012 David Lazar <lazar6@illinois.edu>++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.
+ README.md view
@@ -0,0 +1,10 @@+# About++**hpygments** is a Haskell library for highlighting source code using [Pygments](http://pygments.org).+See the [Hackage page](http://hackage.haskell.org/package/hpygments) for documentation and examples.++# Contributing++This project is available on [GitHub](https://github.com/davidlazar/hpygments) and [Bitbucket](https://bitbucket.org/davidlazar/hpygments/). You may contribute changes using either.++Please report bugs and feature requests using the [GitHub issue tracker](https://github.com/davidlazar/hpygments/issues).
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ hpygments.cabal view
@@ -0,0 +1,44 @@+Name:               hpygments+Version:            0.1.0+Synopsis:           Highlight source code using Pygments+Description:+    Highlight source code using Pygments <http://pygments.org>. This package+    depends on Pygments and its accompanying @pygmentize@ script.+License:            MIT+License-file:       LICENSE+Author:             David Lazar+Maintainer:         David Lazar <lazar6@illinois.edu>+Category:           Text+Build-type:         Simple+Cabal-version:      >=1.6++Extra-source-files:+    README.md++Data-files:+    pygments_dump_json.py++source-repository head+  Type:             git+  Location:         https://github.com/davidlazar/hpygments++Library+  ghc-options:      -Wall++  Hs-source-dirs:   src++  Exposed-modules:+    Text.Highlighting.Pygments+    Text.Highlighting.Pygments.Lexers+    Text.Highlighting.Pygments.Formatters++  Other-modules:+    Text.Highlighting.Pygments.JSON+    Paths_hpygments++  Build-depends:+    base >= 4 && < 5,+    bytestring,+    process,+    process-extras >= 0.1.3,+    aeson == 0.6.0.*
+ pygments_dump_json.py view
@@ -0,0 +1,29 @@+#!/usr/bin/env python+import sys+import json+from pygments.lexers import get_all_lexers+from pygments.formatters import get_all_formatters++def lexer_dict(name, aliases, filetypes, mimetypes):+    return { '_lexerName': name+           , '_lexerAliases': list(aliases)+           , '_lexerFileTypes': list(filetypes)+           , '_lexerMimeTypes': list(mimetypes)+           }++def formatter_dict(f):+    return { '_formatterName': f.name+           , '_formatterAliases': list(f.aliases)+           }++if len(sys.argv) < 2:+    print('Usage: {} (lexers|formatters)'.format(sys.argv[0]))+    sys.exit(1)++if sys.argv[1] == "lexers":+    lexers = [lexer_dict(*x) for x in get_all_lexers()]+    json.dump(lexers, sys.stdout)++if sys.argv[1] == "formatters":+    formatters = [formatter_dict(x) for x in get_all_formatters()]+    json.dump(formatters, sys.stdout)
+ src/Text/Highlighting/Pygments.hs view
@@ -0,0 +1,99 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  Text.Highlighting.Pygments+-- Copyright   :  (c) David Lazar, 2012+-- License     :  MIT+--+-- Maintainer  :  lazar6@illinois.edu+-- Stability   :  experimental+-- Portability :  unknown+--+-- This library uses the @pygmentize@ script that comes with Pygments to+-- highlight code in many languages. For documentation on the various lexers,+-- formatters, and options, see the Pygments documentation+-- <http://pygments.org/docs/>.+-----------------------------------------------------------------------------++module Text.Highlighting.Pygments+    (+      highlight+    , pygmentize++    , module Text.Highlighting.Pygments.Lexers+    , module Text.Highlighting.Pygments.Formatters++    -- * Options+    , Option+    , Options++    -- * Examples+    -- $examples+    ) where++import System.Process (readProcess)++import Text.Highlighting.Pygments.Lexers+import Text.Highlighting.Pygments.Formatters++-- | Highlight code robustly. This function is more robust than the+-- lower-level 'pygmentize' function since this library forbids the +-- construction of invalid 'Lexer' and 'Formatter' values. Invalid+-- 'Options' may still cause this function to raise an exception.+highlight :: Lexer -> Formatter -> Options -> String -> IO String+highlight lexer formatter options code = do+    let (lexerAlias : _) = lexerAliases lexer+    let (formatterAlias : _) = formatterAliases formatter+    pygmentize lexerAlias formatterAlias options code++-- | Highlight code (less robustly) using the @pygmentize@ script that comes+-- with Pygments. Invalid values for 'LexerAlias', 'FormatterAlias', or+-- 'Options' will cause this function to raise an exception.+pygmentize :: LexerAlias -> FormatterAlias -> Options -> String -> IO String+pygmentize lexer formatter options code = do+    let args = ["-l", lexer, "-f", formatter] ++ optionsToArgs options+    readProcess "pygmentize" args code++-- | The lexer/formatter option @(key, value)@ is passed to the @pygmentize@ +-- script via the command-line flag @-P key=value@.+--+-- Examples:+--+-- > [("hl_lines", "16,23,42"), ("encoding", "utf-8"), ("anchorlines", "True")]+--+type Option = (String, String)+type Options = [Option]++optionsToArgs :: Options -> [String]+optionsToArgs options = concatMap optionToArg options++optionToArg :: Option -> [String]+optionToArg (name, value) = ["-P", name ++ "=" ++ value]++{- $examples++Highlight a proposition:++>>> Just coqLexer <- getLexerByName "coq"+>>> highlight coqLexer terminalFormatter [("encoding", "utf-8")] "∀ x y : Z, x * y = 0 -> x = 0 \\/ y = 0" >>= putStr+∀ x y : Z, x * y = 0 -> x = 0 \/ y = 0++Output a complete HTML document:++>>> highlight haskellLexer htmlFormatter [("full", "True"), ("linenos", "table"), ("style", "emacs")] "fix f = let x = f x in x" >>= writeFile "fix.html"++Self-highlighting quine:++> quine = pygmentize "hs" "terminal" [] (s ++ show s) >>= putStr+>   where s = "quine = pygmentize \"hs\" \"terminal\" [] (s ++ show s) >>= putStr\n  where s = "++Highlight the code \"answer = 42\" using every language Pygments knows about:++>>> lexers <- getAllLexers+>>> forM_ lexers $ \l -> highlight l terminalFormatter [] "answer = 42" >>= printf "(%s) %s" (lexerName l)+...+(Prolog) answer = 42+(CSS+Django/Jinja) answer = 42+(Smalltalk) answer = 42+...++-}
+ src/Text/Highlighting/Pygments/Formatters.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE TemplateHaskell #-}+module Text.Highlighting.Pygments.Formatters+    (+      FormatterAlias+    , Formatter+    , getAllFormatters+    , getFormatterByName++    -- ** Accessors+    , formatterName+    , formatterAliases++    -- ** Common formatters+    , htmlFormatter+    , terminalFormatter+    ) where++import Data.Aeson.TH (deriveJSON)+import Data.Maybe (listToMaybe)++import Text.Highlighting.Pygments.JSON++type FormatterAlias = String++data Formatter = Formatter+    { _formatterName    :: String+    , _formatterAliases :: [FormatterAlias]+    } deriving (Eq, Ord, Show)++$(deriveJSON id ''Formatter)++getAllFormatters :: IO [Formatter]+getAllFormatters = getPygmentsJSON "formatters"++-- | Similar to the @get_formatter_by_name()@ function in Pygments+getFormatterByName :: FormatterAlias -> IO (Maybe Formatter)+getFormatterByName name = do+    formatters <- getAllFormatters+    let fs = filter (\f -> name `elem` _formatterAliases f) formatters+    return $ listToMaybe fs++formatterName :: Formatter -> String+formatterName = _formatterName++formatterAliases :: Formatter -> [FormatterAlias]+formatterAliases = _formatterAliases++htmlFormatter :: Formatter+htmlFormatter = Formatter+    { _formatterName = "HTML"+    , _formatterAliases = ["html"]+    }++terminalFormatter :: Formatter+terminalFormatter = Formatter+    { _formatterName = "Terminal"+    , _formatterAliases = ["terminal", "console"]+    }
+ src/Text/Highlighting/Pygments/JSON.hs view
@@ -0,0 +1,27 @@+{-# LANGUAGE OverloadedStrings #-}+module Text.Highlighting.Pygments.JSON +    (+      getPygmentsJSON+    ) where++import Control.Monad (when)+import Data.Aeson (decode, FromJSON)+import Data.ByteString.Lazy.Char8 ()+import System.Exit+import System.Process.ByteString.Lazy++import Paths_hpygments++getJSONDumper :: IO FilePath+getJSONDumper = getDataFileName "pygments_dump_json.py"++getPygmentsJSON :: FromJSON a => String -> IO a+getPygmentsJSON what = do+    jsonDumper <- getJSONDumper+    (exitCode, stdout, _) <- readProcessWithExitCode jsonDumper [what] ""+    when (exitCode /= ExitSuccess) $+        fail $ jsonDumper ++ " failed: " ++ show exitCode+    case decode stdout of+        Nothing -> fail $ "failed to decode " ++ what+        Just ls -> return ls+
+ src/Text/Highlighting/Pygments/Lexers.hs view
@@ -0,0 +1,82 @@+{-# LANGUAGE TemplateHaskell #-}+module Text.Highlighting.Pygments.Lexers+    (+      LexerAlias+    , Lexer+    , getAllLexers+    , getLexerByName++    -- ** Accessors+    , lexerName+    , lexerAliases+    , lexerFileTypes+    , lexerMimeTypes++    -- ** Common lexers+    , haskellLexer+    , literateHaskellLexer+    , textLexer+    ) where++import Data.Aeson.TH (deriveJSON)+import Data.Maybe (listToMaybe)++import Text.Highlighting.Pygments.JSON++type LexerAlias = String++data Lexer = Lexer+    { _lexerName      :: String+    , _lexerAliases   :: [LexerAlias]+    , _lexerFileTypes :: [String]+    , _lexerMimeTypes :: [String]+    } deriving (Eq, Ord, Show)++$(deriveJSON id ''Lexer)++getAllLexers :: IO [Lexer]+getAllLexers = getPygmentsJSON "lexers"++-- | Similar to the @get_lexer_by_name()@ function in Pygments+getLexerByName :: LexerAlias -> IO (Maybe Lexer)+getLexerByName name = do+    lexers <- getAllLexers+    let ls = filter (\l -> name `elem` _lexerAliases l) lexers+    return $ listToMaybe ls++lexerName :: Lexer -> String+lexerName = _lexerName++lexerAliases :: Lexer -> [LexerAlias]+lexerAliases = _lexerAliases++lexerFileTypes :: Lexer -> [String]+lexerFileTypes = _lexerFileTypes++lexerMimeTypes :: Lexer -> [String]+lexerMimeTypes = _lexerMimeTypes++haskellLexer :: Lexer+haskellLexer = Lexer+    { _lexerName = "Haskell"+    , _lexerAliases = ["haskell","hs"]+    , _lexerFileTypes = ["*.hs"]+    , _lexerMimeTypes = ["text/x-haskell"]+    }++literateHaskellLexer :: Lexer+literateHaskellLexer = Lexer +    { _lexerName = "Literate Haskell"+    , _lexerAliases = ["lhs","literate-haskell"]+    , _lexerFileTypes = ["*.lhs"]+    , _lexerMimeTypes = ["text/x-literate-haskell"]+    }++-- | No highlighting+textLexer :: Lexer+textLexer = Lexer+    { _lexerName = "Text only"+    , _lexerAliases = ["text"]+    , _lexerFileTypes = ["*.txt"]+    , _lexerMimeTypes = ["text/plain"]+    }