Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't specify output directory with quarto_render() #81

Open
lawalter opened this issue Dec 28, 2022 · 11 comments
Open

Can't specify output directory with quarto_render() #81

lawalter opened this issue Dec 28, 2022 · 11 comments
Labels
enhancement New feature or request upstream concerns an upstream library like quarto or pandoc
Milestone

Comments

@lawalter
Copy link

There is no parameter for quarto_render() that allows the user to set a desired output directory when rendering a .qmd document.

In rmarkdown::render() this functionality is seen with the output_dir parameter.

The use case I have for setting an output directory, other than it being generally useful, is rendering a .qmd template from an R package. Currently, quarto_render() attempts to write the output document to the location of the template in the R package directory. This therefore limits the utility of quarto templates in R packages. I would like to see quarto_render() to work as rmarkdown::render() does, which allows users to set an output directory for the destination of a rendered template.

@cderv
Copy link
Collaborator

cderv commented Jan 9, 2023

Quarto is a CLI tool and quarto_render() is a wrapper on quarto render call. This means that all options supported by the R packages would be ones supported by quarto itself.

For project Quarto has a output-dir option (e.g for books: https://quarto.org/docs/books/book-output.html#output-path) which allows to pass a folder relative to project directory. This argument is missing in R function even if exist in the CLI. We could add it.

However, it seems here you are in another use case.

The use case I have for setting an output directory, other than it being generally useful, is rendering a .qmd template from an R package

How are you rendering the template qmd ? Usually with templates, they should be moved to a project location. This is how it works with R Markdown templates (using the rmarkdown::draft() function).
How are you storing and distributing the template in your R Package ? Are you leveraging rmarkdown::draft() or another copy to setup function ?

Moving template file and resources before rendering is important because rendering could need to write some files at the source location. Having an output directory to move results may not be enough.

Is the pattern :

  • Retrieving template and resources to local user project then rendering something that you tried ?
  • Or are you more in a situation with a template as parametrized report that users is not supposed to modify ?
    In the latter case, usual pattern in R package is to have a specific render function that will wrap the moving part needed.

Let's discuss this further.

Hope it helps.

@lawalter
Copy link
Author

lawalter commented Jan 9, 2023

Hi @cderv,

I'm in the second situation, in terms of the template is a parameterized report.

I render the .Rmd template from the inst directory within the R package. A function in the R package leverages rmarkdown::render() by calling the .Rmd template using system.file("templates", "template.Rmd", package = "Rpackagename") and taking specified params for data directories, an output directory, and an output file name. Users can therefore set any local path and any desired file name and rmarkdown::render uses them via its output_dir and output_file params.

When I tried this using quarto::quarto_render(), I realized there were no similar output options and the template was attempted to be written to the R package directory itself.

@cderv
Copy link
Collaborator

cderv commented Jan 9, 2023

Thanks for the precision. I know the situation. This is my personal view on this

I would not try to call render on the file within the package. You will consider folder system.file("templates", "template.Rmd", package = "Rpackagename") as being writeable for work need. But really it means that anytime the user is rendering, some content could be written inside the package installation folder. output_dir and output_file, does not mean that rendering will happen elsewhere. It is possible the intermediates file and other are written to the installation folder.

I would say this is not good practice, all the more because in some situation, a package installation folder is not writeable and will be read -only.

For this type of need, I would use the following pattern.

  • As a developer, organize things in the package that that it is easy to copy source. A folder copy-able using draft() is helpful
  • In you wrapper render function, copy your source folder in a temporary directory
  • Do you rendering there
  • Move your outputs in the specified user location.

This will be safer for your rendering, and it is good practice for a package to only write in specific place (temporary directory or user's data directory for things that should stay).

With that in mind, you may understand better the Quarto approach.

  • Quarto itself won't allow you to render a file somewhere to a completely different place. It will let the user do the copying / moving itself before and after rendering.
  • only the output directory of project can be customize relatively to the source project (_quarto.yml folder) so that output name or place can be customized (from _book to output/_book for example).
  • Quarto offers a script execution to have some workflow happens before and after rendering, or easily run step in a broader process (makefile or something else).
  • Quarto offers

Managing outputs for users was very tricky and prone to error. Between the inputs, the resources, the intermediary outputs, the different formats and all. We had a hard time in rmarkdown and it is buggy in some place. (lots of opened issues https://github.com/rstudio/rmarkdown/issues?q=label%3A%22theme%3A+paths%22+is%3Aopen+sort%3Aupdated-desc)

So for now, Quarto does things minimal on this. It may evolve in the future, but I believe the good practice will stay.

Hope it helps understand.

Would you be willing to try one of the approach above ?

@lawalter
Copy link
Author

lawalter commented Jan 9, 2023

But really it means that anytime the user is rendering, some content could be written inside the package installation folder. output_dir and output_file, does not mean that rendering will happen elsewhere. It is possible the intermediates file and other are written to the installation folder.

Since parameters supplied to rmarkdown::render() params output_dir and output_file are required by the R function, it is impossible that the .Rmd would ever be written to the R directory when using the workflow I have created (with the template inside the R package).

I am aware of workarounds, such as bypassing quarto::quarto_render() entirely by copying the template to a local directory (e.g. Spencer Schien's blog post) and then rendering, but this is an exhausting workaround compared to rmarkdown::render(). I will list several reasons:

  1. I create periodic parameterized reports and write them to a shared drive for coworkers to read. Using a template that is stored within the R package is simple and easy. I do not want to copy a template to a local drive or keep a template in a shared directory.
  2. Any time I create a .qmd document, not just through an R package template, I have no way to write the rendered output to a desired directory. Working code and rendered documents are often stored separately in organized, professional environments. It wastes time and energy to have to complete a separate step to copy and/or cut and paste the rendered .html or .pdf Quarto document every single time one is created.
  3. Quarto has been heralded as the Rmarkdown replacement, but without the ability to render a .qmd to a desired location, I see quarto::quarto_render() as substantially inferior to .Rmd and rmarkdown::render().

@lawalter lawalter closed this as completed Jan 9, 2023
@lawalter lawalter reopened this Jan 9, 2023
@cderv
Copy link
Collaborator

cderv commented Jan 9, 2023

Since parameters supplied to rmarkdown::render() params output_dir and output_file are required by the R function, it is impossible that the .Rmd would ever be written to the R directory when using the workflow I have created (with the template inside the R package).

I was thinking of intermediates file mainly. I recall that in some case the output_dir had effect only at the end for the results, and that during the rendering the intermediates files and resources could be written locally to the Rmd file during knitting and pandoc conversion before being moved in the output destination. Paths are really tricky to handle and base expectation is that everything happens at Rmd level at first. Those options are here to tweak that but I think I have seen report of leftover during the processing. Usually clean up - but anyhow, that is my warning. Maybe with your formats it works ok (it could have been for PDF only - I need to look in opened issues).

  1. I create periodic parameterized reports and write them to a shared drive for coworkers to read. Using a template that is stored within the R package is simple and easy. I do not want to copy a template to a local drive or keep a template in a shared directory.

I don't recommend too. I am advising to copy resources from your package to a temp directory for the rendering process and then move stuff to end destination, before cleaning stuff. That is the process recommended in Shiny apps for example (https://shiny.rstudio.com/articles/generating-reports.html)

  1. Any time I create a .qmd document, not just through an R package template, I have no way to write the rendered output to a desired directory. Working code and rendered documents are often stored separately in organized, professional environments.

Here you are referring to using quarto render directly and not with the R package ?
In quarto the extension mechanism is what allows to share formats and templates between project and users. https://quarto.org/docs/extensions/
R package only works for R users regarding distribution and are limite to template file where Extensions offers much more customisation.

Regarding output directory for a rendering, you should add to this discussion and follow quarto-dev/quarto-cli#2171

It wastes time and energy to have to complete a separate step to copy and/or cut and paste the rendered .html or .pdf Quarto document every single time one is created.

Sorry I may have misunderstood then. I though you were offering a function in package as wrapper of quarto_render() that would do those step for users. Like myorg::custom_render(...) that your user would call.

  1. Quarto has been heralded as the Rmarkdown replacement,

Quarto is an evolution of R Markdown for next generation scientific publishing. It does not replace R Markdown in the way that R Markdown is not going away, and Quarto even use part of R Markdown internally. Quarto extends R Markdown ecosystem that R users benefits since some years to other scientific communities by starting fresh with the experience and new vision.

but without the ability to render a .qmd to a desired location, I see quarto::quarto_render() as substantially inferior to .Rmd and rmarkdown::render().

Something I may have missed and misunderstood: Do you manage to do what you want with Quarto CLI calling quarto render in terminal and something is missing in quarto R 📦

Quarto works with the notion of projects which brings many new features and possibility, and offer the mechanism of extensions to offer shared content.

Maybe the current design of Quarto does not yet answer to your past workflow, or maybe this workflow needs adaptation. Anyway, I don't think this is a direct issue of the R package Quarto which this issue thread is about. You should contribute to linked discussion or open a new one to share your feedback. I'll do internally.

I was trying to help find a good workflow to work with quarto and templates. I am happy to keep sharing and help on that if you think that is useful to you.

Anyway, thanks a lot for the discussion by the way. That is very enlightening. I wonder what we could do at the R package level. But we want to keep it as close to Quarto itself.

@lawalter
Copy link
Author

lawalter commented Jan 9, 2023

I was thinking of intermediates file mainly. I recall that in some case the output_dir had effect only at the end for the results, and that during the rendering the intermediates files and resources could be written locally to the Rmd file during knitting and pandoc conversion before being moved in the output destination.

While rendering with rmarkdown, the intermediates file appears at the output_dir.

Anyway, I don't think this is a direct issue of the R package Quarto which this issue thread is about. You should contribute to linked discussion or open a new one to share your feedback. I'll do internally.

I view this as a quarto R package issue. I typically render .qmd documents outside of a project structure. Maybe Quarto documents were not intended to be rendered that way. However, it seems strange that the output directory cannot be specified with quarto_render(). I like to pass along R code to others for full reproducibility, using quarto render on the command line limits that. I prefer the rmarkdown::render() structure that can pinpoint, specifically, where a document is rendered to. The constraint of only rendering a .qmd in the same directory creates several limitations which were noted by others in the discussion you linked, namely this one: quarto-dev/quarto-cli#2171 (comment).

Thanks for the discussion as well, I do look forward to seeing Quarto and the R package quarto evolve over time.

@cderv
Copy link
Collaborator

cderv commented Jan 9, 2023

I view this as a quarto R package issue. I typically render .qmd documents outside of a project structure

Oh that is interesting. So this is really something in the usage context of R template within package... 🤔

However, it seems strange that the output directory cannot be specified with quarto_render()

We are currently only passing argument to quarto render and the function is a wrapper. We don't do any logic on the rendering. So doing this in the R package only without making quarto render works differently seems a bit more than a wrapper to CLI tool.

There is a quarto inspect endpoint, exposed as quarto_inspect() that gives all the infos to help integrating quarto in other workflows (package targets uses that for example). There should be information on resources and output in there.

Anyway, the upstream issue is about all this, so this will evolves in time.

Thank you again.

@cderv cderv added upstream concerns an upstream library like quarto or pandoc enhancement New feature or request labels Jan 10, 2023
lawalter referenced this issue in USFWS/migbirdHIP Jul 20, 2023
quarto::quarto_render() will not render a .qmd document to .html anywhere but the original directory; as a workaround, since this is a known issue and we cannot render an .html inside this R package, the function copies the .qmd template to the desired outpur dir, renders it, and then deletes the template; params updated for clarity
@salim-b

This comment was marked as outdated.

@lawalter

This comment was marked as outdated.

@salim-b

This comment was marked as outdated.

@EkShunyam
Copy link

Here to say - i loved quarto - its crisp and simple
plus i love how engaged you are with the community, explaining with such long and helpful answers

thank you :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request upstream concerns an upstream library like quarto or pandoc
Projects
None yet
Development

No branches or pull requests

4 participants