diff options
Diffstat (limited to 'src/Text')
-rw-r--r-- | src/Text/Pandoc/Readers/Org.hs | 64 | ||||
-rw-r--r-- | src/Text/Pandoc/Writers/Org.hs | 2 |
2 files changed, 54 insertions, 12 deletions
diff --git a/src/Text/Pandoc/Readers/Org.hs b/src/Text/Pandoc/Readers/Org.hs index ceac69367..bda0b0262 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 @@ -44,9 +45,6 @@ import Data.List (foldl', isPrefixOf, isSuffixOf) import Data.Maybe (listToMaybe, fromMaybe) import Data.Monoid (mconcat, mempty, mappend) --- Ignore HLint warnings to use String instead of [Char] -{-# ANN module ("HLint: ignore Use String" :: String) #-} - -- | Parse org-mode string and return a Pandoc document. readOrg :: ReaderOptions -- ^ Reader options -> String -- ^ String to parse (assuming @'\n'@ line endings) @@ -158,6 +156,7 @@ block = choice [ mempty <$ blanklines , orgBlock , example , drawer + , figure , specialLine , header , hline @@ -252,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 @@ -277,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") @@ -288,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 $ @@ -424,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 -- @@ -506,6 +539,7 @@ anyLineNewline = (++ "\n") <$> anyLine inline :: OrgParser Inlines inline = choice [ whitespace + , linebreak , link , str , endline @@ -523,6 +557,8 @@ inline = ] <* (guard =<< newlinesCountWithinLimits) <?> "inline" +parseInlines :: OrgParser Inlines +parseInlines = trimInlines . mconcat <$> many1 inline -- treat these as potentially non-text when parsing inline: specialChars :: [Char] @@ -535,6 +571,9 @@ whitespace = B.space <$ skipMany1 spaceChar <* updateLastForbiddenCharPos <?> "whitespace" +linebreak :: OrgParser Inlines +linebreak = try $ B.linebreak <$ string "\\\\" <* skipSpaces <* newline + str :: OrgParser Inlines str = B.str <$> many1 (noneOf $ specialChars ++ "\n\r ") <* updateLastStrPos @@ -580,6 +619,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]") diff --git a/src/Text/Pandoc/Writers/Org.hs b/src/Text/Pandoc/Writers/Org.hs index d318c5f6a..58a5729e7 100644 --- a/src/Text/Pandoc/Writers/Org.hs +++ b/src/Text/Pandoc/Writers/Org.hs @@ -271,7 +271,7 @@ inlineToOrg (Math t str) = do else "$$" <> text str <> "$$" inlineToOrg (RawInline f str) | f == "tex" || f == "latex" = return $ text str inlineToOrg (RawInline _ _) = return empty -inlineToOrg (LineBreak) = return cr -- there's no line break in Org +inlineToOrg (LineBreak) = return (text "\\\\" <> cr) inlineToOrg Space = return space inlineToOrg (Link txt (src, _)) = do case txt of |