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

Make it possible to hook into the output #248

Open
jankatins opened this issue Mar 9, 2016 · 6 comments
Open

Make it possible to hook into the output #248

jankatins opened this issue Mar 9, 2016 · 6 comments

Comments

@jankatins
Copy link

Currently it is not possible to get the output and display it as markdown without either using a wrapper function or setting some knitr options to get a knit_asis object. Unfortunately, the asis object doesn't work in the context of the Jupyter R kernel, as it lacks information what kind of content is in the asis object (html, latex, md,...)

To make it possible to consume the output of teh pander call in both knitr and irkernel, I propose to change the API of the pander call to return a structure and then implement three methods to print the markdown as appropriate in the current context.

Prototype:

library(pander)
# to make it work in the jupyter notebook...
panderOptions('table.style', 'rmarkdown')
panderOptions("table.split.table", Inf)

# This would be the new pander(...) function
pander <- function(x = NULL, ...){
    t = capture.output(UseMethod('pander', x))
    structure(paste(t, collapse="\n"), class = 'pander_output')
}

# output in knitr
knit_print.pander_output <- function(x, ...) {
    if (isTRUE(panderOptions('knitr.auto.asis')){
       return(knitr::asis_output(as.character(x)))
   } else {
       cat(as.character(x))
   }
}

# output in the jupyter notebook
repr_markdown.pander_output <- function(x,...){
    as.character(x)
}

# output when in a console
print.pander_output <- function(x) {
    cat(as.character(x))
}
# ---
# in a notebook, this will result in a displayed markdown = html table
# in the console, it will display the markdown code
# in knitr, it will return a knit_asis object, which knitr then displays
pander_new(df)

As far as I understand it, the only downside is that x = paste(capture.output(pander(...)), collapse="\n") wont work afterwards anymore, as the call itself won't cat anything. All such calls would have to be changed to as.character(pander(...)) -> breaking API change :-(.

If this is acceptable, a question is how deep you want to change this: the easiest implementation would just use capture.output(), but this issue/PR could also be used to change the calls further down to use string concatenation and return a string instead of using cat directly.

If you agree with this proposal, I can do a PR...

[This original issue for this was https://github.com/IRkernel/repr/issues/33 // cc: @flying-sheep]

@daroczig
Copy link
Member

daroczig commented Mar 9, 2016

Thanks for this proposal, which makes a lot of sense, but I will have to make sure that it doesn't break many things in the reverse dependencies -- as eg brew / Pandoc.brew / rapport requires stuff written to stdout without printing. Based on that, it's not as simple as described above -- so it might not happen within a few days. Anyway, it's a great idea and I will spend some time on these checks.

@jankatins
Copy link
Author

Ok, I never considered that there more packages which do document conversations...

If this becomes a problem, this could be solved the same was as the multiline vs. rmarkdown switch in the options:

pander_return <- function(...){...new version...}
pander_cat <- function(...){..old version...}
in_kernel = isTRUE(getOption('knitr.in.progress'))
in_knitr = isTRUE(getOption('jupyter.in_kernel', FALSE))
pander <- if(in_kernel | in_knitr){pander_return} else{pander_cat}

@daroczig
Copy link
Member

@JanSchulz can you please have a look at the above PR and test with Jupyter? I am not sure if you need a character vector or concatenated string.

If it seems to work, then I will add some docs on this behavior and merge.

@jankatins
Copy link
Author

This doesn't work :-( We need to have something which differentiates it from a plain character vector, so that we can treat it differently from such a vector:

structure(paste(t, collapse="\n"), class = 'pander_output')

@daroczig
Copy link
Member

@JanSchulz please check the updated PR based on that.

@jankatins
Copy link
Author

See the pr...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants