lib: superficial changes to comment parsers
This commit is contained in:
parent
188583e232
commit
67ed2d6cbf
@ -115,7 +115,6 @@ import Data.Text (Text)
|
|||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Data.Time.Calendar
|
import Data.Time.Calendar
|
||||||
import Data.Time.LocalTime
|
import Data.Time.LocalTime
|
||||||
import Safe
|
|
||||||
import System.Time (getClockTime)
|
import System.Time (getClockTime)
|
||||||
import Text.Megaparsec.Compat hiding (skipManyTill)
|
import Text.Megaparsec.Compat hiding (skipManyTill)
|
||||||
import Control.Applicative.Combinators (skipManyTill)
|
import Control.Applicative.Combinators (skipManyTill)
|
||||||
@ -819,6 +818,7 @@ multilinecommentp = startComment *> anyLine `skipManyTill` endComment
|
|||||||
where
|
where
|
||||||
startComment = string "comment" >> emptyLine
|
startComment = string "comment" >> emptyLine
|
||||||
endComment = eof <|> (string "end comment" >> emptyLine)
|
endComment = eof <|> (string "end comment" >> emptyLine)
|
||||||
|
|
||||||
emptyLine = void $ skipMany spacenonewline *> newline
|
emptyLine = void $ skipMany spacenonewline *> newline
|
||||||
anyLine = anyChar `manyTill` newline
|
anyLine = anyChar `manyTill` newline
|
||||||
|
|
||||||
@ -834,11 +834,13 @@ followingcommentp = T.unlines . map snd <$> followingcommentlinesp
|
|||||||
followingcommentlinesp :: TextParser m [(SourcePos, Text)]
|
followingcommentlinesp :: TextParser m [(SourcePos, Text)]
|
||||||
followingcommentlinesp = do
|
followingcommentlinesp = do
|
||||||
skipMany spacenonewline
|
skipMany spacenonewline
|
||||||
|
|
||||||
samelineComment@(_, samelineCommentText)
|
samelineComment@(_, samelineCommentText)
|
||||||
<- try commentp <|> (,) <$> (getPosition <* eolof) <*> pure ""
|
<- try commentp <|> (,) <$> (getPosition <* eolof) <*> pure ""
|
||||||
newlineComments <- many $ try $ do
|
newlineComments <- many $ try $ do
|
||||||
skipSome spacenonewline -- leading whitespace is required
|
skipSome spacenonewline -- leading whitespace is required
|
||||||
commentp
|
commentp
|
||||||
|
|
||||||
if T.null samelineCommentText && null newlineComments
|
if T.null samelineCommentText && null newlineComments
|
||||||
then pure []
|
then pure []
|
||||||
else pure $ samelineComment : newlineComments
|
else pure $ samelineComment : newlineComments
|
||||||
@ -863,7 +865,9 @@ followingcommentlinesp = do
|
|||||||
-- Right ("date:3/4=5/6\n",[("date","3/4=5/6")],Just 2000-03-04,Nothing)
|
-- Right ("date:3/4=5/6\n",[("date","3/4=5/6")],Just 2000-03-04,Nothing)
|
||||||
--
|
--
|
||||||
followingcommentandtagsp
|
followingcommentandtagsp
|
||||||
:: Monad m => Maybe Day -> ErroringJournalParser m (Text, [Tag], Maybe Day, Maybe Day)
|
:: Monad m
|
||||||
|
=> Maybe Day
|
||||||
|
-> ErroringJournalParser m (Text, [Tag], Maybe Day, Maybe Day)
|
||||||
followingcommentandtagsp mdefdate = do
|
followingcommentandtagsp mdefdate = do
|
||||||
-- pdbg 0 "followingcommentandtagsp"
|
-- pdbg 0 "followingcommentandtagsp"
|
||||||
|
|
||||||
@ -871,31 +875,31 @@ followingcommentandtagsp mdefdate = do
|
|||||||
-- pdbg 0 $ "commentws:" ++ show commentLines
|
-- pdbg 0 $ "commentws:" ++ show commentLines
|
||||||
|
|
||||||
-- Reparse the comment for any tags.
|
-- Reparse the comment for any tags.
|
||||||
tagsWithPositions <- case traverse (runTextParserAt tagswithvaluepositions) commentLines of
|
tagsWithPositions <- case
|
||||||
Right tss -> pure $ concat tss
|
traverse (runTextParserAt tagswithvaluepositions) commentLines of
|
||||||
Left e -> throwError $ parseErrorPretty e
|
Right tss -> pure $ concat tss
|
||||||
|
Left e -> throwError $ parseErrorPretty e
|
||||||
|
|
||||||
-- Extract date-tag style posting dates from the tags.
|
-- Extract date-tag style posting dates from the tags.
|
||||||
-- Use the transaction date for defaults, if provided.
|
-- Use the transaction date for defaults, if provided.
|
||||||
let eTagDates = traverse tagDate
|
let isDateLabel txt = txt == "date" || txt == "date2"
|
||||||
$ filter (isDateLabel . fst . snd) tagsWithPositions
|
isDateTag = isDateLabel . fst . snd
|
||||||
where isDateLabel txt = txt == "date" || txt == "date2"
|
tagDates <- case traverse tagDate $ filter isDateTag tagsWithPositions of
|
||||||
tagDates <- case eTagDates of
|
Right ds -> pure ds
|
||||||
Right ds -> pure ds
|
Left e -> throwError $ parseErrorPretty e
|
||||||
Left e -> throwError e
|
|
||||||
|
|
||||||
-- Reparse the comment for any bracketed style posting dates.
|
-- Reparse the comment for any bracketed style posting dates.
|
||||||
-- Use the transaction date for defaults, if provided.
|
-- Use the transaction date for defaults, if provided.
|
||||||
let eBracketedDates =
|
bracketedDates <- case
|
||||||
traverse (runTextParserAt (bracketedpostingdatesp mdefdate)) commentLines
|
traverse (runTextParserAt (bracketedpostingdatesp mdefdate))
|
||||||
bracketedDates <- case eBracketedDates of
|
commentLines of
|
||||||
Right dss -> pure $ concat dss
|
Right dss -> pure $ concat dss
|
||||||
Left e -> throwError $ parseErrorPretty e
|
Left e -> throwError $ parseErrorPretty e
|
||||||
|
|
||||||
let pdates = tagDates ++ bracketedDates
|
let pdates = tagDates ++ bracketedDates
|
||||||
|
mdate = fmap snd $ find ((=="date") .fst) pdates
|
||||||
|
mdate2 = fmap snd $ find ((=="date2").fst) pdates
|
||||||
-- pdbg 0 $ "allDates: "++show pdates
|
-- pdbg 0 $ "allDates: "++show pdates
|
||||||
let mdate = headMay $ map snd $ filter ((=="date") .fst) pdates
|
|
||||||
mdate2 = headMay $ map snd $ filter ((=="date2").fst) pdates
|
|
||||||
|
|
||||||
let strippedComment = T.unlines $ map (T.strip . snd) commentLines
|
let strippedComment = T.unlines $ map (T.strip . snd) commentLines
|
||||||
tags = map snd tagsWithPositions
|
tags = map snd tagsWithPositions
|
||||||
@ -907,30 +911,30 @@ followingcommentandtagsp mdefdate = do
|
|||||||
runTextParserAt parser (pos, txt) =
|
runTextParserAt parser (pos, txt) =
|
||||||
runTextParser (setPosition pos *> parser) txt
|
runTextParser (setPosition pos *> parser) txt
|
||||||
|
|
||||||
tagDate :: (SourcePos, Tag) -> Either String (TagName, Day)
|
tagDate :: (SourcePos, Tag)
|
||||||
|
-> Either (ParseError Char MPErr) (TagName, Day)
|
||||||
tagDate (pos, (name, value)) =
|
tagDate (pos, (name, value)) =
|
||||||
case runTextParserAt (datep' myear) (pos, value) of
|
fmap (name,) $ runTextParserAt (datep' myear) (pos, value)
|
||||||
Left e -> Left $ parseErrorPretty e
|
|
||||||
Right day -> Right (name, day)
|
|
||||||
where myear = fmap (first3 . toGregorian) mdefdate
|
where myear = fmap (first3 . toGregorian) mdefdate
|
||||||
|
|
||||||
-- A transaction/posting comment must start with a semicolon.
|
-- A transaction/posting comment must start with a semicolon. This parser
|
||||||
-- This parser discards the leading whitespace of the comment
|
-- discards the leading whitespace of the comment and returns the source
|
||||||
-- and returns the source position of the comment's first non-whitespace character.
|
-- position of the comment's first non-whitespace character.
|
||||||
commentp :: TextParser m (SourcePos, Text)
|
commentp :: TextParser m (SourcePos, Text)
|
||||||
commentp = commentStartingWithp ";"
|
commentp = commentStartingWithp (==';')
|
||||||
|
|
||||||
-- A line (file-level) comment can start with a semicolon, hash,
|
-- A line (file-level) comment can start with a semicolon, hash, or star
|
||||||
-- or star (allowing org nodes).
|
-- (allowing org nodes). This parser discards the leading whitespace of
|
||||||
-- This parser discards the leading whitespace of the comment
|
-- the comment and returns the source position of the comment's first
|
||||||
-- and returns the source position of the comment's first non-whitespace character.
|
-- non-whitespace character.
|
||||||
linecommentp :: TextParser m (SourcePos, Text)
|
linecommentp :: TextParser m (SourcePos, Text)
|
||||||
linecommentp = commentStartingWithp ";#*"
|
linecommentp =
|
||||||
|
commentStartingWithp $ \c -> c == ';' || c == '#' || c == '*'
|
||||||
|
|
||||||
commentStartingWithp :: [Char] -> TextParser m (SourcePos, Text)
|
commentStartingWithp :: (Char -> Bool) -> TextParser m (SourcePos, Text)
|
||||||
commentStartingWithp cs = do
|
commentStartingWithp f = do
|
||||||
-- ptrace "commentStartingWith"
|
-- ptrace "commentStartingWith"
|
||||||
oneOf cs
|
satisfy f
|
||||||
skipMany spacenonewline
|
skipMany spacenonewline
|
||||||
startPos <- getPosition
|
startPos <- getPosition
|
||||||
content <- T.pack <$> anyChar `manyTill` eolof
|
content <- T.pack <$> anyChar `manyTill` eolof
|
||||||
@ -956,10 +960,7 @@ commentStartingWithp cs = do
|
|||||||
-- []
|
-- []
|
||||||
--
|
--
|
||||||
commentTags :: Text -> [Tag]
|
commentTags :: Text -> [Tag]
|
||||||
commentTags s =
|
commentTags s = either (const []) id $ runTextParser tagsp s
|
||||||
case runTextParser tagsp s of
|
|
||||||
Right r -> r
|
|
||||||
Left _ -> [] -- shouldn't happen
|
|
||||||
|
|
||||||
-- | Parse all tags found in a string.
|
-- | Parse all tags found in a string.
|
||||||
tagsp :: SimpleTextParser [Tag]
|
tagsp :: SimpleTextParser [Tag]
|
||||||
@ -1000,8 +1001,10 @@ tagswithvaluepositions = do
|
|||||||
then tagswithvaluepositions
|
then tagswithvaluepositions
|
||||||
else do
|
else do
|
||||||
pos <- getPosition
|
pos <- getPosition
|
||||||
(:) <$> fmap (\val -> (pos, (tagName, val))) tagValue
|
tagVal <- tagValue
|
||||||
<*> tagswithvaluepositions
|
let tag = (pos, (tagName, tagVal))
|
||||||
|
tags <- tagswithvaluepositions
|
||||||
|
pure $ tag : tags
|
||||||
|
|
||||||
atEof :: SimpleTextParser [(SourcePos, Tag)]
|
atEof :: SimpleTextParser [(SourcePos, Tag)]
|
||||||
atEof = eof *> pure []
|
atEof = eof *> pure []
|
||||||
@ -1023,10 +1026,6 @@ bracketedpostingdatesp mdefdate = do
|
|||||||
|
|
||||||
--- ** bracketed dates
|
--- ** bracketed dates
|
||||||
|
|
||||||
-- tagorbracketeddatetagsp :: Monad m => Maybe Day -> TextParser u m [Tag]
|
|
||||||
-- tagorbracketeddatetagsp mdefdate =
|
|
||||||
-- bracketeddatetagsp mdefdate <|> ((:[]) <$> tagp)
|
|
||||||
|
|
||||||
-- | Parse Ledger-style bracketed posting dates ([DATE=DATE2]), as
|
-- | Parse Ledger-style bracketed posting dates ([DATE=DATE2]), as
|
||||||
-- "date" and/or "date2" tags. Anything that looks like an attempt at
|
-- "date" and/or "date2" tags. Anything that looks like an attempt at
|
||||||
-- this (a square-bracketed sequence of 0123456789/-.= containing at
|
-- this (a square-bracketed sequence of 0123456789/-.= containing at
|
||||||
@ -1057,16 +1056,20 @@ bracketeddatetagsp :: Maybe Day -> SimpleTextParser [(TagName, Day)]
|
|||||||
bracketeddatetagsp mdefdate = do
|
bracketeddatetagsp mdefdate = do
|
||||||
-- pdbg 0 "bracketeddatetagsp"
|
-- pdbg 0 "bracketeddatetagsp"
|
||||||
try $ do
|
try $ do
|
||||||
let digits = "0123456789"
|
s <- lookAhead
|
||||||
s <- lookAhead $ between (char '[') (char ']')
|
$ between (char '[') (char ']')
|
||||||
(some (oneOf $ '=':digits++datesepchars))
|
$ some $ digitChar <|> datesepchar <|> char '='
|
||||||
unless (any (`elem` s) digits && any (`elem` datesepchars) s) $
|
unless (any isDigit s && any (`elem` datesepchars) s) $
|
||||||
fail "not a bracketed date"
|
fail "not a bracketed date"
|
||||||
|
|
||||||
-- Looks sufficiently like a bracketed date to commit to parsing a date
|
-- Looks sufficiently like a bracketed date to commit to parsing a date
|
||||||
|
|
||||||
between (char '[') (char ']') $ do
|
between (char '[') (char ']') $ do
|
||||||
let myear1 = fmap (first3 . toGregorian) mdefdate
|
let myear1 = fmap readYear mdefdate
|
||||||
md1 <- optional $ datep' myear1
|
md1 <- optional $ datep' myear1
|
||||||
let myear2 = fmap (first3 . toGregorian) md1 <|> myear1
|
|
||||||
|
let myear2 = fmap readYear md1 <|> myear1
|
||||||
md2 <- optional $ char '=' *> (datep' myear2)
|
md2 <- optional $ char '=' *> (datep' myear2)
|
||||||
|
|
||||||
pure $ catMaybes [("date",) <$> md1, ("date2",) <$> md2]
|
pure $ catMaybes [("date",) <$> md1, ("date2",) <$> md2]
|
||||||
|
|
||||||
|
where readYear = first3 . toGregorian
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user