How to access files local to caller?

I have a function that I import from another file. I pass in a file path to the function, and the function should import that file. The problem is, the function imports the file relative to the definition of the function rather than the calling of the function. How can I import a file relative to the caller instead?

Eg.

// lib/functions.typ
#let func(path) = {
  #let cont = include path
  // do something with cont
}
// file1.typ
#import "lib/functions.typ": func
#func("file2.typ")
// want to include ./file2.typ
// instead includes ./lib/file2.typ

Unfortunately I can’t just rewrite the function to take in include path rather than path because that would cause cyclic imports.

1 Like

I found a hacky solution.

#let func(local-include, path) = {
  #let cont = local-include(path)
  // do something with cont
}
#import "lib/functions.typ": func
#func((path) => { include path }, "file2.typ")

Because local-include was defined in the caller file, anything included with it will be relative to that file.

Unfortunately, if a project has a nested directory structure, then either file paths need to be absolute from the file that defines this function, or a separate function needs to be defined and used at every level of nesting to allow for relative file paths.

There is an older post about this problem:

In there I showed a hacky workaround that may work for your situation: Why are paths always relative to the current file? - #5 by SillyFreak

Wow, that is really hacky and makes almost zero sense, LOL. There sure are some skeletons here… But this could make my public API stay the same when proper paths are added.