noamross / redoc

[NOTE: Project in suspended animation for now] Reversible Reproducible Documents
https://noamross.github.io/redoc
Other
514 stars 44 forks source link

Only the first citation gets wrapped #67

Open shirdekel opened 4 years ago

shirdekel commented 4 years ago

Given the following reprex.bib file:

@article{einstein,
    author =       "Albert Einstein",
    title =        "{Zur Elektrodynamik bewegter K{\"o}rper}. ({German})
        [{On} the electrodynamics of moving bodies]",
    journal =      "Annalen der Physik",
    volume =       "322",
    number =       "10",
    pages =        "891--921",
    year =         "1905",
    DOI =          "http://dx.doi.org/10.1002/andp.19053221004"
}

Only the first citation in the following reprex.Rmd is wrapped by redoc:

---
title: Reversible R Markdown Document
subtitle: Your subtitle
author: Your Name
date: Created `r Sys.Date()`
bibliography: reprex.bib
output:
  redoc::redoc:
    highlight_outputs: TRUE
    margins: 1 
    line_numbers: FALSE 
---

@einstein

@einstein

reprex.docx

This is evident after a dedoc:

---
title: Reversible R Markdown Document
subtitle: Your subtitle
author: Your Name
date: Created `r Sys.Date()`
bibliography: reprex.bib
output:
  redoc::redoc:
    highlight_outputs: yes
    margins: 1
    line_numbers: no
---

@einstein

Einstein (1905)

Einstein, Albert. 1905. "Zur Elektrodynamik bewegter Körper. (German) \[on the
Electrodynamics of Moving Bodies\]." *Annalen Der Physik* 322 (10): 891--921.
<https://doi.org/http://dx.doi.org/10.1002/andp.19053221004>.

Session Info ```r ─ Session info ───────────────────────── setting value version R version 3.5.3 (2019-03-11) os macOS Mojave 10.14.6 system x86_64, darwin15.6.0 ui RStudio language (EN) collate en_AU.UTF-8 ctype en_AU.UTF-8 tz Australia/Sydney date 2020-03-26 ``` Pandoc version (get with rmarkdown::pandoc_version): 2.3.1 RStudio version (if applicable): 1.3.300
shirdekel commented 4 years ago

This issue seems to arise from a few lines in wrappers.R. The stri_lineno_first_fixed and stri_replace_first_fixed functions create all the span wraps for a given citation around the first instance of that citation, e.g., if there are three @einstein citations, the output is:

<span class=\"redoc\" id=\"redoc-citation-1\"><span class=\"redoc\" id=\"redoc-citation-2\"><span class=\"redoc\" id=\"redoc-citation-3\">@einstein</span></span></span>

I fixed this for myself by replacing them with the following functions:

match_n <- function(text, pattern){
  pre <- stringr::str_match(text, pattern = paste0('(?s).*?(?<!">)(', Hmisc::escapeRegex(pattern),')(?!\\]|<\\/span>)'))[,1]
  as.integer(stri_count_lines(pre))
}

replace_n <- function(text, pattern, replacement){
  loc <- stringr::str_locate(text, pattern = paste0('(?s)(?<!">)(', Hmisc::escapeRegex(pattern),')(?!\\]|<\\/span>)'))
  stringr::str_sub(text, loc[1], loc[2]) <- replacement
  return(text)
}

and amending the previous code to:

for (i in seq_along(chunks)) {
      chunks[[i]]$lineno <- match_n(text = rmd$text,
                                    pattern = chunks[[i]]$code)
      rmd$text <- replace_n(text = rmd$text,
                            pattern = chunks[[i]]$code,
                            replacement = container_wrapper(
                              chunks[[i]]$code,
                              chunks[[i]]$name))
    }

However, I don't know if this is a perfect fix, because it might be breaking something else.