rr-exams

exams:::exams2pdf: compile SVG and PNG images conditionally


This question regards finding a way to use the same R/exams exercise to pick either an SVG image if exams2html is called, or a twin PNG image if exams2pdf is called.

I have been using SVG images with exams2html because vectorized images look great on any browser. But of course that won't work for exams2pdf so I also export the image to PNG. The images are perfectly identical. Ideally, it would be great if I could code the exercise such that ![](myplot.png){width="40%"} is picked up by exams2pdf and ![](myplot.svg){width="40%"} is picked up by exams2html. Could someone suggest a coding trick inside the exercise to make this happen? Thank you so much.


Solution

  • First, when the graphic is generated in an R figure code chunk within the exercise (e.g., as in boxplots or scatterplot), then you can simply use exams2html(..., svg = TRUE) to get the SVG version while the PNG version would be used by default (also in exams2pdf()).

    If you have a static graphic you want to include - or a graphic that you do not generate with a standard figure code chunk - then you can use one of two functions to control which file you use: match_exams_device() or match_exams_call().

    With match_exams_device() you get "png" or "svg" etc. depending on which type of graphic a figure code chunk would have used. Thus, you can propagate settings such as exams2html(..., svg = TRUE) into the exercise. Then you could do:

    fig <- if(match_exams_device() == "svg") "myplot.svg" else "myplot.png"
    

    and then include it as

    ![](`r fig`){width="40%"}
    

    With match_exams_call() you can do the same but would check something like:

    fig <- if(match_exams_call() %in% c("exams2pdf", "exams2nops")) {
      "myplot.png"
    } else {
      "myplot.svg"
    }
    

    For further examples see the automaton and logic exercises where the graphics are generated with TikZ using these ideas.