How to pass File Path arguments relative to where a function is invoked, not defined?

Consider the following folder structure

|- lib.typ
|- content
|  |- main.typ
|  |- chapters
|  |  |- chapter_1.typ

This code executes as expected in main.typ

// main.typ

#let chapters = (
  "chapter_1",
)

#let print_chapters(chapters) = {
    for chapter in chapters {
    include "chapters/" + chapter + ".typ"
  }
}

#print_chapters(chapters)

But if I refactor into:

// lib.typ
#let print_chapters(chapters) = {
    for chapter in chapters {
    include "chapters/" + chapter + ".typ"
  }
}

// main.typ
#import "../lib.typ": *

#let chapters = (
  "chapter_1",
)

#print_chapters(chapters)

It fails as it tries to pick-up the path relative to lib.typ’s location.

Is it possible to define the function in lib.typ in such a way that main.typ has it available as it if it were defined in main.typ and so the filenames are relative to main.typ and not lib.typ.

This is a greatly simplified example, as in reality, lib.typ will be in a very different place to main.typ and it is inconvenient to have to specify the chapter file paths relative to lib.typ.

TLDR: can we define the function to execute relative to where it is invoked, rather than where it defined (or otherwise some workaround for the above that does not require giving the file path relative to lib.sty)

You can use absolute paths (starting with /) to reference files starting from the root of the project. Is that what you are looking for?

No I’m looking to be able to use relative paths, relative to main.typ (and not to lib.typ / the package)

Not possible if you only specify the file path. In this case, you could do as follows:

// lib.typ
#let print_chapters(chapters) = {
    for chapter in chapters {
       chapter
    }
    // or just 'chapters.join()'
}

// main.typ
#import "../lib.typ": *

#let chapters = (
  "chapter_1",
).map(chapter => include "chapters/" + chapter + ".typ")

#print_chapters(chapters)

By the way, you don’t have to use rust codeblocks, the forum supports ```typ … ``` for Typst code. In addition, I’ve renamed your post to a question. All of this info and more are in our guidelines, take a look: How to post in the Questions category

2 Likes