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

Proof of concept: Rmarkdown support #397

Closed
wants to merge 4 commits into from
Closed

Conversation

dometto
Copy link
Member

@dometto dometto commented Feb 13, 2021

Resolves gollum/gollum#1553

I managed to implement support for RMarkdown relatively painlessly by modifying the code filter. Obviously this is only a proof of concept. The biggest problem is that this implementation relies on the RinRuby gem which seems to be no longer maintained. I can't get the master version of that gem to work (the app hangs on startup when I require 'rinruby'), but the older released gem has a bug (fixed on master) which means you can't Ctrrl-D to interrupt the R process. :( Nevertheless, if there are different R-for-Ruby implementations, we would only have to modify the render_r method in the code filter.

Anyway, the end result on gollum is pretty cool:

Screenshot 2021-02-13 at 20 52 20

For this source:

```{r first_r_chunk}
vec <- c(1, 2, 3)
print(vec)

Tset

vec2 <- c(10, 20, 30)
vec3 <- vec * vec2
print(vec3)     

Test

library(ggplot2)
data(mpg, package="ggplot2")

mpg_select <- mpg[mpg$manufacturer %in% c("audi", "ford", "honda", "hyundai"), ]

# Scatterplot
theme_set(theme_bw())  # pre-set the bw theme.
g <- ggplot(mpg_select, aes(displ, cty)) + 
  labs(subtitle="mpg: Displacement vs City Mileage",
       title="Bubble chart")

g + geom_jitter(aes(col=manufacturer, size=hwy)) + 
  geom_smooth(aes(col=manufacturer), method="lm", se=F)
```% 

@dometto
Copy link
Member Author

dometto commented Feb 14, 2021

Fun fact: running it on JRuby with the master branch of https://github.com/clbustos/rinruby, everything works nicely!

Running with this in gollum's Gemfile:

gem 'rinruby', :github => 'clbustos/rinruby'
gem 'gollum-lib', :path => '/Users/dawa/Code/gollum_project/gollum-lib'

@dometto
Copy link
Member Author

dometto commented Feb 14, 2021

The difference between JRuby and MRI turns out to be that on JRuby, rinruby's so-called "interactive mode" was disabled by default. Disabling it explicitly fixes the problems on MRI, too.

@bartkamphorst
Copy link
Member

I wonder if we need rinruby or whether we would be better off rolling our own?

@dometto
Copy link
Member Author

dometto commented Feb 14, 2021

I wonder if we need rinruby or whether we would be better off rolling our own?

I've wondered about this too. Three points:

  • rinruby seems to work fine out of the box when you just run it in irb for instance. It's the combination with sinatra that seems to cause trouble unless interactive mode is disabled.
  • with interactive mode disabled, it seems to work fine with sinatra as well.
  • there are some complicated bits that I wouldn't look forward to writing myself (or would I?).

The maintainability of the project does not look great, but maybe it's better than nothing for MRI? On Java, there seem to be some other options, and on Truffle there would be https://github.com/rbotafogo/galaaz.

Another way to go would be using a TCP client to interact with RServe. There is an old ruby client for that by the same maintainer as rinruby. But it would require people to have installed and run RServe (not just R).

@dometto dometto marked this pull request as draft February 14, 2021 09:56
@dometto dometto changed the title [WIP] Proof of concept: Rmarkdown support Proof of concept: Rmarkdown support Feb 14, 2021
@dometto
Copy link
Member Author

dometto commented Feb 14, 2021

Some more notes:

  • The current approach requires the knitr (and gnuplot2) R packages to be installed by the user, but I think there's no real substitute for that (we don't really want to go installing packages on people's machines automatically).
  • We should test whether the speed of this implementation is acceptable for some more serious computations.
  • Currently, we're rendering {r} code blocks on pages in every format, not just .rmd. But maybe that's actually a cool feature? ROrg-Mode with gollum!

@dometto
Copy link
Member Author

dometto commented Feb 14, 2021

I should also clarify that when I say it works fine without interactive mode, that's on the master branch of rinruby. On the latest released version of the gem, everything "works" but there's still the problem of it being impossible to kill the app via ctrl-c. So there's a problem of maintainability anyway.

@bartkamphorst
Copy link
Member

The current approach requires the knitr (and gnuplot2) R packages to be installed by the user, but I think there's no real substitute for that (we don't really want to go installing packages on people's machines automatically).

Agreed, but we could try to render a useful message instead of either breaking or not rendering.

@dometto
Copy link
Member Author

dometto commented Feb 14, 2021

Conceptually, for MRI, I actually like the approach taken by this old gem which leverages libR through a C-extension to connect with an R instance -- so no need to handle sockets and threads in ruby. I don't know if a modern approach to that using ffi would work on JRuby.

@dometto
Copy link
Member Author

dometto commented Feb 14, 2021

Also: we should probably disable R execution by default for security purposes. Users who want to use RMarkdown on a public instance of gollum should probably use something like https://github.com/jeroen/RAppArmor.

@dometto
Copy link
Member Author

dometto commented Feb 14, 2021

Here's a way of capturing the output of R --slave (listen on standard in) that works on JRuby as well as MRI: https://gist.github.com/dometto/4b0bb1e43ef96f81d30c3d018062f64d

@dometto
Copy link
Member Author

dometto commented Nov 13, 2021

Different implementation coming

@dometto dometto closed this Nov 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature request: RMarkdown Support
2 participants