journal: the include directive now accepts a file format prefix
This works with glob patterns too, applying the prefix to each path. This can be useful when included files don't have the standard file extension, eg: include timedot:2020*.md
This commit is contained in:
parent
9bc8c5d668
commit
00e9e844ac
@ -240,19 +240,23 @@ directivep = (do
|
|||||||
]
|
]
|
||||||
) <?> "directive"
|
) <?> "directive"
|
||||||
|
|
||||||
|
-- | Parse an include directive. include's argument is an optionally
|
||||||
|
-- file-format-prefixed file path or glob pattern. In the latter case,
|
||||||
|
-- the prefix is applied to each matched path. Examples:
|
||||||
|
-- foo.j, foo/bar.j, timedot:foo/2020*.md
|
||||||
includedirectivep :: MonadIO m => ErroringJournalParser m ()
|
includedirectivep :: MonadIO m => ErroringJournalParser m ()
|
||||||
includedirectivep = do
|
includedirectivep = do
|
||||||
string "include"
|
string "include"
|
||||||
lift (skipSome spacenonewline)
|
lift (skipSome spacenonewline)
|
||||||
filename <- T.unpack <$> takeWhileP Nothing (/= '\n') -- don't consume newline yet
|
prefixedglob <- T.unpack <$> takeWhileP Nothing (/= '\n') -- don't consume newline yet
|
||||||
|
|
||||||
parentoff <- getOffset
|
parentoff <- getOffset
|
||||||
parentpos <- getSourcePos
|
parentpos <- getSourcePos
|
||||||
|
let (mprefix,glob) = splitReaderPrefix prefixedglob
|
||||||
filepaths <- getFilePaths parentoff parentpos filename
|
paths <- getFilePaths parentoff parentpos glob
|
||||||
|
let prefixedpaths = case mprefix of
|
||||||
forM_ filepaths $ parseChild parentpos
|
Nothing -> paths
|
||||||
|
Just fmt -> map ((fmt++":")++) paths
|
||||||
|
forM_ prefixedpaths $ parseChild parentpos
|
||||||
void newline
|
void newline
|
||||||
|
|
||||||
where
|
where
|
||||||
@ -275,10 +279,11 @@ includedirectivep = do
|
|||||||
else customFailure $ parseErrorAt parseroff $
|
else customFailure $ parseErrorAt parseroff $
|
||||||
"No existing files match pattern: " ++ filename
|
"No existing files match pattern: " ++ filename
|
||||||
|
|
||||||
parseChild :: MonadIO m => SourcePos -> FilePath -> ErroringJournalParser m ()
|
parseChild :: MonadIO m => SourcePos -> PrefixedFilePath -> ErroringJournalParser m ()
|
||||||
parseChild parentpos filepath = do
|
parseChild parentpos prefixedpath = do
|
||||||
parentj <- get
|
let (_mprefix,filepath) = splitReaderPrefix prefixedpath
|
||||||
|
|
||||||
|
parentj <- get
|
||||||
let parentfilestack = jincludefilestack parentj
|
let parentfilestack = jincludefilestack parentj
|
||||||
when (filepath `elem` parentfilestack) $
|
when (filepath `elem` parentfilestack) $
|
||||||
Fail.fail ("Cyclic include: " ++ filepath)
|
Fail.fail ("Cyclic include: " ++ filepath)
|
||||||
@ -289,7 +294,7 @@ includedirectivep = do
|
|||||||
|
|
||||||
-- Choose a reader/format based on the file path, or fall back
|
-- Choose a reader/format based on the file path, or fall back
|
||||||
-- on journal. Duplicating readJournal a bit here.
|
-- on journal. Duplicating readJournal a bit here.
|
||||||
let r = fromMaybe reader $ findReader Nothing (Just filepath)
|
let r = fromMaybe reader $ findReader Nothing (Just prefixedpath)
|
||||||
parser = rParser r
|
parser = rParser r
|
||||||
dbg1IO "trying reader" (rFormat r)
|
dbg1IO "trying reader" (rFormat r)
|
||||||
updatedChildj <- journalAddFile (filepath, childInput) <$>
|
updatedChildj <- journalAddFile (filepath, childInput) <$>
|
||||||
|
|||||||
@ -878,16 +878,20 @@ See also [comments](#comments).
|
|||||||
You can pull in the content of additional files by writing an include directive, like this:
|
You can pull in the content of additional files by writing an include directive, like this:
|
||||||
|
|
||||||
```journal
|
```journal
|
||||||
include path/to/file.journal
|
include FILEPATH
|
||||||
```
|
```
|
||||||
|
|
||||||
If the path does not begin with a slash, it is relative to the current file.
|
Only journal files can include, and only journal, timeclock or timedot files can be included (not CSV files, currently).
|
||||||
The include file path may contain
|
|
||||||
[common glob patterns](https://hackage.haskell.org/package/Glob-0.9.2/docs/System-FilePath-Glob.html#v:compile)
|
|
||||||
(e.g. `*`).
|
|
||||||
|
|
||||||
The `include` directive can only be used in journal files.
|
If the file path does not begin with a slash, it is relative to the current file's folder.
|
||||||
It can include journal, timeclock or timedot files, but not CSV files.
|
|
||||||
|
It may contain [glob patterns] to match multiple files, eg: `include *.journal`.
|
||||||
|
|
||||||
|
Or a tilde, meaning home directory: `include ~/main.journal`.
|
||||||
|
|
||||||
|
It may also be prefixed to force a specific file format, overriding the file extension (as described in [hledger.1 -> Input files](hledger.html#input-files)): `include timedot:~/notes/2020*.md`.
|
||||||
|
|
||||||
|
[glob patterns]: https://hackage.haskell.org/package/Glob-0.9.2/docs/System-FilePath-Glob.html#v:compile
|
||||||
|
|
||||||
### Default year
|
### Default year
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user