From 3ddc9d74320d09492cf7fd117ac8858b6f4f01f8 Mon Sep 17 00:00:00 2001 From: Simon Michael Date: Wed, 16 Nov 2016 13:25:33 -0800 Subject: [PATCH] lib: clarify file format detectors --- hledger-lib/Hledger/Read/CsvReader.hs | 10 ++++++---- hledger-lib/Hledger/Read/JournalReader.hs | 14 +++++++++----- hledger-lib/Hledger/Read/LedgerReader.hs | 11 ++++++----- hledger-lib/Hledger/Read/TimeclockReader.hs | 10 ++++++---- hledger-lib/Hledger/Read/TimedotReader.hs | 10 ++++++---- 5 files changed, 33 insertions(+), 22 deletions(-) diff --git a/hledger-lib/Hledger/Read/CsvReader.hs b/hledger-lib/Hledger/Read/CsvReader.hs index fe1165fdd..209df6ccb 100644 --- a/hledger-lib/Hledger/Read/CsvReader.hs +++ b/hledger-lib/Hledger/Read/CsvReader.hs @@ -69,11 +69,13 @@ reader = Reader format detect parse format :: String format = "csv" --- | Does the given file path and data look like it might be CSV ? +-- | Does the given file path and data look like something this reader can handle ? detect :: FilePath -> Text -> Bool -detect f t - | f /= "-" = takeExtension f == '.':format -- from a file: yes if the extension is .csv - | otherwise = T.length (T.filter (==',') t) >= 2 -- from stdin: yes if there are two or more commas +detect f excerpt + -- file name known: try this reader if it has any of these extensions + | f /= "-" = takeExtension f `elem` ['.':format] + -- file name unknown: try this reader if excerpt contains two or more commas + | otherwise = T.length (T.filter (==',') excerpt) >= 2 -- | Parse and post-process a "Journal" from CSV data, or give an error. -- XXX currently ignores the string and reads from the file path diff --git a/hledger-lib/Hledger/Read/JournalReader.hs b/hledger-lib/Hledger/Read/JournalReader.hs index 422edc40b..4733ee28a 100644 --- a/hledger-lib/Hledger/Read/JournalReader.hs +++ b/hledger-lib/Hledger/Read/JournalReader.hs @@ -111,12 +111,16 @@ reader = Reader format detect parse format :: String format = "journal" --- | Does the given file path and data look like it might be hledger's journal format ? +-- | Does the given file path and data look like something this reader can handle ? detect :: FilePath -> Text -> Bool -detect f _t - | f /= "-" = takeExtension f `elem` ['.':format, ".j", ".hledger"] -- from a known file name: yes if the extension is .hledger or .journal or .j - | otherwise = True -- from stdin: yes, always attempt to parse stdin as hledger journal data - -- otherwise = regexMatches "(^|\n)[0-9]+.*\n[ \t]+" $ T.unpack t -- from stdin: yes if we can see something that looks like a journal entry (digits in column 0 with the next line indented) +detect f _ + -- file name known: try this reader if it has any of these extensions + | f /= "-" = takeExtension f `elem` ['.':format, ".j", ".hledger", ".ledger", ".l"] + -- file name unknown: always try this reader + | otherwise = True + -- file name unknown: try this reader if we can see something like a journal entry + -- (digits in column 0 with the next line indented) + -- otherwise = regexMatches "(^|\n)[0-9]+.*\n[ \t]+" $ T.unpack excerpt -- | Parse and post-process a "Journal" from hledger's journal file -- format, or give an error. diff --git a/hledger-lib/Hledger/Read/LedgerReader.hs b/hledger-lib/Hledger/Read/LedgerReader.hs index 0560f73f9..6df15cf47 100644 --- a/hledger-lib/Hledger/Read/LedgerReader.hs +++ b/hledger-lib/Hledger/Read/LedgerReader.hs @@ -56,12 +56,13 @@ reader = Reader format detect parse format :: String format = "ledger" --- | Does the given file path and data look like it might be ledger's journal format ? +-- | Does the given file path and data look like something this reader can handle ? detect :: FilePath -> Text -> Bool -detect f _t - | f /= "-" = takeExtension f `elem` ['.':format, ".l"] -- from a known file name: yes if the extension is .ledger or .l - | otherwise = False -- from stdin: yes, always attempt to parse stdin as a ledger journal - -- otherwise = regexMatches "(^|\n)[0-9]+.*\n[ \t]+" $ T.unpack t -- from stdin: yes if we can see something that looks like a journal entry (digits in column 0 with the next line indented) +detect f _ + -- file name known: try this reader if it has any of these extensions + | f /= "-" = takeExtension f `elem` ['.':format, ".l"] + -- file name unknown: don't try this reader + | otherwise = False -- | Parse and post-process a "Journal" from ledger's journal format, or give an error. parse :: Maybe FilePath -> Bool -> FilePath -> Text -> ExceptT String IO Journal diff --git a/hledger-lib/Hledger/Read/TimeclockReader.hs b/hledger-lib/Hledger/Read/TimeclockReader.hs index 9ec7701f7..3503decd7 100644 --- a/hledger-lib/Hledger/Read/TimeclockReader.hs +++ b/hledger-lib/Hledger/Read/TimeclockReader.hs @@ -75,11 +75,13 @@ reader = Reader format detect parse format :: String format = "timeclock" --- | Does the given file path and data look like it might be timeclock.el's timeclock format ? +-- | Does the given file path and data look like something this reader can handle ? detect :: FilePath -> Text -> Bool -detect f t - | f /= "-" = takeExtension f == '.':format -- from a known file name: yes if the extension is this format's name - | otherwise = regexMatches "(^|\n)[io] " $ T.unpack t -- from stdin: yes if any line starts with "i " or "o " +detect f excerpt + -- file name known: try this reader if it has any of these extensions + | f /= "-" = takeExtension f `elem` ['.':format] + -- file name unknown: try this reader if a line starts with "i " or "o " in excerpt + | otherwise = regexMatches "(^|\n)[io] " $ T.unpack excerpt -- | Parse and post-process a "Journal" from timeclock.el's timeclock -- format, saving the provided file path and the current time, or give an diff --git a/hledger-lib/Hledger/Read/TimedotReader.hs b/hledger-lib/Hledger/Read/TimedotReader.hs index eb49312ce..de31e9a1d 100644 --- a/hledger-lib/Hledger/Read/TimedotReader.hs +++ b/hledger-lib/Hledger/Read/TimedotReader.hs @@ -61,11 +61,13 @@ reader = Reader format detect parse format :: String format = "timedot" --- | Does the given file path and data look like it might contain this format ? +-- | Does the given file path and data look like something this reader can handle ? detect :: FilePath -> Text -> Bool -detect f t - | f /= "-" = takeExtension f == '.':format -- from a file: yes if the extension matches the format name - | otherwise = regexMatches "(^|\n)[0-9]" $ T.unpack t -- from stdin: yes if we can see a possible timedot day entry (digits in column 0) +detect f excerpt + -- file name known: try this reader if it has any of these extensions + | f /= "-" = takeExtension f `elem` ['.':format] + -- file name unknown: try this reader if a line starts with a number in excerpt + | otherwise = regexMatches "(^|\n)[0-9]" $ T.unpack excerpt -- | Parse and post-process a "Journal" from the timedot format, or give an error. parse :: Maybe FilePath -> Bool -> FilePath -> Text -> ExceptT String IO Journal