packages feed

ctemplate (empty) → 0.1

raw patch · 8 files changed

+219/−0 lines, 8 filesdep +basedep +bytestringsetup-changed

Dependencies added: base, bytestring

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) Adam Langley++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 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 AUTHORS 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/CTemplate.hs view
@@ -0,0 +1,90 @@+-- | CTemplate is the template system that Google uses for many of their sites,+--   including the search results from the main www.google.com web search. It's+--   simple templating system, but has easy to use escaping functions.+--+--   See <http://goog-ctemplate.sourceforge.net/doc/howto.html> for+--   documentation (esp see the Tips link at the end of that)+module Text.CTemplate+  ( Dictionary(..)+  , Variable(..)+  , Option(..)+  , expand+  , setTemplateRootDirectory+  ) where++import Foreign+import Foreign.C+import qualified Data.ByteString as B+import qualified Data.ByteString.Unsafe as B++-- | This is a dictionary. Relative filenames are resolved in the current+--   directory+data Dictionary = Dictionary FilePath [(String, Variable)] deriving (Show, Eq)++data Variable = StringV String  -- ^ a string value (note - no char encoding performed)+              | BSV B.ByteString  -- ^ a string value from a ByteString+              | SectionV [[(String, Variable)]]  -- ^ a (possibly repeated) section+              | IncludedV Dictionary  -- ^ an included dictionary+              deriving (Show, Eq)++data Option = DontStrip+            | StripBlankLines+            | StripWhitespace+            deriving (Show, Eq, Enum)++-- | This is the type of the C-side dictionary object+data Dictionary_+-- | Likewise, this is the type of the C-side template+data Template_++foreign import ccall unsafe "ct_load_template" _load_template :: CString -> CInt -> IO (Ptr Template_)+foreign import ccall unsafe "ct_new_dict" _new_dict :: IO (Ptr Dictionary_)+foreign import ccall unsafe "ct_set_string" _set_string :: Ptr Dictionary_ -> CString -> CString -> IO ()+foreign import ccall unsafe "ct_set_bytes" _set_bytes :: Ptr Dictionary_ -> CString -> Ptr CChar -> CInt -> IO ()+foreign import ccall unsafe "ct_new_section" _new_section :: Ptr Dictionary_ -> CString -> IO (Ptr Dictionary_)+foreign import ccall unsafe "ct_new_included" _new_included :: Ptr Dictionary_ -> CString -> IO (Ptr Dictionary_)+foreign import ccall unsafe "ct_set_filename" _set_filename :: Ptr Dictionary_ -> CString -> IO ()+foreign import ccall unsafe "ct_expand" _expand :: Ptr Template_ -> Ptr Dictionary_ -> IO (Ptr CChar)++translateVariable :: Ptr Dictionary_ -> (String, Variable) -> IO ()+translateVariable dict (v, StringV s) =+  withCString v $ \v ->+    withCString s $ \s ->+      _set_string dict v s++translateVariable dict (v, BSV bs) =+  withCString v $ \v ->+    B.unsafeUseAsCStringLen bs $ \(ptr, len) ->+      _set_bytes dict v ptr $ fromIntegral len++translateVariable dict (v, SectionV varses) =+  withCString v $ \v ->+    flip mapM_ varses $ \vars ->+      _new_section dict v >>= \dict -> mapM_ (translateVariable dict) vars++translateVariable dict (v, IncludedV (Dictionary filename vars)) =+  withCString v $ \v ->+    _new_included dict v >>= \dict ->+      withCString filename $ \ptr ->+        _set_filename dict ptr >> mapM_ (translateVariable dict) vars++-- | Expand a template given the values to fill it+expand :: Option -> Dictionary -> IO (Maybe B.ByteString)+expand option (Dictionary filename vars) = do+  template <- withCString filename $ \ptr -> _load_template ptr $ fromIntegral $ fromEnum option+  if template == nullPtr+     then return Nothing+     else do dict <- _new_dict+             mapM_ (translateVariable dict) vars+             str <- _expand template dict+             bs <- B.packCString str+             free str+             return $ Just bs++foreign import ccall unsafe "ct_set_root" _set_root :: Ptr CChar -> IO ()++-- | Set the directory where templates with non-absolute filenames will be+--   loaded from+setTemplateRootDirectory :: FilePath -> IO ()+setTemplateRootDirectory filename =+  withCString filename $ \ptr -> _set_root ptr
+ cbits/ctemplate.cc view
@@ -0,0 +1,50 @@+#include <string>+#include <stdio.h>+#include <stdlib.h>+#include <google/template.h>++extern "C" {+void *ct_load_template(const char *filename, int option) {+  return google::Template::GetTemplate(filename, (google::Strip) option);+}++void *ct_new_dict() {+  return new google::TemplateDictionary("");+}++void ct_set_string(google::TemplateDictionary *dict, const char *key,+                   const char *value) {+  dict->SetValue(key, value);+}++void ct_set_bytes(google::TemplateDictionary *dict, const char *key, const char *bytes,+                  const int length) {+  dict->SetValue(key, std::string(bytes, length));+}++void *ct_new_section(google::TemplateDictionary *dict, const char *key) {+  return dict->AddSectionDictionary(key);+}++void *ct_new_included(google::TemplateDictionary *dict, const char *key) {+  return dict->AddIncludeDictionary(key);+}++void ct_set_filename(google::TemplateDictionary *dict, const char *filename) {+  dict->SetFilename(filename);+}++char *ct_expand(google::Template *tmpl, google::TemplateDictionary *dict) {+  std::string result;+  tmpl->Expand(&result, dict);+  char *ret = (char *) malloc(result.size() + 1);+  memcpy(ret, result.c_str(), result.size() + 1);++  return ret;+}++void ct_set_root(const char *path) {+  google::Template::SetTemplateRootDirectory(path);+}++}
+ ctemplate.cabal view
@@ -0,0 +1,25 @@+Name: ctemplate+Synopsis: Binding to the Google ctemplate library+Description:+  CTemplate is the library that Google uses to render most of their sites+  (including the www.google.com search). It's a simple templating system, but+  includes many, easy to use, escaping functions.+Version: 0.1+License: BSD3+License-File: LICENSE+Author: Adam Langley <agl@imperialviolet.org>+Stability: experimental+Homepage: http://darcs.imperialviolet.org/ctemplate+Category: Text+Tested-With: GHC == 6.8.2+Build-Depends: base, bytestring+Exposed-Modules:  Text.CTemplate+Extensions: ForeignFunctionInterface, EmptyDataDecls+ghc-options: -Wall -fno-warn-name-shadowing+build-type: Simple+C-Sources: cbits/ctemplate.cc+Extra-Source-Files:+        examples/test.tmpl+        examples/included.tmpl+        examples/example.hs+Extra-Libraries: ctemplate
+ examples/example.hs view
@@ -0,0 +1,11 @@+module Main where++import qualified Data.ByteString as B+import Text.CTemplate++main = do+  Just bs <- expand DontStrip $ Dictionary "test.tmpl"+    [("NAME", StringV "Adam"), ("S", SectionV [[("VALUE", StringV "0")], [("VALUE", StringV "1")]]),+     ("INCLUDED", IncludedV $ Dictionary "included.tmpl" []),+     ("HTML", StringV "<br>")]+  B.putStr bs
+ examples/included.tmpl view
@@ -0,0 +1,1 @@+This is an included template
+ examples/test.tmpl view
@@ -0,0 +1,9 @@+Hello {{NAME}}, NAME is a simple variable,+{{#S}}This is a repeatable section, with a value: {{VALUE}}+{{/S}}++If you don't give a value for a variable, it ends up "{{NONAME}}" (blank)++{{>INCLUDED}}++We can try an include HTML in the following, but it will be escaped: {{HTML:h}}