Last active
July 23, 2020 10:23
-
-
Save TravisCardwell/49904adeaa269c7851a3b38b91e3839f to your computer and use it in GitHub Desktop.
demonstration of defining a custom function in ginger
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env stack | |
{- stack | |
script | |
--resolver lts-16.6 | |
--package ginger | |
--package text | |
-} | |
-- This is a demonstration of defining a custom function in ginger. | |
-- | |
-- * https://old.reddit.com/r/haskell/comments/hw3u84/which_template_library_for_source_code_generation/ | |
-- * https://hackage.haskell.org/package/ginger | |
-- | |
-- This file is a Stack script. With Stack installed, make this file | |
-- executable and execute it to run the script. | |
-- | |
-- $ chmod 0755 GingerFunDemo.hs | |
-- $ ./GingerFunDemo.hs | |
{-# LANGUAGE LambdaCase #-} | |
{-# LANGUAGE OverloadedStrings #-} | |
module Main (main) where | |
-- https://hackage.haskell.org/package/base | |
import Data.Bifunctor (first) | |
import Data.Functor.Identity (Identity(runIdentity)) | |
import Data.Maybe (fromMaybe) | |
-- https://hackage.haskell.org/package/ginger | |
import qualified Text.Ginger as G | |
-- https://hackage.haskell.org/package/text | |
import qualified Data.Text as T | |
import qualified Data.Text.IO as TIO | |
------------------------------------------------------------------------------ | |
-- Parse a template. | |
-- | |
-- This is a pure template parser for parsing templates from strings, using | |
-- custom syntax. | |
parseTemplate | |
:: String | |
-> Either String (G.Template G.SourcePos) | |
parseTemplate = first G.peErrorMessage . runIdentity . G.parseGinger' options | |
where | |
options :: G.ParserOptions Identity | |
options = G.ParserOptions | |
{ G.poIncludeResolver = const $ pure Nothing | |
, G.poSourceName = Nothing | |
, G.poKeepTrailingNewline = False | |
, G.poLStripBlocks = False | |
, G.poTrimBlocks = False | |
, G.poDelimiters = G.Delimiters | |
{ G.delimOpenInterpolation = "<<" | |
, G.delimCloseInterpolation = ">>" | |
, G.delimOpenTag = "<!" | |
, G.delimCloseTag = "!>" | |
, G.delimOpenComment = "<#" | |
, G.delimCloseComment = "#>" | |
} | |
} | |
------------------------------------------------------------------------------ | |
-- Format a list of strings as a comma-separated list string. | |
gfnCommas | |
:: Monad m | |
=> G.Function m | |
gfnCommas [(_, arg)] = pure . fromMaybe "" $ | |
G.toGVal . T.intercalate ", " . map G.asText <$> G.asList arg | |
gfnCommas _ = pure "" | |
------------------------------------------------------------------------------ | |
main :: IO () | |
main = do | |
template <- either fail pure . parseTemplate $ unlines | |
[ "function foo(<< args|commas >>) {" | |
, "<! for arg in args !>" | |
, " print(<< arg >>);" | |
, "<! endfor !>" | |
, "}" | |
] | |
let context = G.makeContextText $ \case | |
"args" -> G.toGVal ["hoge", "piyo" :: T.Text] | |
"commas" -> G.fromFunction gfnCommas | |
_ -> G.toGVal () | |
TIO.putStr $ G.runGinger context template |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment