Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Line break in Markdown link text deletes whitespace between words #628

Closed
jennybc opened this issue May 9, 2017 · 2 comments
Closed

Line break in Markdown link text deletes whitespace between words #628

jennybc opened this issue May 9, 2017 · 2 comments
Labels
bug an unexpected problem or unintended behavior markdown ⬇️

Comments

@jennybc
Copy link
Member

jennybc commented May 9, 2017

If line wrapping causes a line break in the text of a Markdown link, the associated space between words goes missing. This does not happen with Rd syntax.

Example of the roxygen comment:

#' Generate a request for the Sheets v4 API
#'
#' Generate a request, using some knowledge of the [Sheets v4
#' API](https://developers.google.com/sheets/api/reference/rest/). Blah blah
#' \href{https://developers.google.com/sheets/api/reference/rest/}{Sheets v4
#' API} Most users should, instead, use higher-level wrappers that facilitate
#' common tasks, such as reading the contents of a sheet. The functions here are
#' intended for internal use and for programming around the Sheets API.

Screenshot of the help. Note "Sheets v4API" (no space, from Markdown) versus "Sheets v4 API" (with space, from Rd), despite a line break falling in exactly the same place.

screen shot 2017-05-09 at 3 01 13 pm

@egnha
Copy link
Contributor

egnha commented May 16, 2017

Here's a somewhat shorter demonstration of the problem:

roc_proc_text(rd_roclet(), "
  #' Title
  #'
  #' Link text [broken
  #' across lines](url) doesn't preserve whitespace.
  #' @md
  foo <- function() {}")[[1]]

gives

% Generated by roxygen2: do not edit by hand
% Please edit documentation in Rtmpp2fxtt/fileb6077549a9
\name{foo}
\alias{foo}
\title{Title}
\usage{
foo()
}
\description{
Link text \href{url}{brokenacross lines} doesn't preserve
whitespace.
}

@egnha
Copy link
Contributor

egnha commented May 16, 2017

@jennybc Here's a little patch to markdown.R, which I think resolves the issue.

The problem

Unpacking the (internal) function markdown(), it looks like the culprit is the call xml_text(xml) in the link method in markdown_tags:

invisible(markdown_on(TRUE))
markdown("[broken\nacross lines](URL)", markdown_tags)
#> [1] "\\href{URL}{brokenacross lines}"

markdown() produces the final link text by calling

xml2::xml_text(xml)
#> [1] "brokenacross lines"

where xml has the following value:

x <-
'<?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE document SYSTEM "CommonMark.dtd">
 <document xmlns="http://commonmark.org/xml/1.0">
   <paragraph>
     <link destination="URL" title="">
       <text>broken</text>
       <softbreak />
       <text>across lines</text>
     </link>
   </paragraph>
 </document>'

# Unwinding the call markdown("[broken\nacross lines](URL)", markdown_tags) ...
xml <- with(markdown_tags,
            paragraph(document(xml2::read_xml(x))[[1]])[[2]])

The problem seems to be that xml encodes the newline as a softbreak:

xml2::xml_contents(xml)
#> {xml_nodeset (3)}
#> [1] <text>broken</text>
#> [2] <softbreak/>
#> [3] <text>across lines</text>

whereas xml2::xml_text(xml) interprets the softbreak as an empty string:

xml2::xml_text(xml2::xml_contents(xml))
#> [1] "broken"       ""             "across lines"

The patch

I don't see a way to get xml2::xml_text() to treat the softbreak as a space; I didn't find any parameters that would invoke such behavior. So here is a rudimentary workaround:

  1. Define a function to interpret softbreaks as spaces:
    xml_link_text <- function(xml) {
      cts <- xml2::xml_contents(xml)
      text <- xml2::xml_text(cts)
      text[xml2::xml_name(cts) == c("linebreak", "softbreak")] <- " "
      text
    }
  2. Replace the final else-clause in the method markdown_tags$link by the line
    list("\\href{", dest, "}{", xml_link_text(xml), "}")

The corrected Rd output

With this modification, we get

markdown("[broken\nacross lines](URL)", markdown_tags)
#> [1] "\\href{URL}{broken across lines}"

The roxygen block

roc_proc_text(rd_roclet(), "
  #' Title
  #'
  #' Link text [broken
  #' across lines](url) preserve whitespace.
  #' @md
  foo <- function() {}")[[1]]

now gives

% Generated by roxygen2: do not edit by hand
% Please edit documentation in RtmpIIl60i/file698e6ecd627f
\name{foo}
\alias{foo}
\title{Title}
\usage{
foo()
}
\description{
Link text \href{url}{broken across lines} preserve
whitespace.
}

which matches your expectation.

(I haven't yet tested whether the patch is robust. But at least it doesn't break existing tests.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug an unexpected problem or unintended behavior markdown ⬇️
Projects
None yet
Development

No branches or pull requests

3 participants