3434# ' @param ... Character vectors of path components to be joined
3535# ' @param root Project root directory. If `NULL` (default), automatic detection
3636# ' is used following the hierarchy described above
37- # ' @return A character vector of the normalized file path relative to the project root
37+ # ' @return A character vector of the normalized file path relative to the project root.
3838# '
3939# ' @examples
4040# ' \dontrun{
41- # ' # Reference a data file from project root
42- # ' data_path <- quarto::project_path("data", "my_data.csv")
41+ # ' # Create a dummy Quarto project structure for example
42+ # ' tmpdir <- tempfile("quarto_project")
43+ # ' dir.create(tmpdir)
44+ # ' quarto::quarto_create_project('test project', type = 'blog', dir = tmpdir, no_prompt = TRUE, quiet = TRUE)
45+ # ' project_dir <- file.path(tmpdir, "test project")
46+ # '
47+ # ' # Simulate working within a blog post
48+ # ' xfun::in_dir(
49+ # ' dir = file.path(project_dir, "posts", "welcome"), {
50+ # '
51+ # ' # Reference a data file from project root
52+ # ' # ../../data/my_data.csv
53+ # ' quarto::project_path("data", "my_data.csv")
54+ # '
55+ # ' # Reference a script from project root
56+ # ' # ../../R/analysis.R
57+ # ' quarto::project_path("R", "analysis.R")
58+ # '
59+ # ' # Explicitly specify root (overrides automatic detection)
60+ # ' # ../../data/file.csv
61+ # ' quarto::project_path("data", "file.csv", root = "../..")
62+ # '
63+ # ' # Alternative approach using here::i_am() (potentially more robust)
64+ # ' # This approach requires you to declare where you are in the project:
65+ # ' if (requireNamespace("here", quietly = TRUE)) {
66+ # ' # Declare that this document is in the project root or subdirectory
67+ # ' here::i_am("posts/welcome/index.qmd")
68+ # '
69+ # ' # Now here::here() will work reliably from the project root
70+ # ' here::here("data", "my_data.csv")
71+ # ' here::here("R", "analysis.R")
72+ # ' }
73+ # ' })
4374# '
44- # ' # Reference a script
45- # ' script_path <- quarto::project_path("R", "analysis.R")
46- # '
47- # ' # Reference nested directories
48- # ' output_path <- quarto::project_path("outputs", "figures", "plot.png")
49- # '
50- # ' # Explicitly specify root (overrides automatic detection)
51- # ' custom_path <- quarto::project_path("data", "file.csv", root = "/path/to/project")
52- # '
53- # ' # Alternative approach using here::i_am() (potentially more robust)
54- # ' # This approach requires you to declare where you are in the project:
55- # ' if (requireNamespace("here", quietly = TRUE)) {
56- # ' # Declare that this document is in the project root or subdirectory
57- # ' here::i_am("analysis.qmd") # If in project root
58- # ' # here::i_am("reports/analysis.qmd") # If in subdirectory
59- # '
60- # ' # Now here::here() will work reliably from the project root
61- # ' data_path_alt <- here::here("data", "my_data.csv")
62- # ' script_path_alt <- here::here("R", "analysis.R")
63- # ' output_path_alt <- here::here("outputs", "figures", "plot.png")
64- # ' }
6575# ' }
6676# '
6777# ' @seealso
68- # ' * [here::here()] for a similar function that works with R projects
69- # ' * [is_running_quarto_project()] to check if quarto is running with a project context
78+ # ' * [here::here()] and [here::i_am()] for a similar function that works with R projects
79+ # ' * [find_project_root()] to search for Quarto Project configuration in parents directories
80+ # ' * [get_running_project_root()] for detecting the project root in Quarto commands
7081# ' * [xfun::from_root()] for the underlying path construction
7182# ' * [xfun::proj_root()] for project root detection logic
7283# '
7384# ' @export
7485project_path <- function (... , root = NULL ) {
7586 if (is.null(root )) {
7687 # Try Quarto project environment variables first
77- quarto_root <- Sys.getenv(
78- " QUARTO_PROJECT_ROOT" ,
79- Sys.getenv(" QUARTO_PROJECT_DIR" )
80- )
88+ quarto_root <- get_running_project_root()
8189
82- root <- if (nzchar(quarto_root )) {
90+ root <- if (! is.null( quarto_root ) && nzchar(quarto_root )) {
8391 quarto_root
8492 } else {
8593 # Try to find project root using xfun::proj_root() with extended rules
@@ -134,41 +142,44 @@ project_path <- function(..., root = NULL) {
134142 path
135143}
136144
137- # ' Check if running within a Quarto project context
145+ # ' Get the root of the currently running Quarto project
138146# '
139147# ' @description
140- # ' This function checks if the current R session is running within a Quarto
141- # ' project context by detecting Quarto project environment variables.
148+ # ' This function is to be used inside cells and will return the project root
149+ # ' when doing [quarto_render()] by detecting Quarto project environment variables.
142150# '
143151# ' @details
144152# ' Quarto sets `QUARTO_PROJECT_ROOT` and `QUARTO_PROJECT_DIR` environment
145153# ' variables when executing commands within a Quarto project context (e.g.,
146154# ' `quarto render`, `quarto preview`). This function detects their presence.
147155# '
148- # ' Note that this function will return `FALSE ` when running code interactively
156+ # ' Note that this function will return `NULL ` when running code interactively
149157# ' in an IDE (even within a Quarto project directory), as these specific
150158# ' environment variables are only set during Quarto command execution.
151159# '
152- # ' @return Logical indicating if Quarto project environment variables are set
160+ # ' @return Character Quarto project root path from set environment variables.
153161# '
154162# ' @seealso
155- # ' * [is_quarto_project ()] for checking Quarto project structure
163+ # ' * [find_project_root ()] for finding the Quarto project root directory
156164# ' * [project_path()] for constructing paths relative to the project root
157165# ' @examples
158166# ' \dontrun{
159167# ' # This will be TRUE during `quarto render` in a project
160- # ' is_running_quarto_project ()
168+ # ' get_running_project_root ()
161169# '
162170# ' # This will be FALSE when not running during `quarto_render` (e.g. interactively)
163- # ' is_running_quarto_project ()
171+ # ' get_running_project_root ()
164172# ' }
165173# ' @export
166- is_running_quarto_project <- function () {
167- nzchar(Sys.getenv(" QUARTO_PROJECT_ROOT" )) ||
168- nzchar(Sys.getenv(" QUARTO_PROJECT_DIR" ))
174+ get_running_project_root <- function () {
175+ root <- Sys.getenv(" QUARTO_PROJECT_ROOT" , Sys.getenv(" QUARTO_PROJECT_DIR" ))
176+ if (! nzchar(root )) {
177+ return ()
178+ }
179+ root
169180}
170181
171- # ' Check if working within a Quarto project structure
182+ # ' Find the root of a Quarto project
172183# '
173184# ' @description
174185# ' This function checks if the current working directory is within a Quarto
@@ -179,38 +190,29 @@ is_running_quarto_project <- function() {
179190# ' @param path Character. Path to check for Quarto project files. Defaults to
180191# ' current working directory.
181192# '
182- # ' @return Logical indicating if a Quarto project structure is detected
193+ # ' @return Character Path of the project root directory if found, or `NULL`
183194# '
184195# ' @examplesIf quarto_available()
185196# ' dir <- tempfile()
186197# ' dir.create(dir)
187- # ' is_quarto_project (dir)
198+ # ' find_project_root (dir)
188199# ' quarto_create_project(dir)
189- # ' is_quarto_project (dir)
200+ # ' find_project_root (dir)
190201# '
191202# ' xfun::in_dir(dir,
192203# ' # Check if current directory is in a Quarto project
193- # ' is_quarto_project( )
204+ # ' !is.null(find_project_root() )
194205# ' )
195206# ' # clean up
196207# ' unlink(dir, recursive = TRUE)
197208# '
198209# '
199210# ' @seealso [is_running_quarto_project()] for detecting active Quarto rendering
200211# ' @export
201- is_quarto_project <- function (path = " ." ) {
202- tryCatch(
203- {
204- quarto_rules <- rbind(
205- c(" _quarto.yml" , " " ),
206- c(" _quarto.yaml" , " " )
207- )
208-
209- proj_root <- xfun :: proj_root(path = path , rules = quarto_rules )
210- ! is.null(proj_root )
211- },
212- error = function (e ) {
213- FALSE
214- }
212+ find_project_root <- function (path = " ." ) {
213+ quarto_rules <- rbind(
214+ c(" _quarto.yml" , " " ),
215+ c(" _quarto.yaml" , " " )
215216 )
217+ xfun :: proj_root(path = path , rules = quarto_rules )
216218}
0 commit comments