git.iko.soy/typeable/pandoc
on master help sign in
Ignore leading space in org code blocks
1bfe39eEmanuel Evans
src/Text/Pandoc/Readers/Org.hs+20−4
@@ -391,6 +391,9 @@ lookupBlockAttribute key =
391
391
392type BlockProperties = (Int, String) -- (Indentation, Block-Type)
392type BlockProperties = (Int, String) -- (Indentation, Block-Type)
393
393
394+updateIndent :: BlockProperties -> Int -> BlockProperties
395+updateIndent (_, blkType) indent = (indent, blkType)
396+
394orgBlock :: OrgParser (F Blocks)
397orgBlock :: OrgParser (F Blocks)
395orgBlock = try $ do
398orgBlock = try $ do
396 blockProp@(_, blkType) <- blockHeaderStart
399 blockProp@(_, blkType) <- blockHeaderStart
@@ -407,11 +410,23 @@ orgBlock = try $ do
407 _ -> withParsed (fmap $ divWithClass blkType)
410 _ -> withParsed (fmap $ divWithClass blkType)
408
411
409blockHeaderStart :: OrgParser (Int, String)
412blockHeaderStart :: OrgParser (Int, String)
410−blockHeaderStart = try $ (,) <$> indent <*> blockType
413+blockHeaderStart = try $ (,) <$> indentation <*> blockType
411 where
414 where
412− indent = length <$> many spaceChar
413 blockType = map toLower <$> (stringAnyCase "#+begin_" *> orgArgWord)
415 blockType = map toLower <$> (stringAnyCase "#+begin_" *> orgArgWord)
414
416
417+indentation :: OrgParser Int
418+indentation = try $ do
419+ tabStop <- getOption readerTabStop
420+ s <- many spaceChar
421+ return $ spaceLength tabStop s
422+
423+spaceLength :: Int -> String -> Int
424+spaceLength tabStop s = (sum . map charLen) s
425+ where
426+ charLen ' ' = 1
427+ charLen '\t' = tabStop
428+ charLen _ = 0
429+
415withRaw' :: (String -> F Blocks) -> BlockProperties -> OrgParser (F Blocks)
430withRaw' :: (String -> F Blocks) -> BlockProperties -> OrgParser (F Blocks)
416withRaw' f blockProp = (ignHeaders *> (f <$> rawBlockContent blockProp))
431withRaw' f blockProp = (ignHeaders *> (f <$> rawBlockContent blockProp))
417
432
@@ -450,7 +465,8 @@ codeBlock blkProp = do
450 skipSpaces
465 skipSpaces
451 (classes, kv) <- codeHeaderArgs <|> (mempty <$ ignHeaders)
466 (classes, kv) <- codeHeaderArgs <|> (mempty <$ ignHeaders)
452 id' <- fromMaybe "" <$> lookupBlockAttribute "name"
467 id' <- fromMaybe "" <$> lookupBlockAttribute "name"
468+ leadingIndent <- lookAhead indentation
453− content <- rawBlockContent blkProp
469+ content <- rawBlockContent (updateIndent blkProp leadingIndent)
454 resultsContent <- followingResultsBlock
470 resultsContent <- followingResultsBlock
455 let includeCode = exportsCode kv
471 let includeCode = exportsCode kv
456 let includeResults = exportsResults kv
472 let includeResults = exportsResults kv
@@ -472,7 +488,7 @@ rawBlockContent (indent, blockType) = try $
472 unlines . map commaEscaped <$> manyTill indentedLine blockEnder
488 unlines . map commaEscaped <$> manyTill indentedLine blockEnder
473 where
489 where
474 indentedLine = try $ ("" <$ blankline) <|> (indentWith indent *> anyLine)
490 indentedLine = try $ ("" <$ blankline) <|> (indentWith indent *> anyLine)
475− blockEnder = try $ indentWith indent *> stringAnyCase ("#+end_" <> blockType)
491+ blockEnder = try $ skipSpaces *> stringAnyCase ("#+end_" <> blockType)
476
492
477parsedBlockContent :: BlockProperties -> OrgParser (F Blocks)
493parsedBlockContent :: BlockProperties -> OrgParser (F Blocks)
478parsedBlockContent blkProps = try $ do
494parsedBlockContent blkProps = try $ do
tests/Tests/Readers/Org.hs+27
@@ -1054,6 +1054,33 @@ tests =
1054 " where greeting = \"moin\"\n"
1054 " where greeting = \"moin\"\n"
1055 in codeBlockWith attr' code'
1055 in codeBlockWith attr' code'
1056
1056
1057+ , "Source block with indented code" =:
1058+ unlines [ " #+BEGIN_SRC haskell"
1059+ , " main = putStrLn greeting"
1060+ , " where greeting = \"moin\""
1061+ , " #+END_SRC" ] =?>
1062+ let attr' = ("", ["haskell"], [])
1063+ code' = "main = putStrLn greeting\n" ++
1064+ " where greeting = \"moin\"\n"
1065+ in codeBlockWith attr' code'
1066+
1067+ , "Source block with tab-indented code" =:
1068+ unlines [ "\t#+BEGIN_SRC haskell"
1069+ , "\tmain = putStrLn greeting"
1070+ , "\t where greeting = \"moin\""
1071+ , "\t#+END_SRC" ] =?>
1072+ let attr' = ("", ["haskell"], [])
1073+ code' = "main = putStrLn greeting\n" ++
1074+ " where greeting = \"moin\"\n"
1075+ in codeBlockWith attr' code'
1076+
1077+ , "Empty source block" =:
1078+ unlines [ " #+BEGIN_SRC haskell"
1079+ , " #+END_SRC" ] =?>
1080+ let attr' = ("", ["haskell"], [])
1081+ code' = ""
1082+ in codeBlockWith attr' code'
1083+
1057 , "Source block between paragraphs" =:
1084 , "Source block between paragraphs" =:
1058 unlines [ "Low German greeting"
1085 unlines [ "Low German greeting"
1059 , " #+BEGIN_SRC haskell"
1086 , " #+BEGIN_SRC haskell"