From e340fa9106b26e4c5f22ad8446683c71e1eef3de Mon Sep 17 00:00:00 2001 From: Joe Zhu Date: Tue, 15 Sep 2026 00:11:53 +0800 Subject: [PATCH 1/4] change version [skip vbump] --- DESCRIPTION | 2 +- NEWS.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 43544da59..4a58f7983 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: formatters Title: ASCII Formatting for Values and Tables -Version: 0.5.12.9003 +Version: 0.5.13 Date: 2026-05-21 Authors@R: c( person("Gabriel", "Becker", , "gabembecker@gmail.com", role = "aut", diff --git a/NEWS.md b/NEWS.md index 3119d0248..a8e1ce59d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -## formatters 0.5.12.9003 +## formatters 0.5.13 * Export `mf_col_widths` accessor (`getter` and `setter`). * Fixed a bug in listing pagination where the logical index of empty key columns was recycled across all columns, selecting the wrong columns for repeated key labels and (on recent R-devel) emitting a subscript-recycling warning that caused CRAN test failures. From 2df89cdc45b4e6a57b777b85ff275466ced710a3 Mon Sep 17 00:00:00 2001 From: Joe Zhu Date: Tue, 15 Sep 2026 09:54:22 +0800 Subject: [PATCH 2/4] fix date --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 4a58f7983..b9a475e20 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: formatters Title: ASCII Formatting for Values and Tables Version: 0.5.13 -Date: 2026-05-21 +Date: 2026-09-15 Authors@R: c( person("Gabriel", "Becker", , "gabembecker@gmail.com", role = "aut", comment = "original creator of the package"), From bb39c686330bdc0d414abb1b6a7203a85481680b Mon Sep 17 00:00:00 2001 From: Joe Zhu Date: Sun, 20 Sep 2026 13:52:14 +0800 Subject: [PATCH 3/4] adding validation report link --- _pkgdown.yml | 2 + pkgdown/extra.js | 113 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 pkgdown/extra.js diff --git a/_pkgdown.yml b/_pkgdown.yml index 375f67d52..57aa5bb02 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -15,6 +15,8 @@ navbar: href: unit-test-report/ - text: Non-CRAN unit test report href: unit-test-report-non-cran/ + - text: Validation report + href: https://pharmar.github.io/pharmapkgs/src/contrib/Meta/validation_report_formatters_v0.5.12.html github: icon: fa-github href: https://github.com/pharmaverse/formatters diff --git a/pkgdown/extra.js b/pkgdown/extra.js new file mode 100644 index 000000000..77835262a --- /dev/null +++ b/pkgdown/extra.js @@ -0,0 +1,113 @@ +// Resolve the "Validation report" navbar link to the correct report for the +// documentation version currently being viewed. +// +// pkgdown builds one independent static site per package version, and this file +// is auto-included on every page of each build. It reads the version shown in +// the navbar and points the link at the newest validation report whose version +// is <= the current version. Versions older than the first available report do +// not get a link at all. +// +// To add a report for a future release, just append its version to REPORTS +// (keep the list sorted ascending) -- no other change is needed. +(function () { + "use strict"; + + // Available validation reports, ascending. Only these versions have a report. + var REPORTS = ["0.5.11", "0.5.12"]; + var REPORT_BASE = + "https://pharmar.github.io/pharmapkgs/src/contrib/Meta/validation_report_formatters_v"; + + // Parse a version string like "0.5.13" or "0.5.12.9003" into a numeric array. + function parseVersion(v) { + return v.split(/[.-]/).map(function (x) { + var n = parseInt(x, 10); + return isNaN(n) ? 0 : n; + }); + } + + // Compare two parsed versions: returns <0, 0, or >0. + function compareVersions(a, b) { + var len = Math.max(a.length, b.length); + for (var i = 0; i < len; i++) { + var d = (a[i] || 0) - (b[i] || 0); + if (d !== 0) return d; + } + return 0; + } + + // Newest report version that is <= the current version, or null if none. + function pickReport(current) { + var cur = parseVersion(current); + var chosen = null; + for (var i = 0; i < REPORTS.length; i++) { + if (compareVersions(cur, parseVersion(REPORTS[i])) >= 0) { + chosen = REPORTS[i]; + } + } + return chosen; + } + + // Read the package version from the navbar of the current page. + function detectVersion() { + var selectors = [ + ".navbar small", + "small.nav-text", + ".navbar .version", + ".navbar-brand + small", + "header .version" + ]; + var re = /\d+\.\d+\.\d+(?:\.\d+)*/; + for (var i = 0; i < selectors.length; i++) { + var el = document.querySelector(selectors[i]); + if (el) { + var m = el.textContent.match(re); + if (m) return m[0]; + } + } + // Fallback: scan the whole navbar/header text. + var header = document.querySelector(".navbar") || document.querySelector("header"); + if (header) { + var hm = header.textContent.match(re); + if (hm) return hm[0]; + } + return null; + } + + // Find the "Validation report" anchor by its (case-insensitive) link text. + function findLink() { + var anchors = document.querySelectorAll("a"); + for (var i = 0; i < anchors.length; i++) { + if (anchors[i].textContent.trim().toLowerCase() === "validation report") { + return anchors[i]; + } + } + return null; + } + + function run() { + var link = findLink(); + if (!link) return; + + var version = detectVersion(); + // If we cannot detect the version, leave the static fallback href in place. + if (!version) return; + + var report = pickReport(version); + if (report) { + link.setAttribute( + "href", + REPORT_BASE + report + ".html" + ); + } else { + // No report for versions older than the first available one: drop the item. + var li = link.closest("li"); + (li || link).remove(); + } + } + + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", run); + } else { + run(); + } +})(); From 8b89f3c942597f3eaa2ee61fe63c450c9633422b Mon Sep 17 00:00:00 2001 From: Melkiades <11279768+Melkiades@users.noreply.github.com> Date: Mon, 21 Sep 2026 22:28:44 +0000 Subject: [PATCH 4/4] Scope the validation-report link lookup and drop two ES6 DOM calls findLink() scanned every anchor on the page, so a vignette using the words "validation report" as link text would have been rewritten instead of the navbar item. Scope it to the navbar. closest() and remove() are the only ES6-era APIs in an otherwise strict ES5 file; replace them with equivalents so the target is consistent. pickReport() now takes the maximum eligible report rather than the last match, so REPORTS no longer has to be kept sorted, and the header comment notes that the static fallback in _pkgdown.yml needs updating alongside it. --- pkgdown/extra.js | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/pkgdown/extra.js b/pkgdown/extra.js index 77835262a..0ffd012ae 100644 --- a/pkgdown/extra.js +++ b/pkgdown/extra.js @@ -7,12 +7,13 @@ // is <= the current version. Versions older than the first available report do // not get a link at all. // -// To add a report for a future release, just append its version to REPORTS -// (keep the list sorted ascending) -- no other change is needed. +// To add a report for a future release, add its version to REPORTS. Order does +// not matter. Also update the static href in _pkgdown.yml, which is what readers +// with JavaScript disabled get. (function () { "use strict"; - // Available validation reports, ascending. Only these versions have a report. + // Versions that have a validation report. Order does not matter. var REPORTS = ["0.5.11", "0.5.12"]; var REPORT_BASE = "https://pharmar.github.io/pharmapkgs/src/contrib/Meta/validation_report_formatters_v"; @@ -36,11 +37,13 @@ } // Newest report version that is <= the current version, or null if none. + // Takes the maximum rather than the last match, so REPORTS need not be sorted. function pickReport(current) { var cur = parseVersion(current); var chosen = null; for (var i = 0; i < REPORTS.length; i++) { - if (compareVersions(cur, parseVersion(REPORTS[i])) >= 0) { + if (compareVersions(cur, parseVersion(REPORTS[i])) < 0) continue; + if (chosen === null || compareVersions(parseVersion(REPORTS[i]), parseVersion(chosen)) > 0) { chosen = REPORTS[i]; } } @@ -74,16 +77,30 @@ } // Find the "Validation report" anchor by its (case-insensitive) link text. + // Scoped to the navbar so page content using the same wording is left alone. function findLink() { - var anchors = document.querySelectorAll("a"); - for (var i = 0; i < anchors.length; i++) { - if (anchors[i].textContent.trim().toLowerCase() === "validation report") { - return anchors[i]; + var roots = [document.querySelector(".navbar"), document.querySelector("header")]; + for (var r = 0; r < roots.length; r++) { + if (!roots[r]) continue; + var anchors = roots[r].querySelectorAll("a"); + for (var i = 0; i < anchors.length; i++) { + if (anchors[i].textContent.trim().toLowerCase() === "validation report") { + return anchors[i]; + } } } return null; } + // Nearest ancestor
  • , or null. Stands in for Element.closest(), which the + // rest of this file's ES5 target does not assume. + function closestListItem(el) { + for (var node = el; node; node = node.parentNode) { + if (node.nodeName && node.nodeName.toLowerCase() === "li") return node; + } + return null; + } + function run() { var link = findLink(); if (!link) return; @@ -100,8 +117,8 @@ ); } else { // No report for versions older than the first available one: drop the item. - var li = link.closest("li"); - (li || link).remove(); + var target = closestListItem(link) || link; + if (target.parentNode) target.parentNode.removeChild(target); } }