twibiral / obsidian-execute-code

Obsidian Plugin to execute code in a note.
MIT License
1.08k stars 67 forks source link

[Feature] Read ```{x} for Rmd/quatro compatability #80

Open vorpalvorpal opened 1 year ago

vorpalvorpal commented 1 year ago

Rmarkdown and quatro are commonly used markdown derivatives used in data science. In these formats, code blocks begin with ```{name} rather than ```name (eg. ```{r} or ```{python} instead of ```r or ```python). Would it be possible to read and execute code blocks with the language name in curly brackets the same as if the curly brackets weren't there. This would make it easy to edit rmarkdown/quartro documents within obsidian.

I feel like this would only be a minor change and I tried to find where in the code to make it, but got lost in all the unfamiliar javascript.

twibiral commented 1 year ago

This syntax is currently not supported by obsidian and therefore isn't supported by this plugin yet. But I think it will be no problem to implement this and I will look into it.

We are currently trying to utilize brackets for additional parameters that allow further configuration of each block. I hope this won't clash. I never used the Rmarkdown and quatro syntax and would really appreciate it if you could link me to some resources that can help us improve the support for Rmarkdown and quatro.

For which languages are quatro and Rmarkdown typically used? Maybe we can further improve the support for these languages in combination quatro/Rmarkdown.

vorpalvorpal commented 1 year ago

Rmarkdown/quatro (quatro is essentially Rmarkdown v2 with better integration for jupyter notebooks) is a system for making data driven documents. It is most frequently used with R, but also with python and to a lesser extent with julia, javascript and maybe some others. The basic idea of Rmarkdown is that it is a plain markdown document with code in it that is evaluated by a system called knitr. So as a simple example if the following code chunk was in a Rmarkdown document:

```{r}
plot(x = variable1, y = variable2)
```

then knitr would read this and create a new markdown file with the code chunk replaced with

![]('plot.png')

and then pass that markdown file on to pandoc (or other programs) to work their magic. So the purpose of the curly brackets around the language name is to distinguish the Rmarkdown code chunk from a markdown code chunk that knitr won't evaluate.

Anyway, because Rmarkdown files are just a superset of markdown it is possible to include Rmarkdown files in a vault and have obsidian read/write them. What I am wondering is if it would be possible to execute Rmarkdown chunks as if they were normal markdown chunks. If I was writing a complex Rmarkdown document I'd want to be doing it within VSCode, Rstudio, vim or some other proper IDE. But it would be nice to also be able to quickly check or edit it within obsidian.

A typical use case would be a report (or dashboard or similar) written in Rmarkdown that analyses some frequently updated data source (website statistics, weekly earnings, environmental monitoring data). To generate this week's report I would use knitr, but if i just wanted to see how one of the plots is looking, I could execute a single code chunk from within obsidian.

With regards to the chunk options syntax you are considering. As I understand it the suggestion was made to use curly brackets inspired from Rmarkdown. Rmarkdown does this slightly differently to this suggestion. The Rmarkdown sytle is to place chunk evaluation options after the language engine name within the same curly brackets. This makes sense since the language engine name is an option (what should I use to evaluate this chunk) eg:

```{r option1=x, option2=y} 
plot(x = var1, y = var2)
```

Quatro takes a different approach and places the options as a commented YAML block at the beginning of the code block. This is a good approach because numerous options all in one line quickly become unreadable. eg:

```{r}
#| label: fig-polar
#| echo: false
#| fig-cap: "A line plot on a polar axis"
plot(x = var1, y = var2)
```
twibiral commented 1 year ago

@vorpalvorpal Thank you for the additional info, this is really helpful!

@milan338 What's your thought about the easiest way to integrate this?

milan338 commented 1 year ago

For rmarkdown syntax, we could just check for the file extension and in that case grab the language by splitting the first { and go from there (assuming you wouldn't have rmarkdown syntax in a non-rmd file, otherwise this could get messy). For quatro there doesn't look like there's a specific file extension, so we'd have to try searching for ```{language} and then try to grab all the following lines that start with #| and parse it as yaml. But obsidian doesn't support these for syntax highlighting, and I don't know how worthwhile it would be to try to support every syntax out there, which would get messy. There's also a lot of functionality that rmd and quatro seem to provide that would take a lot of time to implement, and some involve dealing with the markdown output directly which could get tricky.

Overall we could try to support these syntaxes, but it's a lot of work to get all the features working. Another idea would be to not try support all the quatro / rmd args and just get the language runnable, but this would require adding a run button to every invalid code block (since obsidian doesn't recognise these as valid), and we couldn't use any of our custom syntax because this would result in invalid rmd / quatro. But this wouldn't produce the expected output since the args wouldn't be supported. Maybe if there was a way to get obsidian to recognise them as valid code blocks, this could be easier.

twibiral commented 1 year ago

@vorpalvorpal I implemented a change that is released soon and allows the use of the curly bracket syntax for the language name (using {python} instead of python)

More features of markdown / quatro may follow in the future

vorpalvorpal commented 1 year ago

@twibiral Thanks! For me personally, just being able to execute code chunks is the main thing. Most of the rmarkdown options are probably not really relevant to obsidian.

odebroqueville commented 1 year ago

Instead of parsing the code blocks (namely looking for {language}), would there be a way to use a quarto command to execute the code blocks inside qmd files shown in Obsidian?

Maybe the Quarto CLI command 'quarto preview' could be used? Usually, it applies to a qmd file, so I'm not sure if it can be used for a code block.

odebroqueville commented 1 year ago

@twibiral Don't know if this might help, but by adding the following shell settings in your extension:

Screenshot 2022-10-10 at 22 04 20

I was able to run the following shell code block:

Screenshot 2022-10-10 at 22 02 56

There are 2 issues with this:

  1. the result is rendered in the default browser
  2. the shell code block is also rendered
PCesteban commented 4 months ago

Hello @twibiral, I came across your plugin, and having recently discovered quarto I fell in love with the capabilities we would have with an obsidian-quarto integration. What's the current status of this?

twibiral commented 3 months ago

Hi @PCesteban , the feature is partially implemented. You can use the syntax {r} for all languages (not just R) but many (most?) of Rmarkdowns features are not supported. I think obsidian also doesn't support the Rmarkdown syntax. Just try out what works and what doesn't