frquotes (empty) → 0.1.0
raw patch · 5 files changed
+169/−0 lines, 5 filesdep +basesetup-changed
Dependencies added: base
Files
- LICENSE +30/−0
- Setup.lhs +3/−0
- Text/FrQuotes.hs +85/−0
- frquotes.cabal +23/−0
- frquotes.hs +28/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2010, Nicolas Pouillard+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 the copyright holders 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.lhs view
@@ -0,0 +1,3 @@+#!/usr/bin/env runhaskell+> import Distribution.Simple+> main = defaultMain
+ Text/FrQuotes.hs view
@@ -0,0 +1,85 @@+module Text.FrQuotes (frQuotes) where++frTop, openFrQQ', closeFrQQ', openFrQQ, closeFrQQ,+ openFrQ, closeFrQ, openBr, closeBr :: String+frTop = "(frTop ("+openFrQQ' = "[$frQQ|"+closeFrQQ' = "|]"+openFrQQ = frTop ++ openFrQQ'+closeFrQQ = closeFrQQ' ++ "))"+openFrQ = "\xc2\xab"+closeFrQ = "\xc2\xbb"+openBr = closeFrQQ' ++ " `mappend` frAntiq ("+closeBr = ") `mappend` " ++ openFrQQ'++-- Substitutes UTF8 french quotes «...» for (frTop [$frQQ|...|])+-- Antiquotations are supported via braces {...} and are+-- substituted for frAntiq, blocks are catenated with mappend.+-- Here String is used as UTF-8 code points.+frQuotes :: String -> String+frQuotes = h+ -- All these functions follow the same style,+ -- the first argument 'k' is the continuation, i.e. what to do next.+ -- Each function search for a different closing token, if the closing+ -- token is found the continuation is called with the remaining char+ -- stream, if some opening token is found the continuation is stacked+ -- as the continuation of a new function call that have to find this+ -- new token first.++ -- haskell context+ -- the h function don't needs a continuation parameter+ where h "" = ""+ h ('\xc2':'\xab':'{':xs) = frTop ++ "( frAntiq (" ++ b ((closeBr++) . f ((closeFrQQ++) . (')':) . h)) xs -- avoid an empty [$frQQ||]+ h ('\xc2':'\xab':xs) = openFrQQ ++ f ((closeFrQQ++) . h) xs+ h ('{':'-':xs) = "{-" ++ c (("-}"++) . h) xs+ h ('"':xs) = '"' : s (('"':) . h) xs+ h ('\'':xs) = '\'' : a h xs+ h ('[':'$':xs) = '[' : '$' : startq h xs+ h (x:xs) = x : h xs++ -- french quotes context+ f _ "" = error "unterminated french quotes (expecting `\xc2\xbb')"+ f _ ('}':_) = error "unexpected closing brace `}'"+ f k ('{':xs) = openBr ++ b ((closeBr++) . f k) xs+ f k ('\xc2':'\xab':xs) = openFrQ ++ f ((closeFrQ++) . f k) xs+ f k ('\xc2':'\xbb':xs) = k xs+ f k (x:xs) = x : f k xs++ -- braces (haskell) context+ b _ "" = error "unterminated quotes hole using curly braces (expecting `}')"+ b k ('\xc2':'\xab':xs) = openFrQQ ++ f ((closeFrQQ++) . b k) xs+ b _ ('\xc2':'\xbb':_) = error "unexpected closing french quote"+ b k ('{':'-':xs) = "{-" ++ c (("-}"++) . b k) xs+ b k ('{':xs) = '{' : b (('}':) . b k) xs+ b k ('}':xs) = k xs+ b k ('"':xs) = '"' : s (('"':) . b k) xs+ b k (x:xs) = x : b k xs++ -- haskell (nested) comments+ c _ "" = error "unterminated haskell comment (expecting `-}')"+ c k ('{':'-':xs) = "{-" ++ c (("-}"++) . c k) xs+ c k ('-':'}':xs) = k xs+ c k (x:xs) = x : c k xs++ -- haskell strings literal+ s _ "" = error "unterminated haskell string (expecting `\"')"+ s k ('\\':x:xs) = '\\' : x : s k xs+ s k ('"':xs) = k xs+ s k (x:xs) = x : s k xs++ -- haskell char literal (a bit lenient)+ a _ "" = error "unterminated haskell character (expecting `'')"+ a k ('\\':x:xs) = '\\' : x : a k xs+ a k (x:'\'':xs)+ | x /= '\'' = x : '\'' : k xs+ a k xs = k xs++ -- haskell quasi-quotation+ -- is there nested QQ?+ q _ "" = error "unterminated haskell quasi-quotation (expecting `|]')"+ q k ('|':']':xs) = '|' : ']' : k xs+ q k (x:xs) = x : q k xs+ startq k xs = ys ++ '|' : q k zs'+ where (ys,zs) = break (=='|') xs+ zs' | null zs = error "unrecognized haskell quasi-quotation (expecting `|`)"+ | otherwise = drop 1 zs
+ frquotes.cabal view
@@ -0,0 +1,23 @@+Name: frquotes+Cabal-Version: >= 1.2+Version: 0.1.0+Copyright: (c) Nicolas Pouillard+Author: Nicolas Pouillard+Maintainer: Nicolas Pouillard <nicolas.pouillard@gmail.com>+Category: Text+Synopsis: Lexical extension for Quasi-Quotations using French-Quotes+Description: Translate the French-Quotes in a UTF-8 Haskell file into+ a Quasi-Quotation that can be instantiated later on.+License: BSD3+License-File: LICENSE+Build-Type: Simple++library+ Build-depends: base>=3.0&&<5+ Exposed-Modules: Text.FrQuotes+ ghc-options: -Wall++executable frquotes+ Build-depends: base>=3.0&&<5+ main-is: frquotes.hs+ ghc-options: -Wall
+ frquotes.hs view
@@ -0,0 +1,28 @@+import System.Environment+import System.IO+import Text.FrQuotes (frQuotes)++-- | The 'readBinaryFile' function reads a binary file and+-- returns the contents of the file as a string.+-- The file is read lazily, on demand, as with 'getContents'.++readBinaryFile :: FilePath -> IO String+readBinaryFile name = openBinaryFile name ReadMode >>= hGetContents++-- | The computation 'writeBinaryFile' @file str@ function writes the string @str@,+-- to the file @file@.+writeBinaryFile :: FilePath -> String -> IO ()+writeBinaryFile f txt = withBinaryFile f WriteMode (\ hdl -> hPutStr hdl txt)++interact' :: (String -> String) -> IO ()+interact' f = do+ args <- getArgs+ case args of+ [] -> interact f+ [in1,inp,outp] ->+ writeBinaryFile outp . g . f =<< readBinaryFile inp+ where g = (("{-# LINE 2 \""++in1++"\" #-}\n")++)+ _ -> fail "Usage: frquotes [<orig> <input> <output>]"++main :: IO ()+main = interact' frQuotes