\Sexpr{} special LaTeX characters ($, &, %, # etc.

2019-01-18 16:51发布

It has something to do with the default inline hook, I realize that and I have tried getting at it (the hook) and also read this thread and Yihui's page about hooks, but I haven't been able to solve my issue. I even tried this suggestion from Sacha Epskamp, but it didn't do this trick in my case.

I'm using \Sexpr and doing something along the lines of \Sexpr{load("meta.data.saved"); meta.data[1,7]} to print a keyword in my report, the problem is that people writing these keywords (people I can't control) are using special LaTeX characters ($, &, %, # etc.) and when they are passed to my .tex file without an \ I'm having a bad time.

I have an .Rnw file with this code,

\documentclass{article}
\begin{document}
 Look \Sexpr{foo <- "me&you"; foo} at this.
\end{document}

Thsi creates an .tex file with an illegal LaTeX character. Like this,

<!-- Preamble omitted for this example. -->
\begin{document}
 Look me&you at this.
\end{document}

I'm interested to get an output that looks like this,

<!-- Preamble omitted for this example. -->
\begin{document}
 Look me\&you at this.
\end{document}

Sorry for the simple question, but can someone help me, and maybe others, getting starting on how to modify the default inline hook for \Sexpr?

标签: r latex knitr
2条回答
2楼-- · 2019-01-18 17:07

Hooking works in this case. I customize it like this :

inline_hook <- function(x) {
  x <- gsub("\\&", "\\\\&", x)
  x <- gsub("\\$", "\\\\$", x)
  ## good luck for all Latex special character  
  ## $ % _  {  }  &  ~   ^  <  >   |  \ 
}
knit_hooks$set(inline = inline_hook)                    

Then

 knit(input='report.Rnw')      

Will reproduce your report.tex.

PS: I think it is better to not to allow users do what they want.

查看更多
不美不萌又怎样
3楼-- · 2019-01-18 17:12

The solution provided by @agstudy has shown the basic idea, and here is a more robust version:

hook_inline = knit_hooks$get('inline')
knit_hooks$set(inline = function(x) {
  if (is.character(x)) x = knitr:::escape_latex(x)
  hook_inline(x)
})

It only modifies the default inline hook when the inline result is character (otherwise just use the default hook). I have an internal function escape_latex() which hopefully escapes all special LaTeX characters correctly.

查看更多
登录 后发表回答