I am writing a Haskell command line program and using the lt
quasiquoter ("lazy-text") from Text.Shakespeare.Text
. In the Yesod book, it says that the hamlet
quasiquoter ignores leading whitespace if the first non-whitespace character is a backslash (\
).
Does this work in the lt
quasiquoter?
My code looks like this:
[lt|Usage: #{programName} [OPTION ...]
\Version #{showVersion version}|]
but the output is
Usage: MyProg [OPTION ...]
\Version 0.1.0.0
with the Version
string indented too far (and still containing the backslash). I also tried it with a space between the backslash and V
.
Is this possible with shakespeare-text?
It doesn't appear to, however it isn't hard to add the feature yourself. lt
is just a QuasiQuoter
, which is the data type:
QuasiQuoter {
quoteExp :: String -> Q Exp
, quotePat :: String -> Q Pat
, quoteType :: String -> Q Type
, quoteDec :: String -> Q [Dec]
}
They take a String
, and return the appropriate template haskell type (depending on the context it is used in.
It is a simple matter to transform a string so it works as you described with a regex:
stripWhiteSpaceBeforeBackslash :: String -> String
stripWhiteSpaceBeforeBackslash str = subRegex (mkRegex "^[[:space:]]*\\\\") str ""
Also, a function that transforms a QuasiQuoter
with a string transform function is simple:
transformQuasiQuoter :: (String -> String) -> QuasiQuoter -> QuasiQuoter
transformQuasiQuoter transform quasi = QuasiQuoter {
quoteExp = (quoteExp quasi) . transform
, quotePat = (quotePat quasi) . transform
, quoteType = (quoteType quasi) . transform
, quoteDec = (quoteDec quasi) . transform
}
Now you can make a version of lt
that does what you need:
lt_ = transformQuasiQuoter stripWhiteSpaceBeforeBackslash lt
Using it works as expected:
programName = "SomeProgram"
showVersion _ = "42.42.42"
version = 34
x = [lt_|Usage: #{programName} [OPTIONS...]
\Version #{showVersion version}|]
x
evaluates to "Usage: SomeProgram [OPTIONS...]\nVersion 42.42.42"
in ghci.