@@ -284,6 +284,11 @@ block = choice [ mempty <$ blanklines
284 ] <?> "block"
284 ] <?> "block"
287+-- | Parse a horizontal rule into a block element
288+horizontalRule :: Monad m => OrgParser m (F Blocks)
289+horizontalRule = return B.horizontalRule <$ try hline
288-- Block Attributes
293-- Block Attributes
@@ -522,28 +527,70 @@ trailingResultsBlock = optionMaybe . try $ do
524-- | Parse code block arguments
529-- | Parse code block arguments
525−-- TODO: We currently don't handle switches.
526codeHeaderArgs :: Monad m => OrgParser m ([String], [(String, String)])
530codeHeaderArgs :: Monad m => OrgParser m ([String], [(String, String)])
527codeHeaderArgs = try $ do
531codeHeaderArgs = try $ do
528 language <- skipSpaces *> orgArgWord
532 language <- skipSpaces *> orgArgWord
529− _ <- skipSpaces *> (try $ switch `sepBy` (many1 spaceChar))
533+ (switchClasses, switchKv) <- switchesAsAttributes
530 parameters <- manyTill blockOption newline
534 parameters <- manyTill blockOption newline
531 let pandocLang = translateLang language
535 let pandocLang = translateLang language
536+ let classes = pandocLang : switchClasses
533 if hasRundocParameters parameters
538 if hasRundocParameters parameters
534− then ( [ pandocLang, rundocBlockClass ]
539+ then ( classes <> [ rundocBlockClass ]
535− , map toRundocAttrib (("language", language) : parameters)
540+ , switchKv <> map toRundocAttrib (("language", language) : parameters)
537− else ([ pandocLang ], parameters)
542+ else (classes, switchKv <> parameters)
539 hasRundocParameters = not . null
544 hasRundocParameters = not . null
541−switch :: Monad m => OrgParser m (Char, Maybe String)
546+switchesAsAttributes :: Monad m => OrgParser m ([String], [(String, String)])
542−switch = try $ simpleSwitch <|> lineNumbersSwitch
547+switchesAsAttributes = try $ do
548+ switches <- skipSpaces *> (try $ switch `sepBy` (many1 spaceChar))
549+ return $ foldr addToAttr ([], []) switches
544− simpleSwitch = (\c -> (c, Nothing)) <$> (oneOf "-+" *> letter)
551+ addToAttr :: (Char, Maybe String, SwitchPolarity)
545− lineNumbersSwitch = (\ls -> ('l', Just ls)) <$>
552+ -> ([String], [(String, String)])
553+ -> ([String], [(String, String)])
554+ addToAttr ('n', lineNum, pol) (cls, kv) =
555+ let kv' = case lineNum of
556+ Just num -> (("startFrom", num):kv)
559+ SwitchPlus -> "continuedSourceBlock":cls
561+ in ("numberLines":cls', kv')
564+-- | Whether a switch flag is specified with @+@ or @-@.
565+data SwitchPolarity = SwitchPlus | SwitchMinus
568+-- | Parses a switch's polarity.
569+switchPolarity :: Monad m => OrgParser m SwitchPolarity
570+switchPolarity = (SwitchMinus <$ char '-') <|> (SwitchPlus <$ char '+')
572+-- | Parses a source block switch option.
573+switch :: Monad m => OrgParser m (Char, Maybe String, SwitchPolarity)
574+switch = try $ lineNumberSwitch <|> labelSwitch <|> simpleSwitch
576+ simpleSwitch = (\pol c -> (c, Nothing, pol)) <$> switchPolarity <*> letter
577+ labelSwitch = genericSwitch 'l' $
546− (string "-l \"" *> many1Till nonspaceChar (char '"'))
578+ char '"' *> many1Till nonspaceChar (char '"')
580+-- | Generic source block switch-option parser.
581+genericSwitch :: Monad m
583+ -> OrgParser m String
584+ -> OrgParser m (Char, Maybe String, SwitchPolarity)
585+genericSwitch c p = try $ do
586+ polarity <- switchPolarity <* char c <* skipSpaces
587+ arg <- optionMaybe p
588+ return $ (c, arg, polarity)
590+-- | Reads a line number switch option. The line number switch can be used with
591+-- example and source blocks.
592+lineNumberSwitch :: Monad m => OrgParser m (Char, Maybe String, SwitchPolarity)
593+lineNumberSwitch = genericSwitch 'n' (many digit)
548blockOption :: Monad m => OrgParser m (String, String)
595blockOption :: Monad m => OrgParser m (String, String)
549blockOption = try $ do
596blockOption = try $ do
@@ -558,9 +605,6 @@ orgParamValue = try $
558 *> many1 nonspaceChar
605 *> many1 nonspaceChar
559 <* skipSpaces
606 <* skipSpaces
561−horizontalRule :: Monad m => OrgParser m (F Blocks)
562−horizontalRule = return B.horizontalRule <$ try hline
566-- Drawers
610-- Drawers