yihui / knitr

A general-purpose tool for dynamic report generation in R
https://yihui.org/knitr/
2.39k stars 878 forks source link

inline code chunks for foreign engine #2026

Open rcst opened 3 years ago

rcst commented 3 years ago

I have posted this question on SO.

I've written a knitr engine to process Maxima code (as part of a package), which works for "regular" chunks just fine, e.g.:

```{maxima}
1+1;

results in 

(%i1) 1+1;

(%o1) 2


However, when I try to get the output printed inline, such as

maxima 1+1;



It gets printed literally: `maxima 1+1;`

The *R Markdown Cookbook* explicitly says
> inline: processing output from inline R expressions.

# Questions
So I guess this is not meant be working (yet)? 
Is there a workaround?
What parts of `knitr` should I touch, if I wanted to implement it?    

---

By filing an issue to this repo, I promise that

- [x] I have fully read the issue guide at https://yihui.org/issue/.
- [x] I have provided the necessary information about my issue.
    - If I'm asking a question, I have already asked it on Stack Overflow or RStudio Community, waited for at least 24 hours, and included a link to my question there.
    - If I'm filing a bug report, I have included a minimal, self-contained, and reproducible example, and have also included `xfun::session_info('knitr')`. I have upgraded all my packages to their latest versions (e.g., R, RStudio, and R packages), and also tried the development version: `remotes::install_github('yihui/knitr')`.
    - If I have posted the same issue elsewhere, I have also mentioned it in this issue.
- [x] I have learned the Github Markdown syntax, and formatted my issue correctly.

I understand that my issue may be closed if I don't fulfill my promises.
atusy commented 3 years ago

I've been thought about this before. I concluded the syntax like `maxima 1+1;` is not a good idea because addition of engines certainly make authors difficult to distinguish which inline code need the evaluation.

If I were to implement, I'd implement `1+1;`{maxima} which is more consistent with the syntax of chunk and may allow additional chunk options.

About the current implementation,

yihui commented 3 years ago

I agree with @atusy. I tend not to generalize the syntax `r ` to other engines. I'm not totally comfortable with the syntax for inline expressions since it's not unique enough. People might write literal code like `r = sqrt(x^2 + y^2)`, which doesn't mean inline R code. If I generalize the syntax to other languages, the potential ambiguity can bite users harder.

Is there a workaround?

I don't know anything about the rim package you mentioned. If it provides a way to access maxima variables or run maxima code from the R session, your problem would be solved. The reticulate package is a good example, e.g., you can use reticulate::py to access Python objects. However, you mentioned that rim::maxima.get() uses a different maxima session: https://stackoverflow.com/questions/68283952/knitr-inline-code-chunk-of-foreign-engine#comment120684378_68283952 Then perhaps there isn't a workaround.

vorpalvorpal commented 3 years ago

If I were to implement, I'd implement `1+1;`{maxima} which is more consistent with the syntax of chunk and may allow additional chunk options.

More consistent with both the current syntax and the chunk syntax would be `{engine_name} foo`. If this were introduced, `r foo` could then become a shortcut for `{r} foo`.

atusy commented 3 years ago

`{engine_name} foo` is interesting. However, I still say `foo`{engine_name} because this syntax is more consistent with Pandoc's inline code with attributes (e.g., `knitr::knit(x)`{.r})

rcst commented 3 years ago

Thanks for your suggestions. I solved this issue by implementing a wrapper maxima.inline() that accesses the Maxima session used for the knitr-engine. So the user can do

`r maxima.inline("1+1;")`

I think that's sufficient for this issue.

cderv commented 5 months ago

`{engine_name} foo` is interesting. However, I still say `foo`{engine_name} because this syntax is more consistent with Pandoc's inline code with attributes (e.g., `knitr::knit(x)`{.r})

Just adding here that in Quarto, the inline syntax is now

`{r} x` 
`{python} x`

and not the attribute version

So it would make sense to support similar syntax natively (currently Quarto is doing the transformation from `{r} ...` to `r ... `

https://quarto.org/docs/computations/inline-code.html

yihui commented 5 months ago

Interesting. It happens that I did the same thing in litedown (in theory, inline code can use any language). Also I added support for chunk options for inline code, e.g., `{r, eval=FALSE} x`.