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

Which document is being knit? #950

Closed
klmr opened this issue Feb 2, 2015 · 7 comments
Closed

Which document is being knit? #950

klmr opened this issue Feb 2, 2015 · 7 comments
Labels
feature Feature requests
Milestone

Comments

@klmr
Copy link
Contributor

klmr commented Feb 2, 2015

This is related to #564: My code needs to find out whether it’s being called from inside a knitr document. However, in addition to that, it needs to find out which document is being knit, i.e. the full path to that document.

The background for this is klmr/modules#31: modules needs to know the base path of its calling code in order to resolve relative import file locations. At the moment, it resolves to the directory of the code which kicks off the knitting process, which is usually not the correct directory.

Inside modules I cannot fix this issue without requiring the user to manually specify the module base path, which I’d like to avoid.

MWE:

  • doc.rmd:

    ```{r}
    devtools::install_github('klmr/modules')
    modules::import('./test')
    ```
    
  • test.r:

    message('I was called correctly.\n')
  • script/knit:

    #!/usr/bin/env Rscript
    knitr::knit('doc.rmd', 'doc.md')
chmod +x script/knit
./script/knit

Expected output:

[…]

I was called correctly!

Actual output:

[…]

Error in modules::import("./test"): Unable to load module ./test; not found in "./script"

@yihui
Copy link
Owner

yihui commented Apr 12, 2015

I don't fully understand the modules package, but when you are in knitr code chunks, the working directory is the directory that contains the input document by default. See the Note section in ?knitr::knit.

@klmr
Copy link
Contributor Author

klmr commented Apr 12, 2015

Apologies, I should have described this better:

Unfortunately the working directory doesn’t help me — in fact, modules intentionally does not use the working directory since that is generally completely arbitrary and has no relation to the file being executed. Instead, modules detects whether the code was launched via Rscript or R CMD BATCH (littler is on the TO DO list), and uses the path of that script.

In the MWE given above, this would be script/knit, so modules thinks that the base path is script (which would be correct for calls to modules::import inside script/knit; if modules were to use getwd(), this would not work if the user invoked the script via ./script/knit rather than via ./knit).

If it helps, consider another example with the following file structure (similar to one I’m actually using):

.
├── Makefile
├── analysis
│   ├── analysis-1.rmd
│   └── util
│       └── helpers.r
├── bin
│   └── knit
└── results
    ├── analysis-1.html
    └── analysis-1.md

The Makefile contains a very simple command along these lines:

results/%.html: analysis/%.rmd
    bin/knit $< $@

Here, my working directory would always be . but my analysis files are in ./analysis, and inside these analysis files I want to be able to issue the command modules::import('./util/helpers'), so modules needs to know which source file is being knitted, and where it is located.

@yihui yihui added this to the v1.10 milestone Apr 12, 2015
@yihui yihui added the feature Feature requests label Apr 12, 2015
@yihui yihui closed this as completed in 796e0bb Apr 12, 2015
yihui added a commit that referenced this issue Apr 12, 2015
@yihui
Copy link
Owner

yihui commented Apr 12, 2015

Got you. I think knitr::current_input(dir = TRUE) does what you want now.

@klmr
Copy link
Contributor Author

klmr commented Apr 12, 2015

Thanks, this looks almost perfect, there’s just one issue:

After a call to knit, the function still returns the file path (rather than NULL as it did before calls to knitr) — this one’s simple, it seems that knit should have an

on.exit(knit_concord$set(infile = NULL, outfile = NULL), add = TRUE)

after line 192.

@yihui
Copy link
Owner

yihui commented Apr 12, 2015

I have got it early on there: https://github.com/yihui/knitr/blob/8e2910e09/R/output.R#L132

Just pushed a fix to check if knit_concord$get('infile') is NULL. Thanks!

@klmr
Copy link
Contributor Author

klmr commented Apr 12, 2015

👍 Thanks a lot.

@github-actions
Copy link

This old thread has been automatically locked. If you think you have found something related to this, please open a new issue by following the issue guide (https://yihui.org/issue/), and link to this old issue if necessary.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature Feature requests
Projects
None yet
Development

No branches or pull requests

2 participants