This is indeed tricky, because a lot of things are mixed up in bookdown.
A bit of context first:
This kind of syntax will only work if the file is knit.
"`r rmarkdown::metadata$title`"
This is an inline r expression you can use in an rmarkdown file. And it works in the yaml header because the file is knitted before pandoc process it.
Inside another yaml file, it won't work because this external yaml is not process by knitr.
However, you can run expression in yaml using this syntax !expr
. This is a feature from the yaml that rmarkdown & friends is using with eval.expr
set to TRUE
yaml::yaml.load("test: !expr 1+1", eval.expr = TRUE)
#> $test
#> [1] 2
Created on 2020-09-09 by the reprex package (v0.3.0.9001)
But for that to work, the r object need to be available.
We could try to use
book_filename: !expr rmarkdown::metadata$title
but rmarkdown::metadata
needs to be filed up for that to work and I am not sure it will work.
This is an interesting use case. For now I believe you'll need to use workaround. And I could think of several but only the first one is working
-
You can modify the yaml config file before rendering your book to modify the content programmatically. You can even use a temp one or have several yaml you would select when rendering
-
You could try to set a R variable in the session to be used when loading the yaml file that contains a !expr
call. You need to use clean_envir = FALSE
for now (but it wil be deprecated)
-
We could do some adjustment in bookdown. One example is can pass a list of bookdown configuration in render_book
- This work a that way for output_format
. See below.
We need to open an option to discuss that.
Example for solution 1
bookname <- "mybook"
ori_yml <- "_bookdown.yml"
tmp_yml <- tempfile(fileext = ".yml")
yml_content <- yaml::read_yaml(ori_yml)
yml_content[["book_filename"]] <- bookname
yaml::write_yaml(yml_content, tmp_yml)
bookdown::render_book(
"index.Rmd",
output_format = "bookdown::epub_book",
config_file = tmp_yml
)
Example for solution 2
Write this in your _bookdown.yml
yaml
book_filename: !expr bookname
and use this code to render
bookname <- "mybook"
bookdown::render_book(
"index.Rmd",
output_format = "bookdown::epub_book",
clean_envir = FALSE
)
I set output_format
in both example just to show the the ebook name is changed as expected.
About edit
configuration, you could apply one of this strategy too because you can set it in the _bookdown.yml
too (see https://bookdown.org/yihui/bookdown/configuration.html)
About the modification of _output.yml
option
You could use output_options
argument to change that IMO. It works well for rmarkdown, and it works also for all output format. That means you can change that at rendering using somethink like this
bookdown::render_book(
"index.Rmd",
output_format = "bookdown::gitbook",
output_options = list(
config =
list(edit = "https://github.com/orgname/myproject/edit/master/%s"))
)
This would modify the config
value if gitbook()
format.
With this answer, I have just wanted to share some workaround. It is definitly not obvious at first.
I would like to have your opinion on this. I think it could be improved in some way for _bookdown.yml
option to work as the modification of output options. Something like
bookdown::render_book(
"index.Rmd",
output_format = "bookdown::gitbook",
config_options = list(book_filename = "my_book")
)
That would be merge with the config file used.
I eager to hear your feedback on this. And thanks a lot for all the feedback you gave us on bookdown !