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

External package guessing output format #649

Closed
zeehio opened this issue Mar 22, 2016 · 7 comments
Closed

External package guessing output format #649

zeehio opened this issue Mar 22, 2016 · 7 comments
Assignees
Milestone

Comments

@zeehio
Copy link
Contributor

zeehio commented Mar 22, 2016

Thanks for your time and effort on both rmarkdown and knitr.

Let's say I have a package with a function that returns an S3 object:

new_myclass <- function() {
  return(structure(list(a=1, b=2), class = "myclass"))
}

I also have two functions that take a myclass object and return respectively a HTML representation and a LaTeX representation of the object.

myclass2html <- function(obj) { return("<p>MyClass object</p>")}
myclass2latex <- function(obj) { return("\begin{em}MyClass\end{em} object $x$")}

What functions/methods should I define to provide consistent and transparent knitr and rmarkdown support? I would like to support both .Rmd files and .R files with a header like:

#'---
#' title: My document
#' output: pdf_output
#'---

So far my approach is:

#' @importFrom rmarkdown metadata
#' @importFrom knitr opts_knit
guess_output_format <- function() {
  rmd_output <- tryCatch({rmarkdown::metadata$output},
                         error = function(e) {NULL})
  if (is.null(rmd_output)) {
    rmd_output = ""
  }
  if (is.list(rmd_output)) {
    rmd_output <- names(rmd_output)[1]
  }
  if (rmd_output == "pdf_document") {
    return("latex")
  } else if (rmd_output %in% c("html_document", "html_vignette")) {
    return("html")
  } else if (rmd_output != "") {
    return("")
  }
  # No rmarkdown, let's try with knitr:
  format <- knitr::opts_knit$get("out.format")
  if (format %in% c("html", "markdown")) {
    return("html")
  } else if (format %in% c("latex")) {
    return("latex")
  } else {
    return("")
  }
}

My main issue is that there may be two variables rmarkdown::metadata$output and knitr::opts_knit$get("out.format") that may or may not be defined (depending on whether or not rmarkdown is being used). I find this confusing.

  • What is the right way to know the output format?
  • Is there a get_output_format function that tells me the output format?

To put the question in context, I am working on the condformat package that allows to visualize DataFrames with conditional formatting rules.

This question has been asked also in stackoverflow without answer in several days.

Thanks for any piece of advice

@jjallaire
Copy link
Member

We define some knitr options that give you the pandoc to and from formats:

https://github.com/rstudio/rmarkdown/blob/master/R/render.R#L246-L252

Note that getting the name of the output format isn't that helpful as
there could be dozens of output formats you'd need to write code to
determine whether they are HTML or PDF. I'd say you should check the
output.to and look for "latex" or "beamer" to discover PDF output and then
assume HTML for everything else (i.e. don't try to emit RTF, ODF, MS Word,
markdown, etc.).

On Tue, Mar 22, 2016 at 5:56 AM, Sergio Oller [email protected]
wrote:

Thanks for your time and effort on both rmarkdown and knitr.

Let's say I have a package with a function that returns an S3 object:

new_myclass <- function() {
return(structure(list(a=1, b=2), class = "myclass"))
}

I also have two functions that take a myclass object and return
respectively a HTML representation and a LaTeX representation of the object.

myclass2html <- function(obj) { return("

MyClass object

")}myclass2latex <- function(obj) { return("\begin{em}MyClass\end{em} object $x$")}

What functions/methods should I define to provide consistent and
transparent knitr and rmarkdown support? I would like to support both .Rmd
files and .R files with a header like:

#'---#' title: My document#' output: pdf_output#'---

So far my approach is:

#' @importFrom rmarkdown metadata#' @importFrom knitr opts_knitguess_output_format <- function() {
rmd_output <- tryCatch({rmarkdown::metadata$output},
error = function(e) {NULL})
if (is.null(rmd_output)) {
rmd_output = ""
}
if (is.list(rmd_output)) {
rmd_output <- names(rmd_output)[1]
}
if (rmd_output == "pdf_document") {
return("latex")
} else if (rmd_output %in% c("html_document", "html_vignette")) {
return("html")
} else if (rmd_output != "") {
return("")
}

No rmarkdown, let's try with knitr:

format <- knitr::opts_knit$get("out.format")
if (format %in% c("html", "markdown")) {
return("html")
} else if (format %in% c("latex")) {
return("latex")
} else {
return("")
}
}

My main issue is that there may be two variables
rmarkdown::metadata$output and knitr::opts_knit$get("out.format") that
may or may not be defined (depending on whether or not rmarkdown is being
used). I find this confusing.

  • What is the right way to know the output format?
  • Is there a get_output_format function that tells me the output
    format?

To put the question in context, I am working on the condformat
http://www.sergioller.com/2016-03-10-condformat-release.md package that
allows to visualize DataFrames with conditional formatting rules.

This question has been asked also in stackoverflow
http://stackoverflow.com/questions/36044610/print-custom-object-in-rmarkdown-and-knitr-pdf-and-html
without answer in several days.

Thanks for any piece of advice


You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub
#649

@zeehio
Copy link
Contributor Author

zeehio commented Mar 22, 2016

Thanks @jjallaire, rmarkdown.pandoc.to makes things easier to me.

To make it better to future developers, would you accept a pull request to export knitr:::is_html_output, knitr:::is_latex_output, knitr::escape_html and knitr:::escape_latex? (or at least the first two?)

Otherwise I am happy enough with my approach:

  • If format is either "latex" or "beamer" then: output to LaTeX
  • If format is either "html" or starts with "markdown" (many markdown flavours!) then: output to HTML
  • Else: Use a generic output (I forgot to mention I have one)
#' @importFrom rmarkdown metadata
#' @importFrom knitr opts_knit
guess_output_format <- function() {
  outfmt <- knitr::opts_knit$get("rmarkdown.pandoc.to")
  if (is.null(outfmt)) {
    outfmt <- knitr::opts_knit$get("out.format")
  }
  if (is.null(outfmt)) {
    return("") # not in knitr
  }
  if (outfmt %in% c("latex", "beamer")) {
    return("latex")
  } else if (outfmt == "html" || substr(outfmt, 1, nchar("markdown")) == "markdown") {
    return("html")
  } else {
    return("unsupported") # uses a generic fallback
  }
}

Here is in its context

Thanks!

@jjallaire
Copy link
Member

@yihui, maybe we could even have a function like this:

knitr::current_output_type()

Which returns either "latex", "html", "markdown", or "unknown"

On Tue, Mar 22, 2016 at 8:41 AM, Sergio Oller [email protected]
wrote:

Thanks @jjallaire https://github.com/jjallaire, rmarkdown.pandoc.to
makes things easier to me.

To make it better to future developers, would you accept a pull request to
export knitr:::is_html_output, knitr:::is_latex_output, knitr::escape_html
and knitr:::escape_latex? (or at least the first two?)

Otherwise I am happy enough with my approach:

  • If format is either "latex" or "beamer" then: output to LaTeX
  • If format is either "html" or starts with "markdown" (many markdown
    flavours!) then: output to HTML
  • Else: Use a generic output (I forgot to mention I have one)

#' @importFrom rmarkdown metadata#' @importFrom knitr opts_knitguess_output_format <- function() {
outfmt <- knitr::opts_knit$get("rmarkdown.pandoc.to")
if (is.null(outfmt)) {
outfmt <- knitr::opts_knit$get("out.format")
}
if (is.null(outfmt)) {
return("") # not in knitr
}
if (outfmt %in% c("latex", "beamer")) {
return("latex")
} else if (outfmt == "html" || substr(outfmt, 1, nchar("markdown")) == "markdown") {
return("html")
} else {
return("unsupported") # uses a generic fallback
}
}

Here is in its context
https://github.com/zeehio/condformat/blob/master/R/condformat_render.R#L72


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
#649 (comment)

@yihui
Copy link
Member

yihui commented Mar 22, 2016

Okay, I'll consider exporting some of these functions from knitr.

@yihui yihui self-assigned this Sep 1, 2017
@yihui yihui added this to the v1.7 milestone Sep 1, 2017
@yihui
Copy link
Member

yihui commented Oct 25, 2017

I have exported is_latex_output and is_html_output in the dev version of knitr.

clrpackages pushed a commit to clearlinux-pkgs/R-knitr that referenced this issue Dec 29, 2017
Carsten Behring (1):
      Call lein exec with '-ep' instead of "-e" (#1439)

Christophe Dervieux (1):
      New imgur_upload with xml2 and httr (#1433)

Jim Hester (1):
      Allow use of _ in engine names (#1468)

Michael Chirico (1):
      Closes #1448. Adds support for fig.dim chunk option (#1449)

Yihui Xie (46):
      add a note on `R CMD build` based on the feedback from @pyltime
      a news item for #1417 and bump version
      fix #1431: try to write the csv file if possible
      bump version
      factor out png_available()
      assume the API always returns XML
      remove XML and RCurl in Suggests, and roxygenize after #1433
      roxygenize and bump version
      fix #1441: call evaluate::evaluate() at runtime instead of package build time
      bump version
      a second usage of engine_output(), so that I don't need to export wrap(); close #1442
      roxygenize and bump version
      add my ORCID
      close #1443: add an evaluate.inline hook
      bump version
      rename to showtext::showtext_begin()
      include_graphics() should use plot_counter() too, just in case it is used along with other plotting functions
      bump version
      fix #1446: when trailing spaces on certain lines of a code chunk in a blockquote are trimmed, knitr fails to remove the indent string (e.g. >)
      export is_latex_output() and is_html_output(); close rstudio/rmarkdown#649
      add a news item, roxygenize, and bump version
      html4 is also HTML output
      bump version
      fix rstudio/flexdashboard#155: html4 should be treated as an HTML output format (i.e. should not take screenshots for HTML widgets when the output format is html4)
      the dev option could be of length > 1, as revealed by rstudio/flexdashboard#155
      bump version
      close #1440: finally knitr can say hello to Python loudly and confidently!! 🎉
      unlist() the engine output if it is a list
      bump version
      typo
      fix #1460: `kable()` should generate the table caption when the data only has one column and the output format is pandoc
      add a new engine `julia` based on `JuliaCall::eng_juliacall()` (#1458)
      cosmetic
      fix #1462: retrieve column names *after* coercing x to a data frame, because dplyr's colum names may not be stable
      remove the last dependency on RCurl
      fix #1456: change the default of auto_pdf to FALSE in include_graphics()
      close #1455: support Haskell comments in read_chunk()
      add a news item for #1449
      a news item for #1444, and add @eliocamp to the list of contributors
      bump version
      a news item for #1462
      bump version
      bump the version of reticulate due to rstudio/reticulate#126
      reorder news items
      update the invalid URL
      knitr 1.18 was submitted to CRAN about a month ago, but I don't know what made it stuck there; I'm going to move on anyway

dmurdoch (1):
      Sweave2knitr left a connection open, the next gc() triggered a warning (#1432)

eliocamp (2):
      adds fig.ncol for latex output (#1444)
      trigger `hook_plot_latex()` with fig.subcap (#1466)

yonicd (1):
      add knitr::opts_chunk$append() (#1417)
@hughjonesd
Copy link
Contributor

hughjonesd commented Oct 31, 2018

Actually, it would be useful for package authors to get the name of the current output format. For example, bookdown uses a special reference scheme for tables. I currently detect this by looking at
rmarkdown::default_output_format(knitr::current_input()). That can be wrong if the default format is not what is being knitted. Could this be reopened?

@github-actions
Copy link

github-actions bot commented Nov 3, 2020

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 3, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants