git.iko.soy/typeable/pandoc
on master help sign in
Org reader: recognize babel result blocks with attributes

Babel result blocks can have block attributes like captions and names. Result blocks with attributes were not recognized and were parsed as normal blocks without attributes. Fixes: #3706

commit7852cd560398f0da22783b51fe21db4dc3eb0a54 authorAlbert Krewinkel <albert@zeitkraut.de> dateWed 31 May 2017, 20:01 (9 years ago) parent4b98d04
3 files changed+66−22
src/Text/Pandoc/Readers/Org/Blocks.hs+18−20 src/Text/Pandoc/Readers/Org/Meta.hs+4−2 test/command/3706.md+44
src/Text/Pandoc/Readers/Org/Blocks.hs+18−20
@@ -122,18 +122,18 @@ attrFromBlockAttributes (BlockAttributes{..}) =
122122 kv = filter ((`notElem` ["id", "class"]) . fst) blockAttrKeyValues
123123 in (ident, classes, kv)
124124
125−stringyMetaAttribute :: Monad m => (String -> Bool) -> OrgParser m (String, String)
126−stringyMetaAttribute attrCheck = try $ do
125+stringyMetaAttribute :: Monad m => OrgParser m (String, String)
126+stringyMetaAttribute = try $ do
127127 metaLineStart
128128 attrName <- map toUpper <$> many1Till nonspaceChar (char ':')
129− guard $ attrCheck attrName
130129 skipSpaces
131− attrValue <- anyLine
130+ attrValue <- anyLine <|> ("" <$ newline)
132131 return (attrName, attrValue)
133132
134133blockAttributes :: PandocMonad m => OrgParser m BlockAttributes
135134blockAttributes = try $ do
136− kv <- many (stringyMetaAttribute attrCheck)
135+ kv <- many stringyMetaAttribute
136+ guard $ all (attrCheck . fst) kv
137137 let caption = foldl' (appendValues "CAPTION") Nothing kv
138138 let kvAttrs = foldl' (appendValues "ATTR_HTML") Nothing kv
139139 let name = lookup "NAME" kv
@@ -150,13 +150,7 @@ blockAttributes = try $ do
150150 }
151151 where
152152 attrCheck :: String -> Bool
153− attrCheck attr =
154− case attr of
155− "NAME" -> True
156− "LABEL" -> True
157− "CAPTION" -> True
158− "ATTR_HTML" -> True
159− _ -> False
153+ attrCheck x = x `elem` ["NAME", "LABEL", "CAPTION", "ATTR_HTML", "RESULTS"]
160154
161155 appendValues :: String -> Maybe String -> (String, String) -> Maybe String
162156 appendValues attrName accValue (key, value) =
@@ -166,6 +160,7 @@ blockAttributes = try $ do
166160 Just acc -> Just $ acc ++ ' ':value
167161 Nothing -> Just value
168162
163+-- | Parse key-value pairs for HTML attributes
169164keyValues :: Monad m => OrgParser m [(String, String)]
170165keyValues = try $
171166 manyTill ((,) <$> key <*> value) newline
@@ -301,16 +296,15 @@ codeBlock blockAttrs blockType = do
301296 skipSpaces
302297 (classes, kv) <- codeHeaderArgs <|> (mempty <$ ignHeaders)
303298 content <- rawBlockContent blockType
304− resultsContent <- trailingResultsBlock
299+ resultsContent <- option mempty babelResultsBlock
305300 let id' = fromMaybe mempty $ blockAttrName blockAttrs
306301 let codeBlck = B.codeBlockWith ( id', classes, kv ) content
307302 let labelledBlck = maybe (pure codeBlck)
308303 (labelDiv codeBlck)
309304 (blockAttrCaption blockAttrs)
310− let resultBlck = fromMaybe mempty resultsContent
311305 return $
312− (if exportsCode kv then labelledBlck else mempty) <>
313− (if exportsResults kv then resultBlck else mempty)
306+ (if exportsCode kv then labelledBlck else mempty) <>
307+ (if exportsResults kv then resultsContent else mempty)
314308 where
315309 labelDiv :: Blocks -> F Inlines -> F Blocks
316310 labelDiv blk value =
@@ -325,12 +319,16 @@ codeBlock blockAttrs blockType = do
325319 exportsResults :: [(String, String)] -> Bool
326320 exportsResults = maybe False (`elem` ["results", "both"]) . lookup "exports"
327321
328−trailingResultsBlock :: PandocMonad m => OrgParser m (Maybe (F Blocks))
329−trailingResultsBlock = optionMaybe . try $ do
322+-- | Parse the result of an evaluated babel code block.
323+babelResultsBlock :: PandocMonad m => OrgParser m (F Blocks)
324+babelResultsBlock = try $ do
330325 blanklines
331− stringAnyCase "#+RESULTS:"
332− blankline
326+ resultsMarker <|>
327+ (lookAhead . void . try $
328+ manyTill (metaLineStart *> anyLineNewline) resultsMarker)
333329 block
330+ where
331+ resultsMarker = try . void $ stringAnyCase "#+RESULTS:" *> blankline
334332
335333-- | Parse code block arguments
336334codeHeaderArgs :: Monad m => OrgParser m ([String], [(String, String)])
src/Text/Pandoc/Readers/Org/Meta.hs+4−2
@@ -44,7 +44,7 @@ import qualified Text.Pandoc.Builder as B
4444import Text.Pandoc.Class (PandocMonad)
4545import Text.Pandoc.Definition
4646
47−import Control.Monad (mzero, void)
47+import Control.Monad (mzero, void, when)
4848import Data.Char (toLower)
4949import Data.List (intersperse)
5050import qualified Data.Map as M
@@ -75,7 +75,9 @@ declarationLine :: PandocMonad m => OrgParser m ()
7575declarationLine = try $ do
7676 key <- map toLower <$> metaKey
7777 (key', value) <- metaValue key
78− updateState $ \st -> st { orgStateMeta = B.setMeta key' <$> value <*> orgStateMeta st }
78+ when (key' /= "results") $
79+ updateState $ \st ->
80+ st { orgStateMeta = B.setMeta key' <$> value <*> orgStateMeta st }
7981
8082metaKey :: Monad m => OrgParser m String
8183metaKey = map toLower <$> many1 (noneOf ": \n\r")
test/command/3706.mdnew file+44
@@ -0,0 +1,44 @@
1+Results marker can be hidden in block attributes (#3706)
2+
3+```
4+pandoc -f org -t native
5+#+BEGIN_SRC R :exports results :colnames yes
6+ data.frame(Id = 1:3, Desc = rep("La",3))
7+#+END_SRC
8+
9+#+CAPTION: Lalelu.
10+#+LABEL: tab
11+#+RESULTS:
12+| Id | Desc |
13+|----+------|
14+| 1 | La |
15+| 2 | La |
16+| 3 | La |
17+^D
18+[Table [Str "Lalelu."] [AlignDefault,AlignDefault] [0.0,0.0]
19+ [[Plain [Str "Id"]]
20+ ,[Plain [Str "Desc"]]]
21+ [[[Plain [Str "1"]]
22+ ,[Plain [Str "La"]]]
23+ ,[[Plain [Str "2"]]
24+ ,[Plain [Str "La"]]]
25+ ,[[Plain [Str "3"]]
26+ ,[Plain [Str "La"]]]]]
27+```
28+
29+```
30+pandoc -f org -t native
31+#+BEGIN_SRC R :exports none :colnames yes
32+ data.frame(Id = 1:2, Desc = rep("La",2))
33+#+END_SRC
34+
35+#+CAPTION: Lalelu.
36+#+LABEL: tab
37+#+RESULTS:
38+| Id | Desc |
39+|----+------|
40+| 1 | La |
41+| 2 | La |
42+^D
43+[]
44+```