Skip to content

Commit

Permalink
Merge branch 'main' into add-md-to-node
Browse files Browse the repository at this point in the history
  • Loading branch information
zkamvar authored Oct 17, 2024
2 parents 46974f2 + 2798e86 commit 6fff395
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 44 deletions.
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: tinkr
Title: Cast '(R)Markdown' Files to 'XML' and Back Again
Version: 0.2.0.9000
Version: 0.2.0.9001
Authors@R:
c(person(given = "Maëlle",
family = "Salmon",
Expand Down Expand Up @@ -56,5 +56,5 @@ Config/testthat/edition: 3
Encoding: UTF-8
LazyData: true
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.1
RoxygenNote: 7.3.2.9000
VignetteBuilder: knitr
4 changes: 3 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# tinkr 0.2.0.9000
# tinkr 0.2.0.9001

## NEW FEATURES

Expand Down Expand Up @@ -40,6 +40,8 @@
#96, fix: #111, @zkamvar)
* Documents with no trailing newline will no longer throw a warning (issue: #65;
fix: #114, @zkamvar)
* Documents with dollar signs but no math will no longer fail with the
`$protect_math()` method (issue: #121, @maelle; fix: #122, @zkamvar).

## MISC

Expand Down
7 changes: 6 additions & 1 deletion R/asis-nodes.R
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ protect_inline_math <- function(body, ns) {
# an error.
le <- length(bmath[endless])
lh <- length(bmath[headless])
# 2024-10-10: if the number of headless tags is zero, then we are dealing
# with currency. See issue #121
if (lh == 0) {
return(copy_xml(body))
}
if (le != lh) {
unbalanced_math_error(bmath, endless, headless, le, lh)
}
Expand Down Expand Up @@ -415,7 +420,7 @@ find_escaped_squares <- function(txt) {
#'
#' Knowing this, we can process each node by its line number and wrap all
#' unescpaed square braces in text nodes with the `@asis` attribute, which is
#' performed with the [fix_unescaped()] function.
#' performed with the fix_unescaped() function.
#'
#' @return nothing, invisibly. This function is called for its side-effect.
#' @noRd
Expand Down
121 changes: 83 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.re
status](https://github.com/ropensci/tinkr/workflows/R-CMD-check/badge.svg)](https://github.com/ropensci/tinkr/actions)
[![Coverage
status](https://codecov.io/gh/ropensci/tinkr/branch/master/graph/badge.svg)](https://codecov.io/github/ropensci/tinkr?branch=master)
[![R-CMD-check](https://github.com/ropensci/tinkr/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/ropensci/tinkr/actions/workflows/R-CMD-check.yaml)
[![Codecov test
coverage](https://codecov.io/gh/ropensci/tinkr/branch/main/graph/badge.svg)](https://app.codecov.io/gh/ropensci/tinkr?branch=main)
<!-- badges: end -->

The goal of tinkr is to convert (R)Markdown files to XML and back to
Expand All @@ -23,16 +26,16 @@ regular expressions. If these words mean nothing to you, see our list of

Possible applications are R scripts using tinkr, and XPath via xml2 to:

- change levels of headers, cf [our `roweb2_headers.R`
script](https://github.com/ropensci/tinkr/blob/main/inst/scripts/roweb2_headers.R)
and [pull request \#279 to
roweb2](https://github.com/ropensci-archive/roweb2/pull/279);
- change chunk labels and options;
- extract all runnable code (including inline code);
- insert arbitrary Markdown elements;
- modify link URLs;
- your idea, please [report use
cases](https://discuss.ropensci.org/c/usecases/10)!
- change levels of headers, cf [our `roweb2_headers.R`
script](https://github.com/ropensci/tinkr/blob/main/inst/scripts/roweb2_headers.R)
and [pull request \#279 to
roweb2](https://github.com/ropensci-archive/roweb2/pull/279);
- change chunk labels and options;
- extract all runnable code (including inline code);
- insert arbitrary Markdown elements;
- modify link URLs;
- your idea, please [report use
cases](https://discuss.ropensci.org/c/usecases/10)!

## Workflow

Expand Down Expand Up @@ -175,6 +178,9 @@ rmd <- tinkr::yarn$new(path)
xml2::xml_find_first(rmd$body, ".//md:code_block", rmd$ns)
#| {xml_node}
#| <code_block space="preserve" language="r" name="setup" include="FALSE" eval="TRUE">
```

``` r
new_code <- c(
"```{r xml-block, message = TRUE}",
"message(\"this is a new chunk from {tinkr}\")",
Expand Down Expand Up @@ -217,18 +223,18 @@ rmd$head(21)
If you are not closely following one of the examples provided, what
background knowledge do you need before using tinkr?

- That XPath, a language for querying XML & HTML, exists, and [some
basics](https://www.w3schools.com/xml/xpath_intro.asp).
- Basics of how [xml2
works](https://blog.r-hub.io/2020/01/22/mutable-api/#exposing-the-c-api-in-xml2):
how to find, replace, remove nodes etc.
- How to use R6 classes… although reading the examples should help you
get the gist.
- If you are not happy with [our default
stylesheet](#general-principles-and-solution), then understanding
[XSLT](https://ropensci.org/blog/2017/01/10/xslt-release/) will help
you create your own. Refer to this good resource on [XSLT for XML
transformations](https://www.w3schools.com/xml/xsl_intro.asp).
- That XPath, a language for querying XML & HTML, exists, and [some
basics](https://www.w3schools.com/xml/xpath_intro.asp).
- Basics of how [xml2
works](https://blog.r-hub.io/2020/01/22/mutable-api/#exposing-the-c-api-in-xml2):
how to find, replace, remove nodes etc.
- How to use R6 classes… although reading the examples should help you
get the gist.
- If you are not happy with [our default
stylesheet](#general-principles-and-solution), then understanding
[XSLT](https://ropensci.org/blog/2017/01/10/xslt-release/) will help
you create your own. Refer to this good resource on [XSLT for XML
transformations](https://www.w3schools.com/xml/xsl_intro.asp).

## Loss of Markdown style

Expand All @@ -238,21 +244,21 @@ The (R)md to XML to (R)md loop on which `tinkr` is based is slightly
lossy because of Markdown syntax redundancy, so the loop from (R)md to
R(md) via `to_xml` and `to_md` will be a bit lossy. For instance

- lists can be created with either “+”, “-” or “\*“. When using
`tinkr`, the (R)md after editing will only use”-” for lists.
- lists can be created with either “+”, “-” or “\*“. When using `tinkr`,
the (R)md after editing will only use”-” for lists.

- Links built like `[word][smallref]` with a bottom anchor
`[smallref]: URL` will have the anchor moved to the bottom of the
document.
- Links built like `[word][smallref]` with a bottom anchor
`[smallref]: URL` will have the anchor moved to the bottom of the
document.

- Characters are escaped (e.g. “\[” when not for a link).
- Characters are escaped (e.g. “\[” when not for a link).

- [x] GitHub tickboxes are preserved (only for `yarn` objects)
- [x] GitHub tickboxes are preserved (only for `yarn` objects)

- Block quotes lines all get “\>” whereas in the input only the first
could have a “\>” at the beginning of the first line.
- Block quotes lines all get “\>” whereas in the input only the first
could have a “\>” at the beginning of the first line.

- For tables see the next subsection.
- For tables see the next subsection.

Such losses make your (R)md different, and the git diff a bit harder to
parse, but should *not* change the documents your (R)md is rendered to.
Expand All @@ -265,9 +271,9 @@ and provide its filepath as `stylesheet_path` argument to `to_md`.

### The special case of tables

- Tables are supposed to remain/become pretty after a full loop
`to_xml` + `to_md`. If you notice something amiss, e.g. too much
space compared to what you were expecting, please open an issue.
- Tables are supposed to remain/become pretty after a full loop
`to_xml` + `to_md`. If you notice something amiss, e.g. too much space
compared to what you were expecting, please open an issue.

### LaTeX equations

Expand Down Expand Up @@ -311,7 +317,7 @@ Note, however, that there are a few caveats for this:
sure to either use punctuation after the trailing dollar sign OR
format the text as code. (i.e. `` `INKEY$` `` is good, but `INKEY$`
by itself is not good and will be interpreted as LaTeX code,
throwing an error: ::: {.cell}
throwing an error:

``` r
path <- system.file("extdata", "basic-math.md", package = "tinkr")
Expand All @@ -335,7 +341,7 @@ Note, however, that there are a few caveats for this:
#| Error: Inline math delimiters are not balanced.
#|
#| HINT: If you are writing BASIC code, make sure you wrap variable
#| names and code in backtics like so: `INKEY$`.
#| names and code in backtics like so: `INKEY$`.
#|
#| Below are the pairs that were found:
#| start...end
Expand All @@ -345,7 +351,46 @@ Note, however, that there are a few caveats for this:
#| We write $2 but ...
```

:::
4. **use of `$` as currency will still work**, but there is a caveat
that mixing this inline math broken across lines will cause
problems:

``` r
# this will be mal-formed
bad <- "It's 5:45 and I've got $5.45 in my pocket.\nThe __area of a circle__ is $A =\n \\pi r^2$, where\n$\\pi$ is irrational when it hasn't had its coffee."
fails <- tinkr::yarn$new(textConnection(bad))
fails$show()
#| It's 5:45 and I've got $5.45 in my pocket.
#| The **area of a circle** is $A =
#| \\pi r^2$, where
#| $\\pi$ is irrational when it hasn't had its coffee.
fails$
protect_math()$
show()
#| Error: Inline math delimiters are not balanced.
#|
#| HINT: If you are writing BASIC code, make sure you wrap variable
#| names and code in backtics like so: `INKEY$`.
#|
#| Below are the pairs that were found:
#| start...end
#| -----...---
#| It's 5:45 and I've got $5.45 in my pocket....\pi r^2$, where
#| is $A =...
# This works
good <- "It's 5:45 and I've got $5.45 in my pocket.\nThe __area of a circle__ is $A = \\pi r^2$, where\n$\\pi$ is irrational when it hasn't had its coffee."
works <- tinkr::yarn$new(textConnection(good))
works$show()
#| It's 5:45 and I've got $5.45 in my pocket.
#| The **area of a circle** is $A = \\pi r^2$, where
#| $\\pi$ is irrational when it hasn't had its coffee.
works$
protect_math()$
show()
#| It's 5:45 and I've got $5.45 in my pocket.
#| The **area of a circle** is $A = \pi r^2$, where
#| $\pi$ is irrational when it hasn't had its coffee.
```

## Meta

Expand Down
2 changes: 1 addition & 1 deletion man/isolate_nodes.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/provision_isolation.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions man/rmd-fragments/format-latex.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,22 @@ you must be sure to either use punctuation after the trailing dollar sign OR for
math$head(15) # malformed
math$protect_math() #error
```
4. **use of `$` as currency will still work**, but there is a caveat that mixing
this inline math broken across lines will cause problems:
```{r, split, error = TRUE}
# this will be mal-formed
bad <- "It's 5:45 and I've got $5.45 in my pocket.\nThe __area of a circle__ is $A =\n \\pi r^2$, where\n$\\pi$ is irrational when it hasn't had its coffee."
fails <- tinkr::yarn$new(textConnection(bad))
fails$show()
fails$
protect_math()$
show()
# This works
good <- "It's 5:45 and I've got $5.45 in my pocket.\nThe __area of a circle__ is $A = \\pi r^2$, where\n$\\pi$ is irrational when it hasn't had its coffee."
works <- tinkr::yarn$new(textConnection(good))
works$show()
works$
protect_math()$
show()
```
9 changes: 9 additions & 0 deletions tests/testthat/test-asis-nodes.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
test_that("(#121) single dollar lines dont throw errors", {
expected <- "I've only got $2 in the bank. Feels bad, man.\n"
math <- commonmark::markdown_xml(expected)
txt <- xml2::read_xml(math)
expect_no_error(protxt <- protect_inline_math(txt, md_ns()))
actual <- to_md(list(yaml = NULL, body = protxt))
expect_equal(actual, expected)
})

test_that("mal-formed inline math throws an informative error", {
patherr <- system.file("extdata", "basic-math.md", package = "tinkr")
me <- yarn$new(patherr, sourcepos = TRUE)
Expand Down

0 comments on commit 6fff395

Please sign in to comment.