@@ -303,25 +303,48 @@ codeBlockDelimiter len = try $ do
303303 Nothing -> count 3 (char '~') >> many (char '~') >>=
304304 return . (+ 3) . length
305305 many spaceChar
306− lang <- option "" classAttributes
306+ attr <- option ([],[],[]) attributes
307307 blankline
308− return (size, lang)
308+ return (size, attr)
309309
310−classAttributes = try $ do
310+attributes = try $ do
311311 char '{'
312312 many spaceChar
313− attrs <- many $ try $ do char '.'
314− attr <- many1 alphaNum
315− many spaceChar
316− return attr
313+ attrs <- many (attribute >>~ many spaceChar)
317314 char '}'
318− return $ unwords attrs
315+ let (ids, classes, keyvals) = unzip3 attrs
316+ let id = if null ids then "" else head ids
317+ return (id, concat classes, concat keyvals)
318+
319+attribute = identifierAttr <|> classAttr <|> keyValAttr
320+
321+identifier = do
322+ first <- letter
323+ rest <- many alphaNum
324+ return (first:rest)
325+
326+identifierAttr = try $ do
327+ char '#'
328+ result <- identifier
329+ return (result,[],[])
330+
331+classAttr = try $ do
332+ char '.'
333+ result <- identifier
334+ return ("",[result],[])
335+
336+keyValAttr = try $ do
337+ key <- identifier
338+ char '='
339+ char '"'
340+ val <- manyTill (noneOf "\n") (char '"')
341+ return ("",[],[(key,val)])
319342
320343codeBlockDelimited = try $ do
321− (size, lang) <- codeBlockDelimiter Nothing
344+ (size, attr) <- codeBlockDelimiter Nothing
322345 contents <- manyTill anyLine (codeBlockDelimiter (Just size))
323346 blanklines
324− return $ CodeBlock lang $ joinWithSep "\n" contents
347+ return $ CodeBlock attr $ joinWithSep "\n" contents
325348
326349codeBlockIndented = do
327350 contents <- many1 (indentedLine <|>
@@ -329,7 +352,7 @@ codeBlockIndented = do
329352 l <- indentedLine
330353 return $ b ++ l))
331354 optional blanklines
332− return $ CodeBlock "" $ stripTrailingNewlines $ concat contents
355+ return $ CodeBlock ("",[],[]) $ stripTrailingNewlines $ concat contents
333356
334357--
335358-- block quotes