+horizontalLine :: Parser BlockElement
+horizontalLine = try $ do count 4 (char '-')
+ many (char '-')
+ ws
+ eol
+ return HorizontalLine
+
+
+listElement :: Parser BlockElement
+listElement = listElement' [] >>= return . List
+ where
+ listElement' :: [Char] -> Parser ListElement
+ listElement' stack
+ = try $ do t <- oneOf "*#"
+ ws
+ xs <- items (stack ++ [t])
+ return (ListElement (toType t) xs)
+
+ -- ListItem の終了條件は、
+ items :: [Char] -> Parser [ListItem]
+ items stack = do xs <- many1 inlineElement
+ nested <- option Nothing
+ $ try $ do newline
+ string stack
+ listElement' stack >>= return . Just
+ rest <- items stack
+ return $ (map Right xs ++ map Left (catMaybes [nested])) : rest
+ <|>
+ (try $ do newline
+ string stack
+ ws
+ items stack
+ )
+ <|>
+ return []
+{-
+ items stack = do nested <- listElement' stack
+ rest <- items stack
+ return (Left nested : rest)
+ <|>
+ do xs <- many1 inlineElement
+ rest <- items stack
+ return (Right xs : rest)
+ <|>
+ try ( newline
+ >>
+ string stack
+ >>
+ items stack
+ )
+ <|>
+ return []
+-}
+
+ toType :: Char -> ListType
+ toType '*' = Bullet
+ toType '#' = Numbered
+
+
+leadingSpaced :: Parser BlockElement
+leadingSpaced = char ' ' >> leadingSpaced' >>= return . LeadingSpaced
+ where
+ leadingSpaced' :: Parser [InlineElement]
+ leadingSpaced' = do x <- inlineElement
+ xs <- leadingSpaced'
+ return (x:xs)
+ <|>
+ try ( newline
+ >>
+ char ' '
+ >>
+ leadingSpaced'
+ >>=
+ return . (Text "\n" :)
+ )
+ <|>
+ return []
+
+
+blockTag :: Parser BlockElement
+blockTag = pzero -- not implemented
+
+