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

Add function 'decktape()' #177

Merged
merged 28 commits into from
Nov 9, 2018
Merged

Add function 'decktape()' #177

merged 28 commits into from
Nov 9, 2018

Conversation

pat-s
Copy link
Collaborator

@pat-s pat-s commented Oct 24, 2018

fixes #168

Long wait. I tried various docker packages to make this function a bit more flexible.
None really worked (or my Docker knowledge is too small to properly deal with the implementations). So in the end I use a simple system() call.

However, the chosen hardcoded arguments should be ok for all users. That's why I did not add an option to change them. If errors are thrown some day with these defaults we need to change them anyways.

I am not sure about the implementation of the tests - I am used to testthat and couldn't really get a test run going with the testit pkg. Feel free to make changes yourself or just tell me what to do.

I added an convenience argument open_pdf to automatically open the resulting PDF file. It is cross-platform and works reliably.

Furthermore I tidied the DESCRIPTION using usethis::use_tidy_description(). Feel free to revert if you don't like it.

Should I add a slide to the demo slides with information about this function?

Copy link
Owner

@yihui yihui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with a system() wrapper function if the two dependencies are removed, although I still haven't become a fan of Docker. Perhaps we could let users choose whether to use Docker or not (in the latter case, it'd be a system() call to decktape directly).

For testing, the problem is not testthat or testit (the usage of testit should be straightforward enough: https://github.com/yihui/testit), but how to test PDF output. Do we put a copy of PDF output in this package, and compare MD5 sum? That may not be robust. I'd probably just not add tests for this function, since I feel it would be tricky.

Thanks!

DESCRIPTION Outdated
rstudioapi,
testit
VignetteBuilder:
knitr
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope cosmetic changes can be sent in separate PRs if you really want to make such changes. In general, please try to do one thing per PR. And in particular, cosmetic changes in PRs often become red herrings and can lead to bikeshedding...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can lead to bikeshedding

Yes, that's so true. And prob one of my personal biggest problems to always do such things in a PR while I'm "on something".

Will revert.

R/render.R Outdated
open_pdf = FALSE) {

if (is.null(decktape_version)) {
system(glue::glue("docker run --rm -t -v `pwd`:/slides -v $HOME:$HOME astefanutti/decktape {xaringan_path} {pdf_path}"))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see the need to introduce the dependency on the glue package. A simple call tosprintf() should suffice.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, there are ofc a lot of functions that do similar stuff. I was just used to glue so I used it.

Will change it.

R/render.R Outdated
}

if (isTRUE(open_pdf)) {
PBSmodelling::openFile(pdf_path)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another (soft) dependency introduced (which further depends on tcltk and XML). I'd rather not have this feature of automatically opening the PDF. It is costly with a relatively small gain. If you really like this feature, I'd just borrow the simple code from animation:::auto_browse.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, then I remove it again. I like it and used this pkg because I know that it works reliably cross-platform.

Tbh I didn't check for the deps it introduces.

@pat-s
Copy link
Collaborator Author

pat-s commented Oct 25, 2018

I'm fine with a system() wrapper function if the two dependencies are removed, although I still haven't become a fan of Docker. Perhaps we could let users choose whether to use Docker or not (in the latter case, it'd be a system() call to decktape directly).

I think the docker implementation is the big advantage here. It works OS-agnostic while the behavior of a locally installed decktape highly differs. E.g. on some OS you need to use --no-sandbox, on some not. On some OS specific versions of decktape will work fine while on other OS its different.

Also, with docker, you can use multiple versions easily while having multiple local versions of decktape is tedious.

I think a function that simply does a system() call to a local decktape installation even introduces overhead compared to simply calling decktape directly from the terminal.
By this I mean I am faster typing decktape .html .pdf (or evensystem(decktape .html .pdf) in an R workflow) in the terminal (if I have decktape installed locally) than export_pdf(html, pdf, local = TRUE) or similar.
Also, if we implement the "local method" I feat we might get a lot of issues of people facing problems with their local decktape installation. By only using the docker implementation we could state this in the help file and force the user to try multiple versions (usually 2.8.0 works fine for example).

For the docker image an explicit export_pdf() fun makes sense since I never want to remember all these docker arguments that are needed to call decktape.
In the end, the idea of this function is to not have the requirement of having decktape installed locally but just to have a working docker installation.
Well, now one can discuss which case is easier - having a running docker installation or decktape 😆

For testing, the problem is not testthat or testit (the usage of testit should be straightforward enough: yihui/testit), but how to test PDF output. Do we put a copy of PDF output in this package, and compare MD5 sum? That may not be robust. I'd probably just not add tests for this function, since I feel it would be tricky.

I also thought about a hash comparison but yeah - probably we do not need to test this. It's not a crucial function (convenience only) and error messages could be redirected to the decktape repo as its not within our responsibility.

Ok, this now almost becomes a blog post 🙃
Sorry for stealing so much of your time for such a small contribution.

@pat-s
Copy link
Collaborator Author

pat-s commented Nov 1, 2018

  • Decided to go with animation:::auto_browse() to open the PDF.
  • used roxygen markdown notation (hope that's ok as a PR side-effect)
  • sprintf() instead of glue()
  • added sections to the documentation

Copy link
Owner

@yihui yihui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rename the function to decktape(); export_pdf sounds too general. Thanks!

R/render.R Outdated
}

if (isTRUE(open_pdf)) {
animation:::auto_browse(pdf_path)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to copy the full source of auto_browse here to avoid dependency on animation.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did so.

R/render.R Outdated
xaringan_path, pdf_path))
} else {
system(sprintf("docker run --rm -t -v `pwd`:/slides -v $HOME:$HOME astefanutti/decktape:%s %s %s",
decktape_version, xaringan_path, pdf_path))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you able to merge the two system() calls into one to avoid the repetition of docker run --rm -t -v pwd:/slides -v $HOME:$HOME astefanutti/decktape?

BTW, what do `pwd`:/slides and $HOME:$HOME mean? Will they work on Windows?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you able to merge the two system() calls into one to avoid the repetition of docker run --rm -t -v pwd:/slides -v $HOME:$HOME astefanutti/decktape?

Yes, did so.

BTW, what do pwd:/slides and $HOME:$HOME mean? Will they work on Windows?

AFAICT yes. The two parts you mentioned are required for some local writing permissions for docker. I do not know more details unfortunately. I modified the defaults of the decktape readme because they were not as robust as this notation.

R/render.R Outdated
#'
#' @export

export_pdf = function(xaringan_path = NULL, pdf_path = NULL,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If xaringan_path and pdf_path are required arguments, they shouldn't default to NULL or have defaults at all.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, removed the defaults.

R/render.R Outdated
#' @section Docker:
#' To run this function you need to have a working installation of
#' [docker](https://www.docker.com/). For some operating systems you may need
#' to [add yourself to the "docker" group](https://stackoverflow.com/questions/48957195/how-to-fix-docker-got-permission-denied-issue?noredirect=1&lq=1)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The link could be shortened to https://stackoverflow.com/questions/48957195.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did so.

.travis.yml Outdated
packages:
- libgmp-dev
- libgsl0-dev
- libmagick++-dev # for animation
Copy link
Owner

@yihui yihui Nov 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't be necessary after the animation dependency is removed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jup.

DESCRIPTION Outdated
License: MIT + file LICENSE
URL: https://github.com/yihui/xaringan
BugReports: https://github.com/yihui/xaringan/issues
VignetteBuilder: knitr
Encoding: UTF-8
RoxygenNote: 6.1.0
Roxygen: list(markdown = TRUE)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay this time (you were essentially betting, though).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, sorry. Reverted ;)

@pat-s
Copy link
Collaborator Author

pat-s commented Nov 8, 2018

@yihui ready for the next (hopefully last) round :)

@yihui
Copy link
Owner

yihui commented Nov 9, 2018

@pat-s Thanks a lot! I'll review and merge it tomorrow.

@yihui yihui added this to the v0.8 milestone Nov 9, 2018
@yihui yihui merged commit 57a41b5 into master Nov 9, 2018
@yihui yihui deleted the pdf branch November 9, 2018 20:09
@yihui yihui changed the title Add function 'export_pdf()' Add function 'decktape()' Nov 29, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Function to export slides to PDF?
2 participants