2 | 2 |
|
3 | 3 |
module Data.TeLML.Parser (Fragment(..), Document, parse) where
|
4 | 4 |
|
5 | |
import Data.Char (isAlpha, isSpace)
|
| 5 |
import Data.Char (isAlpha, isAlphaNum, isSpace)
|
6 | 6 |
import Data.TeLML.Type
|
7 | 7 |
|
8 | 8 |
type Result a = Either String (String, a)
|
|
52 | 52 |
|
53 | 53 |
-- Parse a tag name of length >= 0.
|
54 | 54 |
pTagName :: Parse String
|
55 | |
pTagName s = go s `bind` ensureLen
|
| 55 |
pTagName s = go s `bind` ensureName
|
56 | 56 |
where go i@(x:xs)
|
57 | |
| isAlpha x = (x:) `over` go xs
|
58 | |
| elem x "-_" = (x:) `over` go xs
|
59 | |
| otherwise = return (i, "")
|
| 57 |
| isAlphaNum x = (x:) `over` go xs
|
| 58 |
| elem x "-_" = (x:) `over` go xs
|
| 59 |
| otherwise = return (i, "")
|
60 | 60 |
go [] = throw "unexpected end-of-document while parsing tag"
|
61 | |
ensureLen (xs, name)
|
62 | |
| length name > 0 = return (xs, name)
|
63 | |
| otherwise = throw $ "expected tag name after `\\': " ++ show (name, xs)
|
| 61 |
ensureName (xs, name)
|
| 62 |
| length name == 0 =
|
| 63 |
throw "expected tag name after `\\'"
|
| 64 |
| not (isAlpha (head name)) =
|
| 65 |
throw "tag names must begin with an alphabetic character"
|
| 66 |
| otherwise = return (xs, name)
|
64 | 67 |
|
65 | 68 |
-- Skip any space charaters, returning () for the first non-space
|
66 | 69 |
-- character (including EOF).
|