+inlineCmd :: CommandTypeOf -> Parser InlineElement
+inlineCmd cmdTypeOf
+ = (try $ do (tagName, tagAttrs) <- openTag
+ case cmdTypeOf tagName of
+ Just InlineCommandType
+ -> do xs <- contents
+ closeTag tagName
+ return $ InlineCmd $ InlineCommand {
+ iCmdName = tagName
+ , iCmdAttributes = tagAttrs
+ , iCmdContents = xs
+ }
+ _ -> pzero
+ )
+ <|>
+ (try $ do (tagName, tagAttrs) <- emptyTag
+ case cmdTypeOf tagName of
+ Just InlineCommandType
+ -> return $ InlineCmd $ InlineCommand {
+ iCmdName = tagName
+ , iCmdAttributes = tagAttrs
+ , iCmdContents = []
+ }
+ _ -> pzero
+ )
+ where
+ contents :: Parser [InlineElement]
+ contents = do x <- inlineElement cmdTypeOf
+ xs <- contents
+ return (x:xs)
+ <|>
+ (comment >> contents)
+ <|>
+ (newline >> contents >>= return . (Text "\n" :))
+ <|>
+ return []
+
+
+openTag :: Parser (String, [Attribute])
+openTag = try $ do char '<'
+ many space
+ name <- many1 letter
+ many space
+ attrs <- many $ do attr <- tagAttr
+ many space
+ return attr
+ char '>'
+ return (name, attrs)
+
+
+emptyTag :: Parser (String, [Attribute])
+emptyTag = try $ do char '<'
+ many space
+ name <- many1 letter
+ many space
+ attrs <- many $ do attr <- tagAttr
+ many space
+ return attr
+ char '/'
+ many space
+ char '>'
+ return (name, attrs)
+
+
+closeTag :: String -> Parser ()
+closeTag name = try $ do char '<'
+ many space
+ char '/'
+ many space
+ string name
+ many space
+ char '>'
+ return ()
+
+
+tagAttr :: Parser (String, String)
+tagAttr = do name <- many1 letter
+ char '='
+ char '"'
+ value <- many (satisfy (/= '"'))
+ char '"'
+ return (name, value)
+
+