繁体   English   中英

在knitr HTML output中,包含R Z2182A74BAB7188D959E795D3的行号

[英]In knitr HTML output, include line numbers of R Markdown source code?

Question: Is there an automatic way to add the line numbers of the original R Markdown source code to the formatted code portions of the HTML output produced by knitr?

Purpose: My ultimate goal is to be able to quickly move to parts of my source R Markdown code that I identify need editing while reviewing the HTML output. 使用行号是我知道的最快的方法,但我欢迎听到其他人的策略。

我尝试过的解决方案:

  • 尽管块选项attr.source = '.numberLines'将有吸引力地将行号添加到 HTML output 的代码部分,但该选项不会自动提供源代码行号(您必须手动强制使用.startFrom ) - - 相反,这些行在每个块的开头和每块 output 之后重新编号。 在下图中,我包含.startFrom以强制行编号从 10 开始,以匹配test_data <- rnorm(10)的行号,这是我想要查看的行号。 然而,一个实际的解决方案需要起始编号是自动的。 此外,在 HTML output(显示在代码下方)中, hist(test_data)行从相同的起始编号 10 开始重新编号。我希望它是 12,就像在源代码中一样。 示例源 R Markdown 的屏幕截图,显示行号 编织后输出HTML
  • 这个问题( 如何在 Rmarkdown 中跨块添加 go 的行号? )是相关的,但是 OP 只需要每行的任何唯一标识符,不一定是源代码的行号,解决方案是与源代码行号。

考虑的选项:我已经考虑通过运行一个初始脚本来预处理我的代码,该脚本将在行尾添加行号作为注释,但我更喜欢包含在主 knitr 文件中的解决方案。

更新

此版本使用您将在 RStudio 的源代码窗格中看到的行号。 您必须使用 RStudio 才能工作。 需要对 RMD 进行以下更改:

  • library(jsonlite)library(dplyr)
  • 一个 R 块,您可以将其标记为包含和回显为 false
  • 该块之外和之后的一组脚本标签
  • 一个 JS 块(根据我的原始答案修改)

R 块和 R 脚本需要放在 RMD 的末尾。 JS 块可以放在任何地方。

R 块和脚本标签**按顺序排列!

把我放在 RMD 的末尾。

```{r ignoreMe,include=F,echo=F}

# get all lines of RMD into object for numbering; R => JS object 
cx <- rstudioapi::getSourceEditorContext()$contents
cxt <- data.frame(rws = cx, id = 1:length(cx)) %>% toJSON()

```

<script id='dat'>`r cxt`</script>

JS 块

这将收集您在 R 块中创建的 R object,但其位置无关紧要。 所有 R 代码都将在此之前执行,无论您将其放在 RMD 中的哪个位置。

```{r gimme,engine="js",results="as-is",echo=F}

setTimeout(function(){
  scrCx = document.querySelector("#dat"); // call R created JSON*
  cxt = JSON.parse(scrCx.innerHTML);
  echoes = document.querySelectorAll('pre > code'); // capture echoes to #
  j = 0;
  for(i=0; i < echoes.length; i++){ // for each chunk
    txt = echoes[i].innerText;
    ix = finder(txt, cxt, j);  // call finder, which calls looker
    stxt = txt.replace(/^/gm, () => `${ix++} `); // for each line
    echoes[i].innerText = stxt;          // replace with numbered lines
    j = ix; // all indices should be bigger than previous numbering
  }
}, 300)

function looker(str) {  //get the first string in chunk echo
  k = 0;
  ind = str.indexOf("\n");
  sret = str.substring(0, ind);
  oind = ind; // start where left off
  while(sret === null || sret === "" || sret === " "){
    nInd = str.indexOf("\n", oind + 1);       // loop if string is blank!
    sret = str.substring(oind + 1, nInd);
    k++;
    ind = oind;
    oind = nInd;
  }
  return {sret, k};  // return string AND how many rows were blank/offset
}

function finder(txt, jstr, j) {
  txsp = looker(txt);
  xi = jstr.findIndex(function(item, j){ // search JSON match
    return item.rws === txsp.sret;       // search after last index
  })
  xx = xi - txsp.k + 1; // minus # of blank lines; add 1 (JS starts at 0)
  return xx;
}

```

如果要验证行号,可以使用 object cx ,例如cx[102]应该与 HTML 中的 102 和源窗格中的 102 匹配。

我添加了注释,以便您能够理解代码的用途。 但是,如果有不清楚的地方,请告诉我。

在此处输入图像描述

原来的

我认为您正在寻找的是每行回声的行号,不一定是其他任何东西。 如果是这种情况,请将其添加到您的 RMD。 如果有任何您不想编号的块,请添加块选项include=F 代码仍在运行,但不会显示 output 中的内容。 您可能希望将该块选项添加到此 JS 块中。

```{r gimme,engine="js",results="as-is"}

setTimeout(function(){
  // number all lines that reflect echoes
  echoes = document.querySelectorAll('pre > code');
  j = 1;
  for(i=0; i < echoes.length; i++){ // for each chunk
    txt = echoes[i].innerText.replace(/^/gm, () => `${j++} `); // for each line
    echoes[i].innerText = txt;          // replace with numbered lines
  }
}, 300)


```

你把它放在哪里都没有关系(最后,开始)。 如果你尝试内联运行它,你将不会从这个块中得到任何东西。 你必须编织它才能工作。

我组装了一些任意代码来用这个块编号。

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM