git.iko.soy/typeable/pandoc
on master help sign in
Org reader: recognize babel result blocks with attributes
7852cd5Albert Krewinkel
src/Text/Pandoc/Readers/Org/Blocks.hs+18−20
@@ -122,18 +122,18 @@ attrFromBlockAttributes (BlockAttributes{..}) =
122 kv = filter ((`notElem` ["id", "class"]) . fst) blockAttrKeyValues
122 kv = filter ((`notElem` ["id", "class"]) . fst) blockAttrKeyValues
123 in (ident, classes, kv)
123 in (ident, classes, kv)
124
124
125−stringyMetaAttribute :: Monad m => (String -> Bool) -> OrgParser m (String, String)
125+stringyMetaAttribute :: Monad m => OrgParser m (String, String)
126−stringyMetaAttribute attrCheck = try $ do
126+stringyMetaAttribute = try $ do
127 metaLineStart
127 metaLineStart
128 attrName <- map toUpper <$> many1Till nonspaceChar (char ':')
128 attrName <- map toUpper <$> many1Till nonspaceChar (char ':')
129− guard $ attrCheck attrName
130 skipSpaces
129 skipSpaces
131− attrValue <- anyLine
130+ attrValue <- anyLine <|> ("" <$ newline)
132 return (attrName, attrValue)
131 return (attrName, attrValue)
133
132
134blockAttributes :: PandocMonad m => OrgParser m BlockAttributes
133blockAttributes :: PandocMonad m => OrgParser m BlockAttributes
135blockAttributes = try $ do
134blockAttributes = try $ do
136− kv <- many (stringyMetaAttribute attrCheck)
135+ kv <- many stringyMetaAttribute
136+ guard $ all (attrCheck . fst) kv
137 let caption = foldl' (appendValues "CAPTION") Nothing kv
137 let caption = foldl' (appendValues "CAPTION") Nothing kv
138 let kvAttrs = foldl' (appendValues "ATTR_HTML") Nothing kv
138 let kvAttrs = foldl' (appendValues "ATTR_HTML") Nothing kv
139 let name = lookup "NAME" kv
139 let name = lookup "NAME" kv
@@ -150,13 +150,7 @@ blockAttributes = try $ do
150 }
150 }
151 where
151 where
152 attrCheck :: String -> Bool
152 attrCheck :: String -> Bool
153− attrCheck attr =
153+ attrCheck x = x `elem` ["NAME", "LABEL", "CAPTION", "ATTR_HTML", "RESULTS"]
154− case attr of
155− "NAME" -> True
156− "LABEL" -> True
157− "CAPTION" -> True
158− "ATTR_HTML" -> True
159− _ -> False
160
154
161 appendValues :: String -> Maybe String -> (String, String) -> Maybe String
155 appendValues :: String -> Maybe String -> (String, String) -> Maybe String
162 appendValues attrName accValue (key, value) =
156 appendValues attrName accValue (key, value) =
@@ -166,6 +160,7 @@ blockAttributes = try $ do
166 Just acc -> Just $ acc ++ ' ':value
160 Just acc -> Just $ acc ++ ' ':value
167 Nothing -> Just value
161 Nothing -> Just value
168
162
163+-- | Parse key-value pairs for HTML attributes
169keyValues :: Monad m => OrgParser m [(String, String)]
164keyValues :: Monad m => OrgParser m [(String, String)]
170keyValues = try $
165keyValues = try $
171 manyTill ((,) <$> key <*> value) newline
166 manyTill ((,) <$> key <*> value) newline
@@ -301,16 +296,15 @@ codeBlock blockAttrs blockType = do
301 skipSpaces
296 skipSpaces
302 (classes, kv) <- codeHeaderArgs <|> (mempty <$ ignHeaders)
297 (classes, kv) <- codeHeaderArgs <|> (mempty <$ ignHeaders)
303 content <- rawBlockContent blockType
298 content <- rawBlockContent blockType
304− resultsContent <- trailingResultsBlock
299+ resultsContent <- option mempty babelResultsBlock
305 let id' = fromMaybe mempty $ blockAttrName blockAttrs
300 let id' = fromMaybe mempty $ blockAttrName blockAttrs
306 let codeBlck = B.codeBlockWith ( id', classes, kv ) content
301 let codeBlck = B.codeBlockWith ( id', classes, kv ) content
307 let labelledBlck = maybe (pure codeBlck)
302 let labelledBlck = maybe (pure codeBlck)
308 (labelDiv codeBlck)
303 (labelDiv codeBlck)
309 (blockAttrCaption blockAttrs)
304 (blockAttrCaption blockAttrs)
310− let resultBlck = fromMaybe mempty resultsContent
311 return $
305 return $
312− (if exportsCode kv then labelledBlck else mempty) <>
306+ (if exportsCode kv then labelledBlck else mempty) <>
313− (if exportsResults kv then resultBlck else mempty)
307+ (if exportsResults kv then resultsContent else mempty)
314 where
308 where
315 labelDiv :: Blocks -> F Inlines -> F Blocks
309 labelDiv :: Blocks -> F Inlines -> F Blocks
316 labelDiv blk value =
310 labelDiv blk value =
@@ -325,12 +319,16 @@ codeBlock blockAttrs blockType = do
325 exportsResults :: [(String, String)] -> Bool
319 exportsResults :: [(String, String)] -> Bool
326 exportsResults = maybe False (`elem` ["results", "both"]) . lookup "exports"
320 exportsResults = maybe False (`elem` ["results", "both"]) . lookup "exports"
327
321
322+-- | Parse the result of an evaluated babel code block.
328−trailingResultsBlock :: PandocMonad m => OrgParser m (Maybe (F Blocks))
323+babelResultsBlock :: PandocMonad m => OrgParser m (F Blocks)
329−trailingResultsBlock = optionMaybe . try $ do
324+babelResultsBlock = try $ do
330 blanklines
325 blanklines
331− stringAnyCase "#+RESULTS:"
326+ resultsMarker <|>
332− blankline
327+ (lookAhead . void . try $
328+ manyTill (metaLineStart *> anyLineNewline) resultsMarker)
333 block
329 block
330+ where
331+ resultsMarker = try . void $ stringAnyCase "#+RESULTS:" *> blankline
334
332
335-- | Parse code block arguments
333-- | Parse code block arguments
336codeHeaderArgs :: Monad m => OrgParser m ([String], [(String, String)])
334codeHeaderArgs :: 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
44import Text.Pandoc.Class (PandocMonad)
44import Text.Pandoc.Class (PandocMonad)
45import Text.Pandoc.Definition
45import Text.Pandoc.Definition
46
46
47−import Control.Monad (mzero, void)
47+import Control.Monad (mzero, void, when)
48import Data.Char (toLower)
48import Data.Char (toLower)
49import Data.List (intersperse)
49import Data.List (intersperse)
50import qualified Data.Map as M
50import qualified Data.Map as M
@@ -75,7 +75,9 @@ declarationLine :: PandocMonad m => OrgParser m ()
75declarationLine = try $ do
75declarationLine = try $ do
76 key <- map toLower <$> metaKey
76 key <- map toLower <$> metaKey
77 (key', value) <- metaValue key
77 (key', value) <- metaValue key
78+ when (key' /= "results") $
79+ updateState $ \st ->
78− updateState $ \st -> st { orgStateMeta = B.setMeta key' <$> value <*> orgStateMeta st }
80+ st { orgStateMeta = B.setMeta key' <$> value <*> orgStateMeta st }
79
81
80metaKey :: Monad m => OrgParser m String
82metaKey :: Monad m => OrgParser m String
81metaKey = map toLower <$> many1 (noneOf ": \n\r")
83metaKey = 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+```