Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

have internal links into code looking blocks

I would like to place links inside of a block that would look like a code block.

I believe it's impossible to do it in a real code block (though it'd be nice), but I don't really need it as I don't need nor the evaluation nor the syntax highlighting (so please don't mark as duplicate of a post that asks for functional code blocks).

I just need it to look the same (ideally independently from theme choice but I can compromise).

This is what obviously doesn't work but gives you an idea of the desired effect.

```{r,echo=TRUE, eval=FALSE} 
[print](#print)("hello world")
```

### print {#print}

print prints its argument and returns it invisibly (via invisible(x)).

The code will read print("hello world") and print will be clickable and take us to the section tagged with {#print}.

It needs to work with multiple lines of code.


Edit for bounty :

Current solution is really cool and deserves more visibility. However it will create a link for a sequence of character preceding a parenthesis. I would like now to have a link whenever a variable whose name is also the label of a ### header3 is found, with no trick using : #[]

So my markdown would only be the following, with the addition of js proposed in the solution, and clicking on print or summary in my code would link to the right section:

---
title: "Untitled"
output: html_document
---

```{r, eval = FALSE}
mod <- lm(mpg ~ hp, data = mtcars)
summary(lm(mpg ~ hp, data = mtcars))
summary(mtcars)
```

### lm

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.   


### summary

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.  
like image 846
Moody_Mudskipper Avatar asked Apr 15 '18 11:04

Moody_Mudskipper


1 Answers

I presume you only need that for HTML output. Then here is my attempt:

  1. We mark the lines of code where we want to link a function name by adding a comment at the end of the line: #[]. This guarantees that the code can still be evaluated.

  2. We use JavaScript (with JQuery) to select all code chunks (all <code> elements). For each chunk, we get the HTML content, split it by line and save it as old_str.

  3. Now we go through this array of code lines and check if our mark #[] occurs. If so, we remove it and replace the other parts of that line accordingly, including our hyperlink.

  4. At last we insert new_str as the new HTML content of that chunk.

The regex used seems to work well for nested functions. All function names within a marked line are linked.

Here is the MRE and its output:

---
title: "Untitled"
output: html_document
---

<script>
$(document).ready(function() {
  $chks = $('code');
  $chks.each(function() {
    var old_str = $(this).html().match(/[^\r\n]+/g);
    for( i = 0; i < old_str.length; i++ ) {
      if(old_str[i].includes("#[]")) {
        old_str[i] = old_str[i].replace(/#\[\]/g, '');
        old_str[i] = old_str[i].replace(/([a-zA-Z0-9\.\_]*)(\()/g, '<a href="#$1">$1</a>$2');
      } 
    }
    var new_str = old_str.join('\n');
    $(this).html(new_str);
  });
});
</script>

```{r, eval = T} 
print("hello world")#[]
```   

```{r, eval = F}
mod <- lm(mpg ~ hp, data = mtcars) #[]
summary(lm(mpg ~ hp, data = mtcars))#[]
summary(mtcars) #[]
```

### print {#print}

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.   


### Summary {#summary}

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.   

enter image description here

As you can see the linked function names occur blue in the output document. If you dont want the links to be blue you can adjust each state of the link by using the corresponding CSS:

<style>
code > a:link, a:visited, a:hover, a:active {
  color: black;
}
</style>

Here we set the font in all states to black.

like image 157
Martin Schmelzer Avatar answered Sep 22 '22 17:09

Martin Schmelzer