From c3be50ec6d2cbef983d68dbab16cde8c91a1c7a8 Mon Sep 17 00:00:00 2001 From: Yihui Xie Date: Thu, 10 Oct 2024 22:30:27 -0500 Subject: [PATCH 1/3] use \footnotetext and \footnotemark to implement LaTeX footnotes --- src/cmark/latex.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/cmark/latex.c b/src/cmark/latex.c index 1a6367a..5fab7ee 100644 --- a/src/cmark/latex.c +++ b/src/cmark/latex.c @@ -447,8 +447,20 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node, break; case CMARK_NODE_FOOTNOTE_DEFINITION: + if (entering) { + LIT("\\footnotetext["); + OUT(cmark_chunk_to_cstr(renderer->mem, &node->as.literal), false, LITERAL); + LIT("]{"); + } else { + LIT("}"); + } + break; case CMARK_NODE_FOOTNOTE_REFERENCE: - // TODO + if (entering) { + LIT("\\footnotemark["); + OUT(cmark_chunk_to_cstr(renderer->mem, &node->parent_footnote_def->as.literal), false, LITERAL); + LIT("]"); + } break; default: From 3c4600eaf6a55bbd35837d6c38d49699f9b777fd Mon Sep 17 00:00:00 2001 From: Yihui Xie Date: Fri, 11 Oct 2024 10:32:32 -0500 Subject: [PATCH 2/3] git diff be62b2b26a06e0143144a444740f86491e4413ce c3be50ec6d2cbef983d68dbab16cde8c91a1c7a8 > src/patches/latex-footnotes.diff --- src/patches/apply.sh | 3 ++- src/patches/latex-footnotes.diff | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 src/patches/latex-footnotes.diff diff --git a/src/patches/apply.sh b/src/patches/apply.sh index 9af4f82..20f2127 100755 --- a/src/patches/apply.sh +++ b/src/patches/apply.sh @@ -2,4 +2,5 @@ # Upstream PR: https://github.com/github/cmark-gfm/pull/362 patch -p2 -d ../cmark < 362.diff - +# Support footnotes for LaTeX: https://github.com/r-lib/commonmark/pull/32 +patch -p2 -d ../cmark < latex-footnotes.diff diff --git a/src/patches/latex-footnotes.diff b/src/patches/latex-footnotes.diff new file mode 100644 index 0000000..3aa71e0 --- /dev/null +++ b/src/patches/latex-footnotes.diff @@ -0,0 +1,26 @@ +diff --git a/src/cmark/latex.c b/src/cmark/latex.c +index 1a6367a..5fab7ee 100644 +--- a/src/cmark/latex.c ++++ b/src/cmark/latex.c +@@ -447,8 +447,20 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node, + break; + + case CMARK_NODE_FOOTNOTE_DEFINITION: ++ if (entering) { ++ LIT("\\footnotetext["); ++ OUT(cmark_chunk_to_cstr(renderer->mem, &node->as.literal), false, LITERAL); ++ LIT("]{"); ++ } else { ++ LIT("}"); ++ } ++ break; + case CMARK_NODE_FOOTNOTE_REFERENCE: +- // TODO ++ if (entering) { ++ LIT("\\footnotemark["); ++ OUT(cmark_chunk_to_cstr(renderer->mem, &node->parent_footnote_def->as.literal), false, LITERAL); ++ LIT("]"); ++ } + break; + + default: From d6ac5b093b4a6e875db54426cbc2a6d20ad8ec26 Mon Sep 17 00:00:00 2001 From: Yihui Xie Date: Fri, 11 Oct 2024 10:47:49 -0500 Subject: [PATCH 3/3] add tests, news, and bump version --- DESCRIPTION | 2 +- NEWS | 3 ++- tests/testthat/test-extensions.R | 12 ++++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index c16582c..8718e30 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: commonmark Type: Package Title: High Performance CommonMark and Github Markdown Rendering in R -Version: 1.9.3 +Version: 1.9.4 Authors@R: c( person("Jeroen", "Ooms", ,"jeroenooms@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-4035-0289")), diff --git a/NEWS b/NEWS index 59be9da..073c2fe 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,6 @@ -1.9.3 +1.9.4 - Apply upstream PR https://github.com/github/cmark-gfm/pull/362 + - Implement LaTeX footnotes (#32) 1.9.1 - Update libcmark-gfm to 0.29.0.gfm.13 diff --git a/tests/testthat/test-extensions.R b/tests/testthat/test-extensions.R index fa922fe..49cc4f2 100644 --- a/tests/testthat/test-extensions.R +++ b/tests/testthat/test-extensions.R @@ -42,6 +42,18 @@ test_that("autolink", { }) +test_that("footnotes", { + # a single footnote + md <- "Hello[^1]\n\n[^1]: A footnote." + expect_equal(markdown_latex(md, footnotes = FALSE), "Hello{[}\\^{}1{]}\n\n{[}\\^{}1{]}: A footnote.\n") + expect_equal(markdown_latex(md, footnotes = TRUE), "Hello\\footnotemark[1]\n\n\\footnotetext[1]{A footnote.\n\n}\n") + + # multiple footnotes + md <- "Hello[^1] World[^foo-2]\n\n[^1]: A footnote.\n\n[^foo-2]: Footnote ID does not have to be a number." + expect_equal(markdown_latex(md, footnotes = FALSE), "Hello{[}\\^{}1{]} World{[}\\^{}foo-2{]}\n\n{[}\\^{}1{]}: A footnote.\n\n{[}\\^{}foo-2{]}: Footnote ID does not have to be a number.\n") + expect_equal(markdown_latex(md, footnotes = TRUE), "Hello\\footnotemark[1] World\\footnotemark[foo-2]\n\n\\footnotetext[1]{A footnote.\n\n}\\footnotetext[foo-2]{Footnote ID does not have to be a number.\n\n}\n") +}) + test_that("embedded images do not get filtered", { md <- '\n' expect_equal(md, markdown_html(md))