summaryrefslogtreecommitdiff
path: root/src/Text/Pandoc/Readers/Org.hs
diff options
context:
space:
mode:
authorJohn MacFarlane <jgm@berkeley.edu>2014-04-13 14:03:15 -0700
committerJohn MacFarlane <jgm@berkeley.edu>2014-04-13 14:03:15 -0700
commitd5d4227ea5144d7c9da2ffdd44fbbd8131d4d86d (patch)
treed359b454ff5d0cb201a84089c02d1458deb0530a /src/Text/Pandoc/Readers/Org.hs
parentd4c1cd456c16298069b05e1da328e70dc87ea547 (diff)
parentae4280fba528efe68c5955cb3ca0779e6910f43b (diff)
Merge pull request #1238 from tarleb/org-figures
Org reader: Add support for figures
Diffstat (limited to 'src/Text/Pandoc/Readers/Org.hs')
-rw-r--r--src/Text/Pandoc/Readers/Org.hs57
1 files changed, 49 insertions, 8 deletions
diff --git a/src/Text/Pandoc/Readers/Org.hs b/src/Text/Pandoc/Readers/Org.hs
index 36b1ad287..901a49fc8 100644
--- a/src/Text/Pandoc/Readers/Org.hs
+++ b/src/Text/Pandoc/Readers/Org.hs
@@ -37,6 +37,7 @@ import Text.Pandoc.Parsing hiding (newline, orderedListMarker, updateL
import Text.Pandoc.Shared (compactify')
import Control.Applicative (pure, (<$>), (<$), (<*>), (<*), (*>), (<**>))
+import Control.Arrow ((***))
import Control.Monad (guard, when)
import Data.Char (toLower)
import Data.Default
@@ -155,6 +156,7 @@ block = choice [ mempty <$ blanklines
, orgBlock
, example
, drawer
+ , figure
, specialLine
, header
, hline
@@ -249,6 +251,43 @@ drawerEnd = try $
skipSpaces *> stringAnyCase ":END:" <* skipSpaces <* newline
+--
+-- Figures
+--
+
+-- Figures (Image on a line by itself, preceded by name and/or caption)
+figure :: OrgParser Blocks
+figure = try $ do
+ (tit, cap) <- (maybe mempty withFigPrefix *** fromMaybe mempty)
+ <$> nameAndOrCaption
+ src <- skipSpaces *> selfTarget <* skipSpaces <* newline
+ guard (isImageFilename src)
+ return . B.para $ B.image src tit cap
+ where withFigPrefix cs = if "fig:" `isPrefixOf` cs
+ then cs
+ else "fig:" ++ cs
+
+nameAndOrCaption :: OrgParser (Maybe String, Maybe Inlines)
+nameAndOrCaption = try $ nameFirst <|> captionFirst
+ where
+ nameFirst = try $ do
+ n <- name
+ c <- optionMaybe caption
+ return (Just n, c)
+ captionFirst = try $ do
+ c <- caption
+ n <- optionMaybe name
+ return (n, Just c)
+
+caption :: OrgParser Inlines
+caption = try $ annotation "CAPTION" *> inlinesTillNewline
+
+name :: OrgParser String
+name = try $ annotation "NAME" *> skipSpaces *> manyTill anyChar newline
+
+annotation :: String -> OrgParser String
+annotation ann = try $ metaLineStart *> stringAnyCase ann <* char ':'
+
-- Comments, Options and Metadata
specialLine :: OrgParser Blocks
specialLine = try $ metaLine <|> commentLine
@@ -274,7 +313,7 @@ declarationLine = try $ do
return mempty
metaValue :: OrgParser MetaValue
-metaValue = MetaInlines . B.toList . trimInlines <$> restOfLine
+metaValue = MetaInlines . B.toList <$> inlinesTillNewline
metaKey :: OrgParser String
metaKey = map toLower <$> many1 (noneOf ": \n\r")
@@ -285,7 +324,7 @@ metaKey = map toLower <$> many1 (noneOf ": \n\r")
header :: OrgParser Blocks
header = try $
B.header <$> headerStart
- <*> (trimInlines <$> restOfLine)
+ <*> inlinesTillNewline
headerStart :: OrgParser Int
headerStart = try $
@@ -421,13 +460,10 @@ setAligns aligns t = t{ orgTableAlignments = aligns }
-- Paragraphs or Plain text
paraOrPlain :: OrgParser Blocks
paraOrPlain = try $
- trimInlines . mconcat
- <$> many1 inline
- <**> option B.plain
- (try $ newline *> pure B.para)
+ parseInlines <**> option B.plain (try $ newline *> pure B.para)
-restOfLine :: OrgParser Inlines
-restOfLine = mconcat <$> manyTill inline newline
+inlinesTillNewline :: OrgParser Inlines
+inlinesTillNewline = trimInlines . mconcat <$> manyTill inline newline
--
@@ -520,6 +556,8 @@ inline =
] <* (guard =<< newlinesCountWithinLimits)
<?> "inline"
+parseInlines :: OrgParser Inlines
+parseInlines = trimInlines . mconcat <$> many1 inline
-- treat these as potentially non-text when parsing inline:
specialChars :: [Char]
@@ -577,6 +615,9 @@ selflinkOrImage = try $ do
then B.image src "" ""
else B.link src "" (B.str src)
+selfTarget :: OrgParser String
+selfTarget = try $ char '[' *> linkTarget <* char ']'
+
linkTarget :: OrgParser String
linkTarget = enclosed (char '[') (char ']') (noneOf "\n\r]")