-- Copyright © 2015 Mykola Orliuk -- Distributed under the terms of the GNU General Public License v2 {-# LANGUAGE UnicodeSyntax #-} {-# LANGUAGE FlexibleInstances #-} module ExRender.Base ( module ExRender.Base , module Text.PrettyPrint ) where import Text.PrettyPrint -- | Wrap width soft limitt exWrapWidth ∷ Int exWrapWidth = 80 class ExRender a where -- | Renders 'a' into a 'Doc' representing some part of exheres exDisp ∷ a → Doc class ExRenderQ a where -- | Renders 'a' into a 'Doc' to be placed within double-quotes inside of exheres exDispQ ∷ a → Doc -- | Double-quoted string for bash dquoted ∷ String → String dquoted [] = [] dquoted ('\\':xs) = "\\\\" ++ dquoted xs dquoted ('"':xs) = "\\\"" ++ dquoted xs dquoted ('`':xs) = "\\`" ++ dquoted xs dquoted ('$':xs) = "\\$" ++ dquoted xs dquoted (x:xs) = x : dquoted xs -- | Split String in lines according to soft limit softWidth ∷ Int → [String] → [[String]] softWidth width = build 0 [] where build _ ys [] = [reverse ys] build 0 [] (w:ws) = build (length w) [w] ws build n ys (w:ws) | n' > width = reverse ys : build 0 [] (w:ws) | otherwise = build n' (w : ys) ws where n' = length w + n -- | Build a Doc out of String respecting soft width limit reflow ∷ Int → String → Doc reflow width = vcat . map (text . unwords) . softWidth width . words -- | Wrap doc with spaces around if non-empty spaces ∷ Doc → Doc spaces doc | isEmpty doc = empty | otherwise = space <> doc <> space -- | Wrap with brackets non-empty doc nbrackets ∷ Doc → Doc nbrackets doc | isEmpty doc = empty | otherwise = brackets doc -- | Render a multi-line meta-field of Exheres if non-empty value exFieldDoc ∷ String → Doc → Doc exFieldDoc name value | isEmpty value = empty | otherwise = vcat [text name <> text "=\"", value, char '"'] -- |Render a single-line with potential wrap meta-field of Exheres if non-empty value exField ∷ String → String → Doc exField _ "" = empty exField name x | length singleLine < exWrapWidth = text singleLine | otherwise = exFieldDoc name (reflow exWrapWidth (dquoted x)) where singleLine = name ++ "=\"" ++ dquoted x ++ "\"" instance ExRenderQ String where -- TODO: exDispQ = sep . map text . words . dquoted exDispQ = text . dquoted