git.iko.soy/typeable/pandoc
on master help sign in
Org reader: Read inline code blocks

Org's inline code blocks take forms like `src_haskell(print "hi")` and are frequently used to include results from computations called from within the document. The blocks are read as inline code and marked with the special class `rundoc-block`. Proper handling and execution of these blocks is the subject of a separate library, rundoc, which is work in progress. This closes #1278.

commit71bd4fb2b3778d3906a63938625ebcadca40b8c8 authorAlbert Krewinkel <tarleb@moltkeplatz.de> dateMon 5 May 2014, 14:39 (12 years ago) parent7524e8e
2 files changed+58−3
src/Text/Pandoc/Readers/Org.hs+40−3 tests/Tests/Readers/Org.hs+18
src/Text/Pandoc/Readers/Org.hs+40−3
@@ -43,6 +43,7 @@ import Text.Pandoc.Shared (compactify', compactify'DL)
4343
4444import Control.Applicative ( Applicative, pure
4545 , (<$>), (<$), (<*>), (<*), (*>), (<**>) )
46+import Control.Arrow (first)
4647import Control.Monad (foldM, guard, liftM, liftM2, mzero, when)
4748import Control.Monad.Reader (Reader, runReader, ask, asks)
4849import Data.Char (isAlphaNum, toLower)
@@ -721,7 +722,6 @@ bulletList = fmap B.bulletList . fmap compactify' . sequence
721722 <$> many1 (listItem bulletListStart)
722723
723724orderedList :: OrgParser (F Blocks)
724−-- orderedList = B.orderedList . compactify' <$> many1 (listItem orderedListStart)
725725orderedList = fmap B.orderedList . fmap compactify' . sequence
726726 <$> many1 (listItem orderedListStart)
727727
@@ -746,11 +746,11 @@ definitionListItem :: OrgParser Int
746746definitionListItem parseMarkerGetLength = try $ do
747747 markerLength <- parseMarkerGetLength
748748 term <- manyTill (noneOf "\n\r") (try $ string "::")
749− first <- anyLineNewline
749+ line1 <- anyLineNewline
750750 blank <- option "" ("\n" <$ blankline)
751751 cont <- concat <$> many (listContinuation markerLength)
752752 term' <- parseFromString inline term
753− contents' <- parseFromString parseBlocks $ first ++ blank ++ cont
753+ contents' <- parseFromString parseBlocks $ line1 ++ blank ++ cont
754754 return $ (,) <$> term' <*> fmap (:[]) contents'
755755
756756
@@ -789,6 +789,7 @@ inline =
789789 , footnote
790790 , linkOrImage
791791 , anchor
792+ , inlineCodeBlock
792793 , str
793794 , endline
794795 , emph
@@ -989,6 +990,42 @@ solidify = map replaceSpecialChar
989990 | c `elem` "_.-:" = c
990991 | otherwise = '-'
991992
993+-- | Parses an inline code block and marks it as an babel block.
994+inlineCodeBlock :: OrgParser (F Inlines)
995+inlineCodeBlock = try $ do
996+ string "src_"
997+ lang <- many1 orgArgWordChar
998+ opts <- option [] $ enclosedByPair '[' ']' blockOption
999+ inlineCode <- enclosedByPair '{' '}' (noneOf "\n\r")
1000+ let attrClasses = [translateLang lang, rundocBlockClass]
1001+ let attrKeyVal = map toRundocAttrib (("language", lang) : opts)
1002+ returnF $ B.codeWith ("", attrClasses, attrKeyVal) inlineCode
1003+ where enclosedByPair s e p = char s *> many1Till p (char e)
1004+
1005+-- | The class-name used to mark rundoc blocks.
1006+rundocBlockClass :: String
1007+rundocBlockClass = "rundoc-block"
1008+
1009+blockOption :: OrgParser (String, String)
1010+blockOption = try $ (,) <$> orgArgKey <*> orgArgValue
1011+
1012+orgArgKey :: OrgParser String
1013+orgArgKey = try $
1014+ skipSpaces *> char ':'
1015+ *> many1 orgArgWordChar
1016+ <* many1 spaceChar
1017+
1018+orgArgValue :: OrgParser String
1019+orgArgValue = try $
1020+ skipSpaces *> many1 orgArgWordChar
1021+ <* skipSpaces
1022+
1023+orgArgWordChar :: OrgParser Char
1024+orgArgWordChar = alphaNum <|> oneOf "-_"
1025+
1026+toRundocAttrib :: (String, String) -> (String, String)
1027+toRundocAttrib = first ("rundoc-" ++)
1028+
9921029emph :: OrgParser (F Inlines)
9931030emph = fmap B.emph <$> emphasisBetween '/'
9941031
tests/Tests/Readers/Org.hs+18
@@ -207,6 +207,24 @@ tests =
207207 "<<anchor>> Link here later." =?>
208208 (para $ spanWith ("anchor", [], []) mempty <>
209209 "Link" <> space <> "here" <> space <> "later.")
210+
211+ , "Inline code block" =:
212+ "src_emacs-lisp{(message \"Hello\")}" =?>
213+ (para $ codeWith ( ""
214+ , [ "commonlisp", "rundoc-block" ]
215+ , [ ("rundoc-language", "emacs-lisp") ])
216+ "(message \"Hello\")")
217+
218+ , "Inline code block with arguments" =:
219+ "src_sh[:export both :results output]{echo 'Hello, World'}" =?>
220+ (para $ codeWith ( ""
221+ , [ "bash", "rundoc-block" ]
222+ , [ ("rundoc-language", "sh")
223+ , ("rundoc-export", "both")
224+ , ("rundoc-results", "output")
225+ ]
226+ )
227+ "echo 'Hello, World'")
210228 ]
211229
212230 , testGroup "Meta Information" $