@@ -37,6 +37,7 @@ import Text.Pandoc.Parsing hiding (newline, orderedListMarker, updateL
37import Text.Pandoc.Shared (compactify')
37import Text.Pandoc.Shared (compactify')
39import Control.Applicative (pure, (<$>), (<$), (<*>), (<*), (*>), (<**>))
39import Control.Applicative (pure, (<$>), (<$), (<*>), (<*), (*>), (<**>))
40+import Control.Arrow ((***))
40import Control.Monad (guard, when)
41import Control.Monad (guard, when)
41import Data.Char (toLower)
42import Data.Char (toLower)
42import Data.Default
43import Data.Default
@@ -155,6 +156,7 @@ block = choice [ mempty <$ blanklines
155 , orgBlock
156 , orgBlock
156 , example
157 , example
158 , specialLine
160 , specialLine
@@ -249,6 +251,43 @@ drawerEnd = try $
249 skipSpaces *> stringAnyCase ":END:" <* skipSpaces <* newline
251 skipSpaces *> stringAnyCase ":END:" <* skipSpaces <* newline
258+-- Figures (Image on a line by itself, preceded by name and/or caption)
259+figure :: OrgParser Blocks
261+ (tit, cap) <- (maybe mempty withFigPrefix *** fromMaybe mempty)
262+ <$> nameAndOrCaption
263+ src <- skipSpaces *> selfTarget <* skipSpaces <* newline
264+ guard (isImageFilename src)
265+ return . B.para $ B.image src tit cap
266+ where withFigPrefix cs = if "fig:" `isPrefixOf` cs
270+nameAndOrCaption :: OrgParser (Maybe String, Maybe Inlines)
271+nameAndOrCaption = try $ nameFirst <|> captionFirst
273+ nameFirst = try $ do
275+ c <- optionMaybe caption
277+ captionFirst = try $ do
279+ n <- optionMaybe name
282+caption :: OrgParser Inlines
283+caption = try $ annotation "CAPTION" *> inlinesTillNewline
285+name :: OrgParser String
286+name = try $ annotation "NAME" *> skipSpaces *> manyTill anyChar newline
288+annotation :: String -> OrgParser String
289+annotation ann = try $ metaLineStart *> stringAnyCase ann <* char ':'
252-- Comments, Options and Metadata
291-- Comments, Options and Metadata
253specialLine :: OrgParser Blocks
292specialLine :: OrgParser Blocks
254specialLine = try $ metaLine <|> commentLine
293specialLine = try $ metaLine <|> commentLine
@@ -274,7 +313,7 @@ declarationLine = try $ do
274 return mempty
313 return mempty
276metaValue :: OrgParser MetaValue
315metaValue :: OrgParser MetaValue
277−metaValue = MetaInlines . B.toList . trimInlines <$> restOfLine
316+metaValue = MetaInlines . B.toList <$> inlinesTillNewline
279metaKey :: OrgParser String
318metaKey :: OrgParser String
280metaKey = map toLower <$> many1 (noneOf ": \n\r")
319metaKey = map toLower <$> many1 (noneOf ": \n\r")
@@ -285,7 +324,7 @@ metaKey = map toLower <$> many1 (noneOf ": \n\r")
285header :: OrgParser Blocks
324header :: OrgParser Blocks
286header = try $
325header = try $
287 B.header <$> headerStart
326 B.header <$> headerStart
288− <*> (trimInlines <$> restOfLine)
327+ <*> inlinesTillNewline
290headerStart :: OrgParser Int
329headerStart :: OrgParser Int
291headerStart = try $
330headerStart = try $
@@ -421,13 +460,10 @@ setAligns aligns t = t{ orgTableAlignments = aligns }
421-- Paragraphs or Plain text
460-- Paragraphs or Plain text
422paraOrPlain :: OrgParser Blocks
461paraOrPlain :: OrgParser Blocks
423paraOrPlain = try $
462paraOrPlain = try $
424− trimInlines . mconcat
427− (try $ newline *> pure B.para)
463+ parseInlines <**> option B.plain (try $ newline *> pure B.para)
429−restOfLine :: OrgParser Inlines
465+inlinesTillNewline :: OrgParser Inlines
430−restOfLine = mconcat <$> manyTill inline newline
466+inlinesTillNewline = trimInlines . mconcat <$> manyTill inline newline
@@ -520,6 +556,8 @@ inline =
520 ] <* (guard =<< newlinesCountWithinLimits)
556 ] <* (guard =<< newlinesCountWithinLimits)
521 <?> "inline"
557 <?> "inline"
559+parseInlines :: OrgParser Inlines
560+parseInlines = trimInlines . mconcat <$> many1 inline
524-- treat these as potentially non-text when parsing inline:
562-- treat these as potentially non-text when parsing inline:
525specialChars :: [Char]
563specialChars :: [Char]
@@ -577,6 +615,9 @@ selflinkOrImage = try $ do
577 then B.image src "" ""
615 then B.image src "" ""
578 else B.link src "" (B.str src)
616 else B.link src "" (B.str src)
618+selfTarget :: OrgParser String
619+selfTarget = try $ char '[' *> linkTarget <* char ']'
580linkTarget :: OrgParser String
621linkTarget :: OrgParser String
581linkTarget = enclosed (char '[') (char ']') (noneOf "\n\r]")
622linkTarget = enclosed (char '[') (char ']') (noneOf "\n\r]")