8

I am writing a report in Rmarkdown which shall be rendered in html because it contains Rshiny chunks. Is there any way I can add line numbers to the file?

Importantly I need line numbers for the text and not for the code chunks as asked here.

I wonder if it is possible to add some CSS to the .Rmd file below but wouldn't know how to do that.

---
title: "Title"
author: "Yourname"
date: "June 16, 2016"
output: html_document
runtime: shiny
---


This R Markdown document is made interactive using Shiny. 
Unlike the more traditional workflow of creating static reports, you can now create documents that allow your 
readers to change the assumptions underlying your analysis and see the results immediately. 

## Inputs and Outputs

You can embed Shiny inputs and outputs in your document. Outputs are automatically updated whenever inputs change.  
This demonstrates how a standard R plot can be made interactive by wrapping it in the Shiny `renderPlot` function. 
The `selectInput` and `sliderInput` functions create the input widgets used to drive the plot.

Thank you very much,

Paul

Community
  • 1
  • 1
Paul
  • 328
  • 2
  • 11

1 Answers1

7

Interesting question and since I like to play around with JS and jQuery inside of RMarkdown documents I gave it a shot.

This solution is not bulletproof. It is only tested with Firefox. Since cross-browser compatibility of jQuery is a mess it will probably only work with Firefox.

Every line is now labeled including normal paragraphs, unordered and ordered lists, source code and output chunks.

Here is the complete working document:

---
title: "Title"
author: "Yourname"
date: "June 16, 2016"
output: html_document
runtime: shiny
---

<style>
/* Style the linenumber div */
  .linenumbers {
    border: 1px solid #ccc;
    border-radius: 4px;
    background-color: #EBEBEB;
    text-align: center;
    padding: 0px 3px;
    font-family: monospace;
    float: left;
    position: absolute;
    transform:translate(-125%);
    font-size: inherit !important;
  }

  .main-container {
    margin-left: 8% !important;
  }

  /* fixes the problem with inline code 
     that makes the line spacing bigger: */
  p > code {
    line-height: 90% !important;
  }
</style>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>

<script>
  $(document).ready(function(){
  var $elements = $('p:not(:has(>img)), pre,  ul, ol');
    $elements.wrap('<numbering/>');
    $('numbering').prepend('<div class=\"linenumbers\"/>');

    updateLines = function(elmts) {
      var counter = 1; // counts total number of lines
      $(elmts).each(function() {       

        if($(this).is('pre')) {
          var $elmt = $(this).children('code');
          var styles = $(this).css([ "padding-top", "padding-bottom", "line-height"]);
          $(this).siblings('.linenumbers').css(styles);
        } else {
          var $elmt = $(this);
        }

        var h  = $elmt.outerHeight();  // get the height
        var nl = Math.round(h /parseFloat($elmt.css('line-height'))); 
        var text = '';
        for(var i=counter; i < counter + nl; ++i) {
          text += i + '</br>';
        }
        counter += nl;
        $(this).siblings('.linenumbers').html(text);
      });
    };
    updateLines($elements);

  });

  $(window).resize(function() {
    updateLines($elements);
  });
</script>

This R Markdown document has the ability to interactively number 
the lines of text content. It might not be perfect but it sure 
looks nice. If you find a bug or have a tip for how to further improve 
the code, please let me know. I am no professional JavaScript 
programmer so  this was made by an amateur ;)


What if I leave some space here?


## Inputs and Outputs

Here starts another paragraph. Look how the line numbers jump over to 
this one! This is amazing! For demonstrating purposes I have to write 
some more lines. So I bore you a bit more with my nonsense. NONSENSE! 
Ok let us try out some inline code and see whether the line numbers 
still align. `library(ggplot2)` And a second `time()`. Looks ok I 
guess. 
Here starts another paragraph. Look how the line numbers jump over to 
this one! This is amazing! For demonstrating purposes I have to write 
some more lines.    
So I bore you a bit more with my nonsense. NONSENSE! Ok let us try out 
some inline code and see whether the line numbers still align.
`library(ggplot2)` And a second `time()`. Looks ok I guess.
 
```{r}
x <- 1:5
B <- 'Martin'
head(mtcars)
```

```{r}
plot(1)
```

You can exclude certain parts by just removing the corresponding tag from the line

var $elements = $('p:not(:has(>img)), pre,  ul, ol');

So if you do not want to label output chunks and lists, change it to

var $elements = $('p:not(:has(>img)), pre.r');

(Unlike output chunks, source code chunks carry the class .r.)

As I said for complex documents you might stumble over some bugs. Let me know if you do ;)

enter image description here

Martin Schmelzer
  • 23,283
  • 6
  • 73
  • 98
  • This is amazing! How can we get the numbering to include the code chunks? I tried putting around them but it had no effect. – Ben Jun 22 '16 at 16:36
  • Martin, thank you so much! A big step towards writing a conference paper in rmarkdown with Shiny elements. I noticed two things. It works in Firefox 47.0 but not in Chrome 51.0 on my computer. Moreover, if there is a free empty line within the tags it stops numbering. Any ideas? – Paul Jun 22 '16 at 16:44
  • 1
    Paul and @Ben: Thanks and your welcome. I looked into the problems. First thing I can say is that these jQuery mechanisms are not cross-browser compatible so you would have to stick to Firefox. Tomorrow I will update the answer with some new code supporting source code chunks. – Martin Schmelzer Jun 22 '16 at 22:55
  • Paul and @Ben: Well I could not wait until tomorrow ;) – Martin Schmelzer Jun 22 '16 at 23:51
  • You might also be interested in [this answer](https://stackoverflow.com/questions/48914212/numbered-code-chunks-in-rmarkdown). – AvidLearner Jun 10 '18 at 06:45
  • @MartinSchmelzer Is there a another way to do this? I don¨t really know what I do wrong but this is not working for me? I found other methods that numbering each lines with 1 2 3 4 ... 1 2 3 4 .. 1 etc. But I don't it to start from 1 whenever there is a new chunk.. I just want it to start with 1 and then continue. So, your method is what I want but it's just not working for me – rr19 Nov 04 '22 at 21:32
  • @rr19 Are you using rmarkdown or Quarto? And do you want to add line numbers to code chunks only? – Martin Schmelzer Nov 10 '22 at 22:31
  • @MartinSchmelzer I'm using Rmarkdown (i.e. Rstudio the installed version, not the cloud) and I really want number in all the lines from top to down (similarly to the pic in this post. I don't now what Quarto is.. but it may be related to R coding since you ask. I will have a look at it. It interesting me to hear ne things about coding even thoguh I'm not good at it :) – rr19 Nov 17 '22 at 19:19
  • @MartinSchmelzer Also, to let you know I prefer to knit the markdown to html (because the theme color in html is what I like) and then copy it into a word document as appendix for a report. – rr19 Nov 17 '22 at 19:30
  • @rr19 I edited it. should work now. I think Jquery was removed as a dependency. For Quarto (the successor of RMarkdown) the code is dofferent though. – Martin Schmelzer Nov 18 '22 at 19:04