3

When I create an html Rmarkdown that includes a TOC, the links only work as long as the html file is on my drive. As soon as I publish or share it, the links break because they are hardcoded to the document on my drive. Is there a way around this? e.g., having a link with a relative path.

Example:

---
title: "TOC test"
author: "Me"
date: "January 18, 2018"
output: 
  html_document:
    toc: true
    toc_depth: 4
---

###Header1 {#Header1}  
some text here

###Header2 {#Header2}  
some more text here

####Header2b {#Header2b}
and more text here

My link addresses look like this:

file:///C:/Data/PROJECTS/Testing/TOCtest.html#header1

UPDATE:including the Rmd

---
title: "###**Weekly Update**"
author: "#####Author"
date: "#####Report Date: `r Sys.Date()`  "
output: 
  html_document:
    toc: yes
    toc_depth: 5
---

#### **MY FIRST HEADER**  

This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see <http://rmarkdown.rstudio.com>.

##### **MY FIRST SUB-HEADER**  

When you click the **Knit** button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:

```{r cars}
summary(cars)
```

#### **MY SECOND HEADER**  

You can also embed plots, for example:


##### **MY SECOND SUB-HEADER**  

Note that the `echo = FALSE` parameter was added to the code chunk to prevent printing of the R code that generated the plot.

UPDATE: including the html

<!DOCTYPE html>
<!-- saved from url=(0088)file:///C:/Data/PROJECTS/TestLinks.html -->
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="generator" content="pandoc">
<title></title>

<script src="data:application/x-javascript;base64,LyohIGpRdWVyeSB2MS4xMS4zIHwgKGMpIDIwMDUsIDIwMTUgalF1ZXJ5IEZvdW5kYXRpb24sIEluYy4gfCB
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="data:text/css;charset=utf-8,html%7Bfont%2Dfamily%3Asans%2Dserif%3B%2Dwebkit%2Dtext%2Dsize%2Dadjust%3A100%25%3B%2Dms%2Dtex
<script src="data:application/x-javascript;base64,LyohCiAqIEJvb3RzdHJhcCB2My4zLjUgKGh0dHA6Ly9nZXRib290c3RyYXAuY29tKQogKiBDb3B5cmlnaHQ
<script src="data:application/x-javascript;base64,LyoqCiogQHByZXNlcnZlIEhUTUw1IFNoaXYgMy43LjIgfCBAYWZhcmthcyBAamRhbHRvbiBAam9uX25lYWw
<script src="data:application/x-javascript;base64,LyohIFJlc3BvbmQuanMgdjEuNC4yOiBtaW4vbWF4LXdpZHRoIG1lZGlhIHF1ZXJ5IHBvbHlmaWxsICogQ29
<script src="data:application/x-javascript;base64,CgovKioKICogalF1ZXJ5IFBsdWdpbjogU3RpY2t5IFRhYnMKICoKICogQGF1dGhvciBBaWRhbiBMaXN0ZXI
<link href="data:text/css;charset=utf-8,%2Ehljs%2Dliteral%20%7B%0Acolor%3A%20%23990073%3B%0A%7D%0A%2Ehljs%2Dnumber%20%7B%0Acolor%3A%2
<script src="data:application/x-javascript;base64,LyohIGhpZ2hsaWdodC5qcyB2OS4xMi4wIHwgQlNEMyBMaWNlbnNlIHwgZ2l0LmlvL2hsanNsaWNlbnNlICo

<style type="text/css">code{white-space: pre;}</style>
<style type="text/css">
  pre:not([class]) {
    background-color: white;
  }
</style>
<script type="text/javascript">
if (window.hljs) {
  hljs.configure({languages: []});
  hljs.initHighlightingOnLoad();
  if (document.readyState && document.readyState === "complete") {
    window.setTimeout(function() { hljs.initHighlightingOnLoad(); }, 0);
  }
}
</script>
<style type="text/css">
h1 {
  font-size: 34px;
}
h1.title {
  font-size: 38px;
}
h2 {
  font-size: 30px;
}
h3 {
  font-size: 24px;
}
h4 {
  font-size: 18px;
}
h5 {
  font-size: 16px;
}
h6 {
  font-size: 12px;
}
.table th:not([align]) {
  text-align: left;
}
</style>


<script type="text/javascript" src="./TestLinks_files/MathJax.js.download"></script><style type="text/css">.MathJax_Hover_Frame {bord
.MathJax_Menu_Button .MathJax_Hover_Arrow {position: absolute; cursor: pointer; display: inline-block; border: 2px solid #AAA; border
.MathJax_Menu_Button .MathJax_Hover_Arrow span {display: block; background-color: #AAA; border: 1px solid; border-radius: 3px; line-h
.MathJax_Hover_Arrow:hover {color: white!important; border: 2px solid #CCC!important}
.MathJax_Hover_Arrow:hover span {background-color: #CCC!important}
</style><style type="text/css">#MathJax_About {position: fixed; left: 50%; width: auto; text-align: center; border: 3px outset; paddi
#MathJax_About.MathJax_MousePost {outline: none}
.MathJax_Menu {position: absolute; background-color: white; color: black; width: auto; padding: 2px; border: 1px solid #CCCCCC; margi
.MathJax_MenuItem {padding: 2px 2em; background: transparent}
.MathJax_MenuArrow {position: absolute; right: .5em; padding-top: .25em; color: #666666; font-size: .75em}
.MathJax_MenuActive .MathJax_MenuArrow {color: white}
.MathJax_MenuArrow.RTL {left: .5em; right: auto}
.MathJax_MenuCheck {position: absolute; left: .7em}
.MathJax_MenuCheck.RTL {right: .7em; left: auto}
.MathJax_MenuRadioCheck {position: absolute; left: 1em}
.MathJax_MenuRadioCheck.RTL {right: 1em; left: auto}
.MathJax_MenuLabel {padding: 2px 2em 4px 1.33em; font-style: italic}
.MathJax_MenuRule {border-top: 1px solid #CCCCCC; margin: 4px 1px 0px}
.MathJax_MenuDisabled {color: GrayText}
.MathJax_MenuActive {background-color: Highlight; color: HighlightText}
.MathJax_MenuDisabled:focus, .MathJax_MenuLabel:focus {background-color: #E8E8E8}
.MathJax_ContextMenu:focus {outline: none}
.MathJax_ContextMenu .MathJax_MenuItem:focus {outline: none}
#MathJax_AboutClose {top: .2em; right: .2em}
.MathJax_Menu .MathJax_MenuClose {top: -10px; left: -10px}
.MathJax_MenuClose {position: absolute; cursor: pointer; display: inline-block; border: 2px solid #AAA; border-radius: 18px; -webkit-
.MathJax_MenuClose span {display: block; background-color: #AAA; border: 1.5px solid; border-radius: 18px; -webkit-border-radius: 18p
.MathJax_MenuClose:hover {color: white!important; border: 2px solid #CCC!important}
.MathJax_MenuClose:hover span {background-color: #CCC!important}
.MathJax_MenuClose:hover:focus {outline: none}
</style><style type="text/css">.MathJax_Preview .MJXf-math {color: inherit!important}
</style><style type="text/css">.MJX_Assistive_MathML {position: absolute!important; top: 0; left: 0; clip: rect(1px, 1px, 1px, 1px); 
.MJX_Assistive_MathML.MJX_Assistive_MathML_Block {width: 100%!important}
</style><style type="text/css">#MathJax_Zoom {position: absolute; background-color: #F0F0F0; overflow: auto; display: block; z-index:
#MathJax_ZoomOverlay {position: absolute; left: 0; top: 0; z-index: 300; display: inline-block; width: 100%; height: 100%; border: 0;
#MathJax_ZoomFrame {position: relative; display: inline-block; height: 0; width: 0}
#MathJax_ZoomEventTrap {position: absolute; left: 0; top: 0; z-index: 302; display: inline-block; border: 0; padding: 0; margin: 0; b
</style><style type="text/css">.MathJax_Preview {color: #888}
#MathJax_Message {position: fixed; left: 1em; bottom: 1.5em; background-color: #E6E6E6; border: 1px solid #959595; margin: 0px; paddi
#MathJax_MSIE_Frame {position: absolute; top: 0; left: 0; width: 0px; z-index: 101; border: 0px; margin: 0px; padding: 0px}
.MathJax_Error {color: #CC0000; font-style: italic}
</style><style type="text/css">.MJXp-script {font-size: .8em}
.MJXp-right {-webkit-transform-origin: right; -moz-transform-origin: right; -ms-transform-origin: right; -o-transform-origin: right; 
.MJXp-bold {font-weight: bold}
.MJXp-italic {font-style: italic}
.MJXp-scr {font-family: MathJax_Script,'Times New Roman',Times,STIXGeneral,serif}
.MJXp-frak {font-family: MathJax_Fraktur,'Times New Roman',Times,STIXGeneral,serif}
.MJXp-sf {font-family: MathJax_SansSerif,'Times New Roman',Times,STIXGeneral,serif}
.MJXp-cal {font-family: MathJax_Caligraphic,'Times New Roman',Times,STIXGeneral,serif}
.MJXp-mono {font-family: MathJax_Typewriter,'Times New Roman',Times,STIXGeneral,serif}
.MJXp-largeop {font-size: 150%}
.MJXp-largeop.MJXp-int {vertical-align: -.2em}
.MJXp-math {display: inline-block; line-height: 1.2; text-indent: 0; font-family: 'Times New Roman',Times,STIXGeneral,serif; white-sp
.MJXp-display {display: block; text-align: center; margin: 1em 0}
.MJXp-math span {display: inline-block}
.MJXp-box {display: block!important; text-align: center}
.MJXp-box:after {content: " "}
.MJXp-rule {display: block!important; margin-top: .1em}
.MJXp-char {display: block!important}
.MJXp-mo {margin: 0 .15em}
.MJXp-mfrac {margin: 0 .125em; vertical-align: .25em}
.MJXp-denom {display: inline-table!important; width: 100%}
.MJXp-denom > * {display: table-row!important}
.MJXp-surd {vertical-align: top}
.MJXp-surd > * {display: block!important}
.MJXp-script-box > *  {display: table!important; height: 50%}
.MJXp-script-box > * > * {display: table-cell!important; vertical-align: top}
.MJXp-script-box > *:last-child > * {vertical-align: bottom}
.MJXp-script-box > * > * > * {display: block!important}
.MJXp-mphantom {visibility: hidden}
.MJXp-munderover {display: inline-table!important}
.MJXp-over {display: inline-block!important; text-align: center}
.MJXp-over > * {display: block!important}
.MJXp-munderover > * {display: table-row!important}
.MJXp-mtable {vertical-align: .25em; margin: 0 .125em}
.MJXp-mtable > * {display: inline-table!important; vertical-align: middle}
.MJXp-mtr {display: table-row!important}
.MJXp-mtd {display: table-cell!important; text-align: center; padding: .5em 0 0 .5em}
.MJXp-mtr > .MJXp-mtd:first-child {padding-left: 0}
.MJXp-mtr:first-child > .MJXp-mtd {padding-top: 0}
.MJXp-mlabeledtr {display: table-row!important}
.MJXp-mlabeledtr > .MJXp-mtd:first-child {padding-left: 0}
.MJXp-mlabeledtr:first-child > .MJXp-mtd {padding-top: 0}
.MJXp-merror {background-color: #FFFF88; color: #CC0000; border: 1px solid #CC0000; padding: 1px 3px; font-style: normal; font-size: 
.MJXp-scale0 {-webkit-transform: scaleX(.0); -moz-transform: scaleX(.0); -ms-transform: scaleX(.0); -o-transform: scaleX(.0); transfo
.MJXp-scale1 {-webkit-transform: scaleX(.1); -moz-transform: scaleX(.1); -ms-transform: scaleX(.1); -o-transform: scaleX(.1); transfo
.MJXp-scale2 {-webkit-transform: scaleX(.2); -moz-transform: scaleX(.2); -ms-transform: scaleX(.2); -o-transform: scaleX(.2); transfo
.MJXp-scale3 {-webkit-transform: scaleX(.3); -moz-transform: scaleX(.3); -ms-transform: scaleX(.3); -o-transform: scaleX(.3); transfo
.MJXp-scale4 {-webkit-transform: scaleX(.4); -moz-transform: scaleX(.4); -ms-transform: scaleX(.4); -o-transform: scaleX(.4); transfo
.MJXp-scale5 {-webkit-transform: scaleX(.5); -moz-transform: scaleX(.5); -ms-transform: scaleX(.5); -o-transform: scaleX(.5); transfo
.MJXp-scale6 {-webkit-transform: scaleX(.6); -moz-transform: scaleX(.6); -ms-transform: scaleX(.6); -o-transform: scaleX(.6); transfo
.MJXp-scale7 {-webkit-transform: scaleX(.7); -moz-transform: scaleX(.7); -ms-transform: scaleX(.7); -o-transform: scaleX(.7); transfo
.MJXp-scale8 {-webkit-transform: scaleX(.8); -moz-transform: scaleX(.8); -ms-transform: scaleX(.8); -o-transform: scaleX(.8); transfo
.MJXp-scale9 {-webkit-transform: scaleX(.9); -moz-transform: scaleX(.9); -ms-transform: scaleX(.9); -o-transform: scaleX(.9); transfo
.MathJax_PHTML .noError {vertical-align: ; font-size: 90%; text-align: left; color: black; padding: 1px 3px; border: 1px solid}
</style></head>

<body><div id="MathJax_Message" style="display: none;"></div>

<style type="text/css">
.main-container {
  max-width: 940px;
  margin-left: auto;
  margin-right: auto;
}
code {
  color: inherit;
  background-color: rgba(0, 0, 0, 0.04);
}
img {
  max-width:100%;
  height: auto;
}
.tabbed-pane {
  padding-top: 12px;
}
button.code-folding-btn:focus {
  outline: none;
}
</style>



<div class="container-fluid main-container">

<!-- tabsets -->
<script>
$(document).ready(function () {
  window.buildTabsets("TOC");
});
</script>

<!-- code folding -->
<div class="fluid-row" id="header">
<h1 class="title toc-ignore"></h1><h3 id="weekly-update"><strong>Weekly Update</strong></h3>
<h4 class="author"><em><h5 id="author">Author</h5></em></h4>
<h4 class="date"><em><h5 id="report-date-2018-02-02">Report Date: 2018-02-02</h5></em></h4>

</div>

<div id="TOC">
<ul>
<li><a href="file:///C:/Data/PROJECTS/TestLinks.html#my-first-header"><strong>MY FIR
<li><a href="file:///C:/Data/PROJECTS/TestLinks.html#my-first-sub-header"><strong>MY
</ul></li>
<li><a href="file:///C:/Data/PROJECTS/TestLinks.html#my-second-header"><strong>MY SE
<li><a href="file:///C:/Data/PROJECTS/TestLinks.html#my-second-sub-header"><strong>M
</ul></li>
</ul>
</div>

<div id="my-first-header" class="section level4">
<h4><strong>MY FIRST HEADER</strong></h4>
<p>This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more de
<div id="my-first-sub-header" class="section level5">
<h5><strong>MY FIRST SUB-HEADER</strong></h5>
<p>When you click the <strong>Knit</strong> button a document will be generated that includes both content as well as the output of a
<pre class="r"><code class="hljs">summary(cars)</code></pre>
<pre><code class="hljs">##      speed           dist       
##  Min.   : 4.0   Min.   :  2.00  
##  1st Qu.:12.0   1st Qu.: 26.00  
##  Median :15.0   Median : 36.00  
##  Mean   :15.4   Mean   : 42.98  
##  3rd Qu.:19.0   3rd Qu.: 56.00  
##  Max.   :25.0   Max.   :120.00</code></pre>
</div>
</div>
<div id="my-second-header" class="section level4">
<h4><strong>MY SECOND HEADER</strong></h4>
<p>You can also embed plots, for example:</p>
<div id="my-second-sub-header" class="section level5">
<h5><strong>MY SECOND SUB-HEADER</strong></h5>
<p>Note that the <code>echo = FALSE</code> parameter was added to the code chunk to prevent printing of the R code that generated the
</div>
</div>

</div>

<script>

// add bootstrap table styles to pandoc tables
function bootstrapStylePandocTables() {
  $('tr.header').parent('thead').parent('table').addClass('table table-condensed');
}
$(document).ready(function () {
  bootstrapStylePandocTables();
});


</script>

<!-- dynamically load mathjax for compatibility with self-contained -->
<script>
  (function () {
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src  = "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
    document.getElementsByTagName("head")[0].appendChild(script);
  })();
</script>



</body></html>

UPDATE: sessionInfo()

> sessionInfo()
R version 3.4.0 (2017-04-21)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)

Matrix products: default

locale:
[1] LC_COLLATE=English_Canada.1252  LC_CTYPE=English_Canada.1252    LC_MONETARY=English_Canada.1252
[4] LC_NUMERIC=C                    LC_TIME=English_Canada.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
 [1] ggrepel_0.6.5    Rcpp_0.12.14     rprojroot_1.2    digest_0.6.12    grid_3.4.0       plyr_1.8.4       backports_1.1.1 
 [8] gtable_0.2.0     magrittr_1.5     evaluate_0.10.1  scales_0.5.0     ggplot2_2.2.1    stringi_1.1.6    rlang_0.1.4     
[15] lazyeval_0.2.1   rmarkdown_1.7    tools_3.4.0      stringr_1.2.0    munsell_0.4.3    rsconnect_0.8.5  yaml_2.1.14     
[22] compiler_3.4.0   colorspace_1.3-2 htmltools_0.3.6  knitr_1.17       tibble_1.3.4    
val
  • 1,629
  • 1
  • 30
  • 56
  • Your `sessionInfo()` results show that you are using an older version of R and some key packages, such as `rmarkdown` and `knitr`. Can you please try rendering your `.Rmd` in a clean and updated environment? I believe your problem is something local. – Kevin Arseneau Feb 05 '18 at 04:47
  • @KevinArseneau: yes, smg local just not sure what. started everything in new project with updated R, knitr and rmarkdown, but same issue. – val Feb 05 '18 at 06:56

1 Answers1

1

I was going to write this as a comment initially but then decided to answer because of length and that this understanding of HTML output from R markdown could be helpful for other users.

Firstly, the TOC links are already relative and not hardcoded as you say. If you look at the source of your output document after rmarkdown::render("example.Rmd"), you will see...

example.Rmd

---
title: "###**Weekly Update**"
author: "#####Author"
date: "#####Report Date: `r Sys.Date()`  "
output: 
  html_document:
    toc: yes
    toc_depth: 5
---

#### **MY FIRST HEADER**  

This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see <http://rmarkdown.rstudio.com>.

##### **MY FIRST SUB-HEADER**  

When you click the **Knit** button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:

```{r cars}
summary(cars)
```

#### **MY SECOND HEADER**  

You can also embed plots, for example:


##### **MY SECOND SUB-HEADER**  

Note that the `echo = FALSE` parameter was added to the code chunk to prevent printing of the R code that generated the plot.

example.html

<div class="fluid-row" id="header">

<h1 class="title toc-ignore"><h3 id="weekly-update"><strong>Weekly Update</strong></h3></h1>
<h4 class="author"><em><h5 id="author">Author</h5></em></h4>
<h4 class="date"><em><h5 id="report-date-2018-02-03">Report Date: 2018-02-03</h5></em></h4>

</div>

<div id="TOC">
<ul>
<li><a href="#my-first-header"><strong>MY FIRST HEADER</strong></a><ul>
<li><a href="#my-first-sub-header"><strong>MY FIRST SUB-HEADER</strong></a></li>
</ul></li>
<li><a href="#my-second-header"><strong>MY SECOND HEADER</strong></a><ul>
<li><a href="#my-second-sub-header"><strong>MY SECOND SUB-HEADER</strong></a></li>
</ul></li>
</ul>
</div>

<div id="my-first-header" class="section level4">
<h4><strong>MY FIRST HEADER</strong></h4>
<p>This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see <a href="http://rmarkdown.rstudio.com" class="uri">http://rmarkdown.rstudio.com</a>.</p>
<div id="my-first-sub-header" class="section level5">
<h5><strong>MY FIRST SUB-HEADER</strong></h5>
<p>When you click the <strong>Knit</strong> button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:</p>
<pre class="r"><code>summary(cars)</code></pre>
<pre><code>##      speed           dist       
##  Min.   : 4.0   Min.   :  2.00  
##  1st Qu.:12.0   1st Qu.: 26.00  
##  Median :15.0   Median : 36.00  
##  Mean   :15.4   Mean   : 42.98  
##  3rd Qu.:19.0   3rd Qu.: 56.00  
##  Max.   :25.0   Max.   :120.00</code></pre>
</div>
</div>
<div id="my-second-header" class="section level4">
<h4><strong>MY SECOND HEADER</strong></h4>
<p>You can also embed plots, for example:</p>
<div id="my-second-sub-header" class="section level5">
<h5><strong>MY SECOND SUB-HEADER</strong></h5>
<p>Note that the <code>echo = FALSE</code> parameter was added to the code chunk to prevent printing of the R code that generated the plot.</p>
</div>
</div>




</div>

In your links, the href values are pointing to the section id. From your browser, the path will be the location to the file with the section as a suffix.

i.e. protocol://path/to/file/example.html#section

I cannot reproduce what you are generating, please add the output of sessionInfo() to your question and lets have a look.

Kevin Arseneau
  • 6,186
  • 1
  • 21
  • 40
  • @KevinArsenau: I did as you suggested using rmarkdown::render("my file.Rmd"). It generates and html but the TOC links are still "hardcoded" to my local drive. They look like this: file:///C:/Data/PROJECTS/myfile.html#intro so I'm confused. When I share this file the links don't work. – val Feb 02 '18 at 11:46
  • 1
    @val, did you examine the html file? Post the contents of the output as I did in my answer – Kevin Arseneau Feb 02 '18 at 11:48
  • @KevinArsenau: I have included the html. you'll note that my hrefs are still hardcoded to my drive: href="file:///C:/Data/PROJECTS/TestLinks.html#my-first-header"> I don't understand why. – val Feb 02 '18 at 20:34
  • 1
    @val, thank you, could you please edit your rmarkdown to include a space between your section headers, like this `### Header 1 {#header 1}`? – Kevin Arseneau Feb 02 '18 at 20:38
  • @KevinArsenau: OK, i did that but i get the same issue. I've included the Rmd in the question this time. – val Feb 02 '18 at 20:49
  • @val, I can't replicate your problem, I'll edit my solution with your new information. Could you please post your `sessionInfo()` – Kevin Arseneau Feb 03 '18 at 01:50
  • @KevinArsenau: Thank you for persisting. session info added to bottom of question. – val Feb 05 '18 at 02:56