embeddock (empty) → 0.1.0.0
raw patch · 4 files changed
+173/−0 lines, 4 filesdep +MissingHdep +basedep +filepathsetup-changed
Dependencies added: MissingH, base, filepath, her-lexer, process
Files
- LICENSE +30/−0
- Setup.hs +2/−0
- embeddock.cabal +30/−0
- src/main.hs +111/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2013, Takayuki Muranushi++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.++ * Neither the name of Takayuki Muranushi nor the names of other+ 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.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ embeddock.cabal view
@@ -0,0 +1,30 @@+-- Initial embeddock.cabal generated by cabal init. For further +-- documentation, see http://haskell.org/cabal/users-guide/++name: embeddock+version: 0.1.0.0+synopsis: In Haddock documentation embed the values from the same module+description: embeddock is a Haskell source-code preprocessor. + It allows you to embed computer-generated + values in the documentation.+ ++homepage: https://github.com/nushio3/embeddock+license: BSD3+license-file: LICENSE+author: Takayuki Muranushi+maintainer: muranushi@gmail.com+-- copyright: +category: Documentation+build-type: Simple+cabal-version: >=1.8++executable embeddock+ main-is: main.hs+ hs-source-dirs: src/+ -- other-modules: + build-depends: base ==4.6.*+ , filepath >= 1.3+ , her-lexer >= 0.1.1+ , MissingH >= 1.2+ , process >= 0.9
+ src/main.hs view
@@ -0,0 +1,111 @@+{-# OPTIONS -Wall #-}++import Control.Monad+import Data.List (isInfixOf)+import Data.String.Utils (replace)+import Language.Haskell.Her.HaLay (ready, tokssOut, toksOut, Tok(Com))+import System.Environment+import System.FilePath (splitFileName, splitExtension, (</>), (<.>))+import System.IO+import System.Process (runInteractiveCommand)+import Text.Printf+++main :: IO ()+main = do+ (srcPath:_:destPath:ppOpts) <- getArgs+ src <- readFile srcPath+ let+ embedKey :: String+ runhaskellArgs :: [String]++ (embedKey,runhaskellArgs) = case ppOpts of+ [] -> ("$", [])+ (x:xs) -> (x, xs)++ openKey, closeKey :: String+ openKey = findFree "Open" 1 "Sesami"+ closeKey = findFree "Close" 1 "Sesami"++ findFree tag n tag' =+ let cand = tag ++ show (n::Integer) ++ tag' in+ if cand `isInfixOf` src then findFree tag (3*n) tag'+ else cand++ parsedSrc :: [[Tok]]+ parsedSrc =+ map (filter (not . isEmbedPragma)) $+ ready srcPath src++ isEmbedPragma :: Tok -> Bool+ isEmbedPragma (Com str)+ | "OPTIONS_GHC" `isInfixOf` str && "embeddock" `isInfixOf` str+ = True+ | otherwise = False+ isEmbedPragma _ = False++ (srcDir, srcFn) = splitFileName srcPath+ (srcFnBody, srcExt) = splitExtension srcFn++ isEmbedLoop = (head srcFn == '.') &&+ ("_embeddock." `isInfixOf` srcFn)++ runnerFn = srcDir </> ("." ++ srcFnBody ++ "_embeddock") <.> srcExt++ destContent = tokssOut parsedSrc++ quineMain = unlines $ "main = do" :map mkPrinter parsedSrc++ mkPrinter :: [Tok] -> String+ mkPrinter toks = (" putStr $ " ++ ) $+ replace openKey "\"++(" $+ replace closeKey ")++\"" $+ show $ toksOut $ map seedEmbed toks+ where+ embeds :: [String]+ embeds = toks >>= findEmbed++ seedEmbed :: Tok -> Tok+ seedEmbed (Com str) = Com $ foldl+ (\str e -> replace (printf "%s(%s)" embedKey e)+ (printf "%s%s%s" openKey e closeKey)+ str)+ str embeds+ seedEmbed x = x+++ findEmbed :: Tok -> [String]+ findEmbed (Com str) = go str+ where+ go [] = []+ go xss@(_:xs) = try embedKey xss `mplus` go xs++ try [] [] = []+ try _ [] = []+ try (k:ey) (x:xs)+ | k==x = try ey xs+ | otherwise = []+ try [] ('(':xs) = tryParen (1::Int) xs ""+ try _ _ = []++ tryParen n [] buf+ | n <= 0 = [reverse $ drop 1 buf]+ | otherwise = []++ tryParen n (x:xs) buf+ | n <= 0 = [reverse $ drop 1 buf]+ | otherwise = let next '(' = n+1+ next ')' = n-1+ next _ = n+ in tryParen (next x) xs (x:buf)+ findEmbed _ = []++++ when (not isEmbedLoop) $ do+ print parsedSrc+ print embedKey+ writeFile runnerFn $ destContent ++ "\n" ++ quineMain+ (_, hOut, _, _) <- runInteractiveCommand $+ printf "runhaskell %s %s" (unwords runhaskellArgs) runnerFn+ hGetContents hOut >>= writeFile destPath