git.iko.soy/typeable/pandoc
on master help sign in
Ignore leading space in org code blocks

Fixes #2862 Also fix up tab handling for leading whitespace in code blocks.

commit1bfe39e24cb58c361a05f419ef9a4a5263f558f6 authorEmanuel Evans <mail@emanuel.industries> dateSun 24 Apr 2016, 21:58 (11 years ago) parenta0fae92
2 files changed+47−4
src/Text/Pandoc/Readers/Org.hs+20−4 tests/Tests/Readers/Org.hs+27
src/Text/Pandoc/Readers/Org.hs+20−4
@@ -391,6 +391,9 @@ lookupBlockAttribute key =
391391
392392type BlockProperties = (Int, String) -- (Indentation, Block-Type)
393393
394+updateIndent :: BlockProperties -> Int -> BlockProperties
395+updateIndent (_, blkType) indent = (indent, blkType)
396+
394397orgBlock :: OrgParser (F Blocks)
395398orgBlock = try $ do
396399 blockProp@(_, blkType) <- blockHeaderStart
@@ -407,11 +410,23 @@ orgBlock = try $ do
407410 _ -> withParsed (fmap $ divWithClass blkType)
408411
409412blockHeaderStart :: OrgParser (Int, String)
410−blockHeaderStart = try $ (,) <$> indent <*> blockType
413+blockHeaderStart = try $ (,) <$> indentation <*> blockType
411414 where
412− indent = length <$> many spaceChar
413415 blockType = map toLower <$> (stringAnyCase "#+begin_" *> orgArgWord)
414416
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+
415430withRaw' :: (String -> F Blocks) -> BlockProperties -> OrgParser (F Blocks)
416431withRaw' f blockProp = (ignHeaders *> (f <$> rawBlockContent blockProp))
417432
@@ -450,7 +465,8 @@ codeBlock blkProp = do
450465 skipSpaces
451466 (classes, kv) <- codeHeaderArgs <|> (mempty <$ ignHeaders)
452467 id' <- fromMaybe "" <$> lookupBlockAttribute "name"
453− content <- rawBlockContent blkProp
468+ leadingIndent <- lookAhead indentation
469+ content <- rawBlockContent (updateIndent blkProp leadingIndent)
454470 resultsContent <- followingResultsBlock
455471 let includeCode = exportsCode kv
456472 let includeResults = exportsResults kv
@@ -472,7 +488,7 @@ rawBlockContent (indent, blockType) = try $
472488 unlines . map commaEscaped <$> manyTill indentedLine blockEnder
473489 where
474490 indentedLine = try $ ("" <$ blankline) <|> (indentWith indent *> anyLine)
475− blockEnder = try $ indentWith indent *> stringAnyCase ("#+end_" <> blockType)
491+ blockEnder = try $ skipSpaces *> stringAnyCase ("#+end_" <> blockType)
476492
477493parsedBlockContent :: BlockProperties -> OrgParser (F Blocks)
478494parsedBlockContent blkProps = try $ do
tests/Tests/Readers/Org.hs+27
@@ -1054,6 +1054,33 @@ tests =
10541054 " where greeting = \"moin\"\n"
10551055 in codeBlockWith attr' code'
10561056
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+
10571084 , "Source block between paragraphs" =:
10581085 unlines [ "Low German greeting"
10591086 , " #+BEGIN_SRC haskell"