Search code examples
latexr-markdowntikzr-examspstricks

Can I include pstricks code in R/exams with exams2pdf and exams2moodle output?


I'm trying to include the following pstricks code snippet in R/exams .Rmd exercises, but I have no idea how to do it:

\\begin{pspicture}(-2, -2)(3, 3)
\\psset{viewpoint=100 30 20,Decran=100}
\\psSolid[object=cube, a=2,
    action=draw*,
    fillcolor = magenta!20
]
\\axesIIID[showOrigin=false, labelsep=5pt](1,1,1)(3,2,2)
\\end{pspicture}

\\begin{tikzpicture}
    \\draw[<->] (0, 0) -- (5, 5);
\\end{tikzpicture}

Solution

  • Yes, it is possible, although I wouldn't recommend it. You can use the following:

    • Set up a string with the LaTeX code include pstricks.
    • Call tex2image(..., packages = c("auto-pst-pdf", ...)) so that the LaTeX package {auto-pst-pdf} is used. This supports embedding pstricks in documents for the pdfLaTeX by calling LaTeX for the figure in the background.
    • Make sure tex2image() calls pdfLaTeX with the -shell-escape option so that pdfLaTeX is allowed to call LaTeX. This is relatively easy by using the R package tinytex.

    A worked example for this strategy is included below, it is called dist4.Rmd. If you copy the R/Markdown code to a file you can run:

    exams2html("dist4.Rmd")
    

    screenshot of the dist4.Rmd exercise rendered in HTML

    The same could be done in exams2moodle(). The exercise is inspired by the dist, dist2, dist3 exercise templates readily available in R/exams. Compare to these templates which draw the graphics in R, the dist4.Rmd exercise is terribly slow. R calls pdfLaTeX which calls LaTeX and all of these post-process the graphics output. Hence, I would only use pstricks if I have complex legacy LaTeX code in pstricks or specialized packages built on top of pstricks that would be hard to rewrite in R (or in TikZ).

    Below you find the R/Markdown source code. This is similar to the exercises using include_tikz(). The crucial differences are that (a) tex2image() is called directly (rather than via include_tikz()), (b) the resulting image has to be embedded manually, and (c) the R package tinytex is needed and the option tinytex.engine_args = "-shell-escape" needs to be set.

    ```{r, include = FALSE}
    ## data
    p <- c(sample(1:3, 1), sample(1:5, 1))
    q <- c(sample((p[1] + 1):5, 1), sample(1:5, 1))
    sol <- sum(abs(p - q))
    
    ## pstricks
    pst <- '
    \\begin{pspicture}(-1,-1)(7,7)  
    \\psaxes{->}(0,0)(-0.2,-0.2)(6.5,6.5)[$x$,0][$y$, 90]
    \\psdot(%s,%s)
    \\uput[0](%s,%s){$p$}
    \\psdot(%s,%s)
    \\uput[0](%s,%s){$q$}
    \\end{pspicture}
    '
    pst <- sprintf(pst, p[1], p[2], p[1], p[2], q[1], q[2], q[1], q[2])
    
    ## generate figure via tinytex and shell-escape option
    opt <- options(exams_tex = "tinytex", tinytex.engine_args = "-shell-escape")
    fig <- tex2image(pst, packages = c("auto-pst-pdf", "pst-all"),
      name = "pqdist", dir = ".", resize = 400)
    options(opt)
    ```
    
    Question
    ========
    
    What is the Manhattan distance $d_1(p, q)$ of the two points
    $p$ and $q$ shown in the following figure?
    
    ![](`r basename(fig)`)
    
    
    Solution
    ========
    
    The Manhattan distance is given by:
    $d_1(p, q) = \sum_i |p_i - q_i| = |`r p[1]` - `r q[1]`| + |`r p[2]` - `r q[2]`| = `r sol`$.
    
    
    Meta-information
    ================
    exname: Manhattan distance
    extype: num
    exsolution: `r sol`
    exclozetype: num