pandoc-3.2: src/Text/Pandoc/Readers/Org/BlockStarts.hs
{-# LANGUAGE OverloadedStrings #-}
{- |
Module : Text.Pandoc.Readers.Org.BlockStarts
Copyright : Copyright (C) 2014-2024 Albert Krewinkel
License : GNU GPL, version 2 or above
Maintainer : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
Parsers for Org-mode inline elements.
-}
module Text.Pandoc.Readers.Org.BlockStarts
( exampleLineStart
, hline
, noteMarker
, tableStart
, drawerStart
, headerStart
, metaLineStart
, latexEnvStart
, commentLineStart
, bulletListStart
, orderedListStart
, endOfBlock
) where
import Control.Monad (void)
import Data.Text (Text)
import Text.Pandoc.Readers.Org.Parsing
import Text.Pandoc.Definition as Pandoc
import Text.Pandoc.Shared (safeRead)
import Text.Pandoc.Parsing (lowerAlpha, upperAlpha)
import Text.Pandoc.Extensions
import Data.Functor (($>))
-- | Horizontal Line (five -- dashes or more)
hline :: Monad m => OrgParser m ()
hline = try $ do
skipSpaces
string "-----"
many (char '-')
skipSpaces
newline
return ()
-- | Read the start of a header line, return the header level
headerStart :: Monad m => OrgParser m Int
headerStart = try $
(length <$> many1 (char '*')) <* many1 (char ' ') <* updateLastPreCharPos
tableStart :: Monad m => OrgParser m Char
tableStart = try $ skipSpaces *> char '|'
gridTableStart :: Monad m => OrgParser m ()
gridTableStart = try $ skipSpaces <* char '+' <* char '-'
latexEnvStart :: Monad m => OrgParser m Text
latexEnvStart = try $
skipSpaces *> string "\\begin{"
*> latexEnvName
<* string "}"
where
latexEnvName :: Monad m => OrgParser m Text
latexEnvName = try $ mappend <$> many1Char alphaNum <*> option "" (textStr "*")
listCounterCookie :: Monad m => OrgParser m Int
listCounterCookie = try $
string "[@"
*> parseNum
<* char ']'
<* (skipSpaces <|> lookAhead eol)
where parseNum = (safeRead =<< many1Char digit)
<|> snd <$> (lowerAlpha <|> upperAlpha)
bulletListStart :: Monad m => OrgParser m Int
bulletListStart = try $ do
ind <- length <$> many spaceChar
-- Unindented lists cannot use '*' bullets.
oneOf (if ind == 0 then "+-" else "*+-")
skipSpaces1 <|> lookAhead eol
optionMaybe listCounterCookie
return (ind + 1)
eol :: Monad m => OrgParser m ()
eol = void (char '\n')
orderedListStart :: Monad m => OrgParser m (Int, ListAttributes)
orderedListStart = try $ do
ind <- length <$> many spaceChar
fancy <- option False $ True <$ guardEnabled Ext_fancy_lists
-- Ordered list markers allowed in org-mode
let styles = (many1Char digit $> (if fancy
then Decimal
else DefaultStyle))
: if fancy
then [ fst <$> lowerAlpha
, fst <$> upperAlpha ]
else []
let delims = [ char '.' $> (if fancy
then Period
else DefaultDelim)
, char ')' $> (if fancy
then OneParen
else DefaultDelim)
]
style <- choice styles
delim <- choice delims
skipSpaces1 <|> lookAhead eol
start <- option 1 listCounterCookie
return (ind + 1, (start, style, delim))
drawerStart :: Monad m => OrgParser m Text
drawerStart = try $ skipSpaces *> drawerName <* skipSpaces <* newline
where drawerName = char ':' *> manyTillChar nonspaceChar (char ':')
metaLineStart :: Monad m => OrgParser m ()
metaLineStart = try $ skipSpaces <* string "#+"
commentLineStart :: Monad m => OrgParser m ()
commentLineStart = try $
-- the first char after '#' must be a plain space character or a newline
skipSpaces <* string "#" <* lookAhead (oneOf " \n")
exampleLineStart :: Monad m => OrgParser m ()
exampleLineStart = () <$ try (skipSpaces *> char ':' *> (void (char ' ') <|> lookAhead eol))
noteMarker :: Monad m => OrgParser m Text
noteMarker = try $ do
char '['
choice [ many1TillChar digit (char ']')
, (<>) <$> textStr "fn:"
<*> many1TillChar (noneOf "\n\r\t ") (char ']')
]
-- | Succeeds if the parser is at the end of a block.
endOfBlock :: Monad m => OrgParser m ()
endOfBlock = lookAhead . try $
void blankline <|> anyBlockStart
where
-- Succeeds if there is a new block starting at this position.
anyBlockStart :: Monad m => OrgParser m ()
anyBlockStart = try . choice $
[ exampleLineStart
, hline
, metaLineStart
, commentLineStart
, gridTableStart
, void noteMarker
, void tableStart
, void drawerStart
, void headerStart
, void latexEnvStart
, void bulletListStart
, void orderedListStart
]