packages feed

language-python-colour (empty) → 0.1

raw patch · 6 files changed

+286/−0 lines, 6 filesdep +basedep +haskell98dep +language-pythonsetup-changed

Dependencies added: base, haskell98, language-python, xhtml

Files

+ LICENSE view
@@ -0,0 +1,27 @@+Copyright (c) 2009 Bernard James Pope ++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:+1. Redistributions of source code must retain the above copyright+   notice, this list of conditions and the following disclaimer.+2. 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.+3. Neither the name of the author nor the names of his contributors+   may 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 OWNER 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.
+ Setup.lhs view
@@ -0,0 +1,3 @@+#!/usr/bin/env runhaskell+> import Distribution.Simple+> main = defaultMain
+ language-python-colour.cabal view
@@ -0,0 +1,23 @@+name:                language-python-colour +version:             0.1 +cabal-version:       >= 1.6+synopsis:            Generate coloured XHTML for Python code. +description:         Generate coloured XHTML for Python code. +category:            Language+license:             BSD3+license-file:        LICENSE+copyright:           (c) 2009 Bernard James Pope+author:              Bernard James Pope +maintainer:          bjpop@csse.unimelb.edu.au+homepage:            http://www.cs.mu.oz.au/~bjpop/+build-type:          Simple+stability:           experimental+tested-with:         GHC==6.10.4++Executable pycol +  main-is:         Main.hs+  hs-source-dirs:  src+  build-depends:   haskell98, base >= 4 && < 5, language-python, xhtml+  other-modules:+     Language.Python.Colour.Colourise+     Language.Python.Colour.Options
+ src/Language/Python/Colour/Colourise.hs view
@@ -0,0 +1,63 @@+-----------------------------------------------------------------------------+-- |+-- Module      : Language.Python.Colour.Colourise+-- Copyright   : (c) 2009 Bernie Pope +-- License     : BSD-style+-- Maintainer  : bjpop@csse.unimelb.edu.au+-- Stability   : experimental+-- Portability : ghc+--+-- Turn Python tokens into HTML (for colouring), matching the layout of +-- the input program.+-----------------------------------------------------------------------------+module Language.Python.Colour.Colourise ( colourise ) where++import Language.Python.Common+import Text.XHtml.Transitional++colourise :: String -> [Token] -> String+colourise progName tokens = showHtml $ makeHtml progName tokens++makeHtml :: String -> [Token] -> Html+makeHtml progName tokens = theHead progName +++ theBody tokens++theHead :: String -> Html+theHead progName = +   header << (title +++ link)+   where +   title = thetitle << progName +   link = (thelink << noHtml) ! +          [ thetype "text/css", rel "stylesheet", href "pycol.css" ] ++theBody :: [Token] -> Html+theBody tokens = pre << renderTokens tokens++renderTokens :: [Token] -> Html +renderTokens [] = noHtml  +renderTokens [t] = tokenSpan t +renderTokens (t1:t2:ts)+   | getSpan t1 == SpanEmpty = renderTokens (t2:ts)+   | getSpan t2 == SpanEmpty = renderTokens (t1:ts)+   | otherwise = +        tokenSpan t1 ++++        (toHtml $ pad t1EndRow t1EndCol t2StartRow t2StartCol) ++++        renderTokens (t2:ts)+   where+   t1Span = getSpan t1+   t2Span = getSpan t2+   t1EndRow = endRow t1Span +   t1EndCol = endCol t1Span +   t2StartRow = startRow t2Span +   t2StartCol = startCol t2Span ++pad :: Int -> Int -> Int -> Int -> String+pad endRow endCol startRow startCol+   | endRow /= startRow = +        replicate (startRow - endRow) '\n' ++ +        replicate (startCol-1) ' '+   | otherwise = replicate (startCol - endCol - 1) ' '++tokenSpan :: Token -> Html+tokenSpan token =+   (thespan << tokenString token) ! +   [ theclass $ show $ classifyToken token ]
+ src/Language/Python/Colour/Options.hs view
@@ -0,0 +1,109 @@+-----------------------------------------------------------------------------+-- |+-- Module      : Language.Python.Colour.Options+-- Copyright   : (c) 2009 Bernie Pope +-- License     : BSD-style+-- Maintainer  : bjpop@csse.unimelb.edu.au+-- Stability   : experimental+-- Portability : ghc+--+-- Command line option processing for the Python colouring program.+-----------------------------------------------------------------------------+module Language.Python.Colour.Options +   ( processOptions+   , programName+   , Flag (..)+   , PythonVersion (..)+   , getPyVersion+   , probeFlags+   , probeFlagsFirst+   , existsFlag+   , defaultPyVersion+   )+   where++import System.Console.GetOpt +import Data.Maybe (fromMaybe)+import Data.Char (toLower, isDigit)+import Data.Maybe (catMaybes)+import IO (stderr, hPutStrLn)+import System++programName :: String+programName = "pycol"++-- This should really come from the cabal file somehow.+versionNumber :: String+versionNumber = "0.1"++versionInfo :: String+versionInfo = unwords [programName, "version", versionNumber]++processOptions :: [String] -> IO ([Flag], String)+processOptions argv = +   case getOpt RequireOrder options argv of+      (flags, nonOpts, []) +         | existsFlag flags Help -> do +              putStrLn $ usageInfo header options+              exitWith ExitSuccess+         | existsFlag flags Version -> do +              putStrLn versionInfo +              exitWith ExitSuccess+         | length nonOpts /= 1 ->+              raiseError ["You must specify a single input Python file.\n"]  +         | otherwise -> return (flags, head nonOpts)+      (_, _, errs) -> raiseError errs+      where +      header = "Usage: " ++ programName ++ " [OPTION...] file"+      failureMsg = programName ++ ": command line error.\n"+      raiseError errs = do+         hPutStrLn stderr $ failureMsg ++ concat errs ++ usageInfo header options+         exitFailure++probeFlags :: [Flag] -> (Flag -> Maybe a) -> [a]+probeFlags flags probe = catMaybes (map probe flags)++probeFlagsFirst :: [Flag] -> (Flag -> Maybe a) -> a -> a+probeFlagsFirst flags probe defaultValue+   | null probed = defaultValue +   | otherwise = head probed+   where+   probed = probeFlags flags probe++existsFlag :: [Flag] -> Flag -> Bool+existsFlag flags f+   = probeFlagsFirst flags probe False +   where+   probe someFlag = if f == someFlag then Just True else Nothing +    +data Flag +  = PyVersion PythonVersion  -- ^ Which version of Python to parse (2 or 3).+  | Help                   -- ^ Print a help message and exit.+  | Version                -- ^ Print the version number. +  deriving (Eq, Ord, Show)++getPyVersion :: Flag -> Maybe PythonVersion+getPyVersion (PyVersion v) = Just v+getPyVersion _ = Nothing++data PythonVersion+   = V2 +   | V3 +   deriving (Eq, Ord, Show)++options :: [OptDescr Flag]+options =+ [ Option ['p']     ["pyver"]     (ReqArg mkPyVersion "VERSION") "VERSION of Python to parse: 2 or 3 (default is 2)"+ , Option ['v']     ["version"]   (NoArg Version)            "show version number"+ , Option ['h']     ["help"]      (NoArg Help)               "get help about using this program"+ ]++defaultPyVersion :: PythonVersion +defaultPyVersion = V2 ++mkPyVersion :: String -> Flag+mkPyVersion = normalMkVersion . map toLower+   where+   normalMkVersion "2"   = PyVersion V2 +   normalMkVersion "3"   = PyVersion V3 +   normalMkVersion other = PyVersion defaultPyVersion
+ src/Main.hs view
@@ -0,0 +1,61 @@+-----------------------------------------------------------------------------+-- |+-- Module      : Main+-- Copyright   : (c) 2009 Bernie Pope +-- License     : BSD-style+-- Maintainer  : bjpop@csse.unimelb.edu.au+-- Stability   : experimental+-- Portability : ghc+--+-- Generate coloured XHTML for a Python source file. Supports version 2 and+-- 3 of Python. The name of the file is given as a command line argument+-- and an XHTML file is produced on the standard output. +--+-----------------------------------------------------------------------------++module Main where++import Language.Python.Colour.Options +import Language.Python.Colour.Colourise+import qualified Language.Python.Version2 as V2+import qualified Language.Python.Version3 as V3+import Language.Python.Common+import Prelude hiding (lex)+import System +import Control.Monad (when, liftM)+import IO++main :: IO ()+main = do+   args <- getArgs+   (flags, filename) <- processOptions args+   tryContents <- safeReadFile filename+   case tryContents of+      Left error -> putStrLn error >> exitFailure+      Right contents -> do+         -- decide which parser and lexer to use (version 2 or 3?)+         let (parser, lexer) = getParserLexer flags+         case lexer contents filename of+            Left e -> hPutStrLn stderr (prettyText e) >> exitFailure+            Right tokens -> putStrLn $ colourise filename tokens++type Parser = String -> String -> Either ParseError (ModuleSpan, [Token])+type Lexer = String -> String -> Either ParseError [Token]++-- decide which parser and lexer to use based on command line arguments (version 2 or 3?)+getParserLexer :: [Flag] -> (Parser, Lexer)+getParserLexer [] = (V2.parseModule, V2.lex)+getParserLexer flags =+   case pyVersion of+      V2 -> (V2.parseModule, V2.lex)+      V3 -> (V3.parseModule, V3.lex)+   where+   pyVersion = probeFlagsFirst flags getPyVersion defaultPyVersion++-- Read a file and check for exceptions.+safeReadFile :: FilePath -> IO (Either String String)+safeReadFile file+   = catch (rightReadFile file) $ \error -> return $ Left $ show error+   where+   rightReadFile :: FilePath -> IO (Either String String)+   rightReadFile file = liftM Right $ readFile file