23 | module Libraries.Text.Literate
25 | import Libraries.Text.Lexer
28 | import Data.List.Views
33 | untilEOL : Recognise False
34 | untilEOL = manyUntil newline any
36 | line : String -> Lexer
37 | line s = exact s <+> (newline <|> space <+> untilEOL)
39 | block : String -> String -> Lexer
40 | block s e = surround (exact s <+> untilEOL) (exact e <+> untilEOL) any
43 | notCodeLine = newline
44 | <|> any <+> untilEOL
48 | = CodeBlock String String String
50 | | CodeLine String String
53 | showPrec d (CodeBlock l r x) = showCon d "CodeBlock" $
showArg l ++ showArg r ++ showArg x
54 | showPrec d (Any x) = showCon d "Any" $
showArg x
55 | showPrec d (CodeLine m x) = showCon d "CodeLine" $
showArg m ++ showArg x
57 | rawTokens : (delims : List (String, String))
58 | -> (markers : List String)
59 | -> TokenMap LitToken
60 | rawTokens delims ls =
61 | map (\(l,r) => (block l r, CodeBlock (trim l) (trim r))) delims
62 | ++ map (\m => (line m, CodeLine (trim m))) ls
63 | ++ [(notCodeLine, Any)]
66 | reduce : List (WithBounds LitToken) -> List String -> String
67 | reduce [] acc = fastConcat (reverse acc)
68 | reduce (MkBounded (Any x) _ _ :: rest) acc =
71 | then reduce rest ("\n"::acc)
72 | else reduce rest acc
74 | reduce (MkBounded (CodeLine m src) _ _ :: rest) acc =
76 | then reduce rest ("\n"::acc)
77 | else reduce rest ((substr (length m + 1)
82 | reduce (MkBounded (CodeBlock l r src) _ _ :: rest) acc with (lines src)
83 | reduce (MkBounded (CodeBlock l r src) _ _ :: rest) acc | [] = reduce rest acc
84 | reduce (MkBounded (CodeBlock l r src) _ _ :: rest) acc | (s :: ys) with (snocList ys)
85 | reduce (MkBounded (CodeBlock l r src) _ _ :: rest) acc | (s :: []) | Empty = reduce rest acc
86 | reduce (MkBounded (CodeBlock l r src) _ _ :: rest) acc | (s :: (srcs ++ [f])) | (Snoc f srcs rec) =
88 | reduce rest ((unlines srcs) :: "\n" :: acc)
94 | record LiterateError where
95 | constructor MkLitErr
101 | Show LiterateError where
102 | show (MkLitErr line col input) = "\{input}:\{show line}:\{show col}"
145 | record LiterateStyle where
146 | constructor MkLitStyle
148 | deliminators : List (String, String)
151 | line_markers : List String
156 | file_extensions : List String
166 | lexLiterate : (specification : LiterateStyle)
167 | -> (litStr : String)
168 | -> Either LiterateError (List (WithBounds LitToken))
169 | lexLiterate (MkLitStyle delims markers exts) str =
170 | case lex (rawTokens delims markers) str of
171 | (toks, (_,_,"")) => Right toks
172 | (_, (l,c,i)) => Left (MkLitErr l c i)
184 | extractCode : (specification : LiterateStyle)
185 | -> (litStr : String)
186 | -> Either LiterateError String
187 | extractCode spec str = flip reduce Nil <$> lexLiterate spec str
191 | unlit : (specification : LiterateStyle)
192 | -> (litStr : String)
193 | -> Either LiterateError String
194 | unlit = extractCode
202 | isLiterateLine : (specification : LiterateStyle)
204 | -> Pair (Maybe String) String
205 | isLiterateLine (MkLitStyle delims markers _) str with (lex (rawTokens delims markers) str)
206 | isLiterateLine (MkLitStyle delims markers _) str | ([MkBounded (CodeLine m str') _ _], (_,_, "")) = (Just m, str')
207 | isLiterateLine (MkLitStyle delims markers _) str | (_, _) = (Nothing, str)
223 | embedCode : (specification : LiterateStyle)
226 | embedCode (MkLitStyle ((s,e)::delims) _ _) str = unlines [s,str,e]
227 | embedCode (MkLitStyle Nil (m::markers) _) str = unwords [m, str]
228 | embedCode (MkLitStyle _ _ _) str = str
232 | relit : (specification : LiterateStyle)