BlogLiterately-0.7: src/Text/BlogLiterately/Block.hs
-----------------------------------------------------------------------------
-- |
-- Module : Text.BlogLiterately.Block
-- Copyright : (c) 2008-2010 Robert Greayer, 2012 Brent Yorgey
-- License : GPL (see LICENSE)
-- Maintainer : Brent Yorgey <byorgey@gmail.com>
--
-- Utilities for working with code blocks.
--
-----------------------------------------------------------------------------
module Text.BlogLiterately.Block
(
unTag
, onTag
) where
import Data.Char (toLower)
import Text.Pandoc (Attr, Block (CodeBlock))
import Text.ParserCombinators.Parsec
-- | Given a block, if begins with a tag in square brackets, strip off
-- the tag and return a pair consisting of the tag and de-tagged
-- block. Otherwise, return @Nothing@ and the unchanged block.
unTag :: String -> (Maybe String, String)
unTag s = either (const (Nothing, s)) id $ parse tag "" s
where
tag = do
tg <- between (char '[') (char ']') $ many $ noneOf "[]"
skipMany $ oneOf " \t"
_ <- (string "\r\n" <|> string "\n")
txt <- many $ anyToken
eof
return (Just tg, txt)
-- | Run the given function on the attributes and source code of code
-- blocks with a tag matching the given tag (case insensitive). On
-- any other blocks (which don't have a matching tag, or are not code
-- blocks), run the other function.
onTag :: String -> (Attr -> String -> a) -> (Block -> a) -> Block -> a
onTag t f def b@(CodeBlock attr@(_, as, _) s)
| lowercase t `elem` map lowercase (maybe id (:) tag $ as)
= f attr src
| otherwise = def b
where (tag, src) = unTag s
onTag _ _ def b = def b
lowercase :: String -> String
lowercase = map toLower