1{-# LANGUAGE OverloadedStrings #-} 2{- | 3 Module : Text.Pandoc.Readers.Org.BlockStarts 4 Copyright : Copyright (C) 2014-2021 Albert Krewinkel 5 License : GNU GPL, version 2 or above 6 7 Maintainer : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de> 8 9Parsers for Org-mode inline elements. 10-} 11module Text.Pandoc.Readers.Org.BlockStarts 12 ( exampleLineStart 13 , hline 14 , noteMarker 15 , tableStart 16 , drawerStart 17 , headerStart 18 , metaLineStart 19 , latexEnvStart 20 , commentLineStart 21 , bulletListStart 22 , orderedListStart 23 , endOfBlock 24 ) where 25 26import Control.Monad (void) 27import Data.Text (Text) 28import qualified Data.Text as T 29import Text.Pandoc.Readers.Org.Parsing 30 31-- | Horizontal Line (five -- dashes or more) 32hline :: Monad m => OrgParser m () 33hline = try $ do 34 skipSpaces 35 string "-----" 36 many (char '-') 37 skipSpaces 38 newline 39 return () 40 41-- | Read the start of a header line, return the header level 42headerStart :: Monad m => OrgParser m Int 43headerStart = try $ 44 (length <$> many1 (char '*')) <* many1 (char ' ') <* updateLastPreCharPos 45 46tableStart :: Monad m => OrgParser m Char 47tableStart = try $ skipSpaces *> char '|' 48 49gridTableStart :: Monad m => OrgParser m () 50gridTableStart = try $ skipSpaces <* char '+' <* char '-' 51 52 53latexEnvStart :: Monad m => OrgParser m Text 54latexEnvStart = try $ 55 skipSpaces *> string "\\begin{" 56 *> latexEnvName 57 <* string "}" 58 <* blankline 59 where 60 latexEnvName :: Monad m => OrgParser m Text 61 latexEnvName = try $ mappend <$> many1Char alphaNum <*> option "" (textStr "*") 62 63bulletListStart :: Monad m => OrgParser m Int 64bulletListStart = try $ do 65 ind <- length <$> many spaceChar 66 -- Unindented lists cannot use '*' bullets. 67 oneOf (if ind == 0 then "+-" else "*+-") 68 skipSpaces1 <|> lookAhead eol 69 return (ind + 1) 70 71genericListStart :: Monad m 72 => OrgParser m Text 73 -> OrgParser m Int 74genericListStart listMarker = try $ do 75 ind <- length <$> many spaceChar 76 void listMarker 77 skipSpaces1 <|> lookAhead eol 78 return (ind + 1) 79 80eol :: Monad m => OrgParser m () 81eol = void (char '\n') 82 83orderedListStart :: Monad m => OrgParser m Int 84orderedListStart = genericListStart orderedListMarker 85 -- Ordered list markers allowed in org-mode 86 where orderedListMarker = T.snoc <$> many1Char digit <*> oneOf ".)" 87 88drawerStart :: Monad m => OrgParser m Text 89drawerStart = try $ skipSpaces *> drawerName <* skipSpaces <* newline 90 where drawerName = char ':' *> manyTillChar nonspaceChar (char ':') 91 92metaLineStart :: Monad m => OrgParser m () 93metaLineStart = try $ skipSpaces <* string "#+" 94 95commentLineStart :: Monad m => OrgParser m () 96commentLineStart = try $ 97 -- the first char after '#' must be a plain space character or a newline 98 skipSpaces <* string "#" <* lookAhead (oneOf " \n") 99 100exampleLineStart :: Monad m => OrgParser m () 101exampleLineStart = () <$ try (skipSpaces *> string ": ") 102 103noteMarker :: Monad m => OrgParser m Text 104noteMarker = try $ do 105 char '[' 106 choice [ many1TillChar digit (char ']') 107 , (<>) <$> textStr "fn:" 108 <*> many1TillChar (noneOf "\n\r\t ") (char ']') 109 ] 110 111-- | Succeeds if the parser is at the end of a block. 112endOfBlock :: Monad m => OrgParser m () 113endOfBlock = lookAhead . try $ 114 void blankline <|> anyBlockStart 115 where 116 -- Succeeds if there is a new block starting at this position. 117 anyBlockStart :: Monad m => OrgParser m () 118 anyBlockStart = try . choice $ 119 [ exampleLineStart 120 , hline 121 , metaLineStart 122 , commentLineStart 123 , gridTableStart 124 , void noteMarker 125 , void tableStart 126 , void drawerStart 127 , void headerStart 128 , void latexEnvStart 129 , void bulletListStart 130 , void orderedListStart 131 ] 132