From cbdd84ad2caab67b7bcd92998604d3d8ded982fe Mon Sep 17 00:00:00 2001
From: LiNk-NY
Date: Fri, 24 Jul 2026 16:40:29 -0400
Subject: [PATCH 1/9] Add tasks for compiling and building test packages in
Rakefile; filter packages based on environment variables in BiocViews
---
Rakefile | 12 ++++++++++++
lib/data_sources/bioc_views.rb | 10 ++++++++++
2 files changed, 22 insertions(+)
diff --git a/Rakefile b/Rakefile
index d3db01e0b..64466d7cd 100644
--- a/Rakefile
+++ b/Rakefile
@@ -53,6 +53,18 @@ desc "Run nanoc compile"
task :compile => [:pre_compile,
:real_compile, :post_compile]
+desc "Run nanoc compile for a predefined set of test packages"
+task :compile_test do
+ ENV["TEST_PACKAGES"] = "true"
+ Rake::Task[:compile].invoke
+end
+
+desc "Build the bioconductor.org site for test packages"
+task :build_test do
+ ENV["TEST_PACKAGES"] = "true"
+ Rake::Task[:build].invoke
+end
+
desc "Pre-compilation tasks"
task :pre_compile do
FileUtils.mkdir_p "content/packages"
diff --git a/lib/data_sources/bioc_views.rb b/lib/data_sources/bioc_views.rb
index f16a179f4..f28bf9c46 100644
--- a/lib/data_sources/bioc_views.rb
+++ b/lib/data_sources/bioc_views.rb
@@ -157,6 +157,16 @@ def items
packages.delete(bad)
end
+ pkg_filter = ENV["ONLY_PACKAGES"] || ENV["PKG"]
+ if (ENV["TEST_PACKAGES"] == "true" || ENV["DEBUG_PACKAGES"] == "true") && (!pkg_filter || pkg_filter.empty?)
+ pkg_filter = "SummarizedExperiment,Biobase,BiocBaseUtils,BiocGenerics,DelayedArray,GenomicRanges,IRanges,S4Vectors"
+ end
+
+ if pkg_filter && !pkg_filter.empty?
+ allowed = pkg_filter.split(",").map(&:strip)
+ packages.select! { |k, _| allowed.include?(k) }
+ end
+
items.push(get_index_page(packages, v, version))
for package in packages.keys
From f94416fc9dd7fa7969bff1985ba39fa48f94b177 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 14 May 2026 18:12:56 +0000
Subject: [PATCH 2/9] Add citation copy buttons, DOI badge, and seminal
articles section
Agent-Logs-Url: https://github.com/Bioconductor/bioconductor.org/sessions/1c891688-7cff-4ad6-9e72-04bb485a5953
Co-authored-by: LiNk-NY <4392950+LiNk-NY@users.noreply.github.com>
---
assets/js/bioconductor.js | 55 +++++++++++++++++++++++++
assets/style/pages/packages.css | 37 +++++++++++++++++
content/about/index.md | 26 ++++++++++++
layouts/_bioc_views_package_detail.html | 3 +-
layouts/components/packages/badges.html | 1 +
5 files changed, 121 insertions(+), 1 deletion(-)
diff --git a/assets/js/bioconductor.js b/assets/js/bioconductor.js
index 6c86338b3..53f6d60d1 100644
--- a/assets/js/bioconductor.js
+++ b/assets/js/bioconductor.js
@@ -331,6 +331,8 @@ var handleCitations = function () {
segs.push(pkg);
segs.push("citation.html");
url = segs.join("/");
+ var bibUrl = url.replace("citation.html", "citation.bib");
+ var pkgName = jQuery("#bioc-citation-outer").data("package") || pkg;
jQuery.ajax({
url: url,
dataType: "html",
@@ -342,6 +344,59 @@ var handleCitations = function () {
data = data.replace(" (????)", "");
jQuery("#bioc-citation").html(data);
+
+ // Extract preferred DOI from citation text
+ var citationText = jQuery("#bioc-citation").text();
+ var doiMatch = citationText.match(/\bdoi:?(10\.\d{4,}\/\S+)/i) ||
+ citationText.match(/https?:\/\/doi\.org\/(10\.\d{4,}\/\S+)/i);
+ var preferredDoi = doiMatch ? doiMatch[1] : "10.18129/B9.bioc." + pkgName;
+ // Strip trailing punctuation from DOI
+ preferredDoi = preferredDoi.replace(/[.,;)>]+$/, "");
+
+ // Update DOI badge with preferred citation DOI
+ var encodedDoi = preferredDoi.replace(/-/g, "--").replace(/_/g, "__").replace(/\//g, "%2F");
+ var badgeHtml = '' +
+ ' ';
+ jQuery("#citation-doi-badge").html(badgeHtml);
+
+ // Add copy/download action buttons
+ var actionsHtml =
+ '\uD83D\uDCCB Copy Text ' +
+ '\uD83D\uDCCB Copy BibTeX ';
+ jQuery("#bioc-citation-actions").html(actionsHtml);
+
+ jQuery("#bioc-copy-text-btn").on("click", function () {
+ var btn = jQuery(this);
+ var text = jQuery("#bioc-citation").text().trim();
+ navigator.clipboard.writeText(text).then(function () {
+ var orig = btn.text();
+ btn.text("Copied!").addClass("copied");
+ setTimeout(function () { btn.text(orig).removeClass("copied"); }, 2000);
+ });
+ });
+
+ jQuery("#bioc-copy-bibtex-btn").on("click", function () {
+ var btn = jQuery(this);
+ btn.prop("disabled", true);
+ jQuery.ajax({
+ url: bibUrl,
+ dataType: "text",
+ success: function (bibData) {
+ navigator.clipboard.writeText(bibData).then(function () {
+ var orig = "\uD83D\uDCCB Copy BibTeX";
+ btn.text("Copied!").addClass("copied");
+ setTimeout(function () { btn.text(orig).removeClass("copied").prop("disabled", false); }, 2000);
+ });
+ },
+ error: function () {
+ btn.text("BibTeX unavailable").prop("disabled", false);
+ setTimeout(function () { btn.text("\uD83D\uDCCB Copy BibTeX"); }, 3000);
+ },
+ });
+ });
+
jQuery("#bioc-citation-outer").show();
},
error: function (data, textStatus, jqXHR) {
diff --git a/assets/style/pages/packages.css b/assets/style/pages/packages.css
index 850a6315a..8c2e1159c 100644
--- a/assets/style/pages/packages.css
+++ b/assets/style/pages/packages.css
@@ -128,6 +128,43 @@ ul.ui-autocomplete li::marker {
margin: 0.5rem 0 1rem;
}
+.citation-actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5rem;
+ margin: 0.75rem 0 0.25rem;
+}
+
+.citation-btn {
+ background: var(--neutral-n50);
+ color: var(--primary-p400);
+ border: 1px solid var(--neutral-n75);
+ border-radius: 8rem;
+ cursor: pointer;
+ font-size: 0.85rem;
+ padding: 0.2rem 0.75rem;
+ transition: background 0.2s;
+}
+
+.citation-btn:hover {
+ background: var(--primary-p50);
+}
+
+.citation-btn:active {
+ background: var(--primary-p200);
+}
+
+.citation-btn:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+
+.citation-btn.copied {
+ background: #d4edda;
+ color: #155724;
+ border-color: #c3e6cb;
+}
+
@media (max-device-width: 1450px), (max-width: 1450px) {
.biocViewsTreeContainer {
display: flex;
diff --git a/content/about/index.md b/content/about/index.md
index 7dbbdcd41..06da2549f 100644
--- a/content/about/index.md
+++ b/content/about/index.md
@@ -43,6 +43,32 @@ Methods 12:115-121][1] and Gentleman et al., 2004 [Genome Biology
[1]: http://www.nature.com/nmeth/journal/v12/n2/abs/nmeth.3252.html
[2]: https://genomebiology.biomedcentral.com/track/pdf/10.1186/gb-2004-5-10-r80.pdf
+
+
+
Huber W , Carey VJ, Gentleman R, Anders S, Carlson M, Carvalho BS,
+Bravo HC, Davis S, Gatto L, Girke T, Gottardo R, Hahne F, Hansen KD, Irizarry RA,
+Lawrence M, Love MI, MacDonald J, Obenchain V, OleŠAK, Pagès H, Reyes A, Shannon P,
+Smyth GK, Tenenbaum D, Waldron L, Morgan M (2015). "Orchestrating high-throughput
+genomic analysis with Bioconductor." Nature Methods , 12 (2),
+115β121. doi:10.1038/nmeth.3252 .
+
+ π Copy Text
+ π Copy BibTeX
+
+
+
Gentleman RC , Carey VJ, Bates DM, Bolstad B, Dettling M, Dudoit S,
+Ellis B, Gautier L, Ge Y, Gentry J, Hornik K, Hothorn T, Huber W, Iacus S, Irizarry R,
+Leisch F, Li C, Maechler M, Rossini AJ, Sawitzki G, Smith C, Smyth G, Tierney L, Yang JYH,
+Zhang J (2004). "Bioconductor: open software development for computational biology and
+bioinformatics." Genome Biology , 5 (10), R80.
+doi:10.1186/gb-2004-5-10-r80 .
+
+ π Copy Text
+ π Copy BibTeX
+
+
+
+
<%= render('/components/homepage/join/') %>
diff --git a/layouts/_bioc_views_package_detail.html b/layouts/_bioc_views_package_detail.html
index 4575078e6..f37158998 100644
--- a/layouts/_bioc_views_package_detail.html
+++ b/layouts/_bioc_views_package_detail.html
@@ -34,9 +34,10 @@ <%= @package[:Title]%>
Maintainer: <%= filter_emails(@package[:Maintainer])%>
-
+
Citation (from within R, enter citation("<%=@package[:Package]%>")):
+
diff --git a/layouts/components/packages/badges.html b/layouts/components/packages/badges.html
index 9a8490d0b..dfd203ece 100644
--- a/layouts/components/packages/badges.html
+++ b/layouts/components/packages/badges.html
@@ -161,4 +161,5 @@
10.18129/B9.bioc.<%=@item[:Package]%>
+
From 9df489ba723a6ad06a006e62d0fe1d820abac7b0 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 14 May 2026 18:17:30 +0000
Subject: [PATCH 3/9] Fix XSS via DOI sanitization, add ARIA live region for
clipboard feedback
Agent-Logs-Url: https://github.com/Bioconductor/bioconductor.org/sessions/1c891688-7cff-4ad6-9e72-04bb485a5953
Co-authored-by: LiNk-NY <4392950+LiNk-NY@users.noreply.github.com>
---
assets/js/bioconductor.js | 90 ++++++++++++++++++-------
content/about/index.md | 8 +--
layouts/_bioc_views_package_detail.html | 1 +
3 files changed, 71 insertions(+), 28 deletions(-)
diff --git a/assets/js/bioconductor.js b/assets/js/bioconductor.js
index 53f6d60d1..2fdb199b4 100644
--- a/assets/js/bioconductor.js
+++ b/assets/js/bioconductor.js
@@ -320,6 +320,37 @@ var getHrefForSymlinks = function (href) {
}
};
+// Copy text to clipboard and show brief feedback on the button
+var copyToClipboardWithFeedback = function (btn, text, label, statusEl) {
+ navigator.clipboard.writeText(text).then(function () {
+ btn.text("Copied!").addClass("copied");
+ if (statusEl) { statusEl.text("Copied to clipboard."); }
+ setTimeout(function () {
+ btn.text(label).removeClass("copied");
+ if (statusEl) { statusEl.text(""); }
+ }, 2000);
+ }).catch(function () {
+ btn.text("Copy failed").prop("disabled", false);
+ if (statusEl) { statusEl.text("Copy failed. Please copy the text manually."); }
+ setTimeout(function () {
+ btn.text(label);
+ if (statusEl) { statusEl.text(""); }
+ }, 3000);
+ });
+};
+
+// Copy a static citation text to clipboard; used for hardcoded project citations.
+// Called from inline onclick handlers in content pages.
+var copyStaticCitationText = function (btn, text) {
+ copyToClipboardWithFeedback(jQuery(btn), text, btn.textContent, null);
+};
+
+// Copy a static BibTeX string to clipboard; used for hardcoded project citations.
+// Called from inline onclick handlers in content pages.
+var copyStaticBibtex = function (btn, bibtex) {
+ copyToClipboardWithFeedback(jQuery(btn), bibtex, btn.textContent, null);
+};
+
var handleCitations = function () {
if (jQuery("#bioc-citation").length) {
jQuery("#bioc-citation-outer").hide();
@@ -345,23 +376,34 @@ var handleCitations = function () {
data = data.replace(" (????)", "");
jQuery("#bioc-citation").html(data);
- // Extract preferred DOI from citation text
+ // Extract preferred DOI from citation text.
+ // Use a precise pattern that avoids capturing trailing punctuation.
var citationText = jQuery("#bioc-citation").text();
- var doiMatch = citationText.match(/\bdoi:?(10\.\d{4,}\/\S+)/i) ||
- citationText.match(/https?:\/\/doi\.org\/(10\.\d{4,}\/\S+)/i);
+ var doiPattern = /\bdoi:?(10\.\d{4,}\/[^\s.,;)>]+)/i;
+ var urlPattern = /https?:\/\/doi\.org\/(10\.\d{4,}\/[^\s.,;)>]+)/i;
+ var doiMatch = citationText.match(doiPattern) || citationText.match(urlPattern);
var preferredDoi = doiMatch ? doiMatch[1] : "10.18129/B9.bioc." + pkgName;
- // Strip trailing punctuation from DOI
- preferredDoi = preferredDoi.replace(/[.,;)>]+$/, "");
- // Update DOI badge with preferred citation DOI
+ // Sanitize DOI: only allow characters valid in a DOI (alphanumeric,
+ // and the punctuation permitted by the DOI specification).
+ if (!/^10\.\d{4,}\/[\w./:;()\[\]<>-]+$/.test(preferredDoi)) {
+ preferredDoi = "10.18129/B9.bioc." + pkgName;
+ }
+
+ // Build shields.io badge URL. Shields.io requires hyphens doubled,
+ // underscores doubled, and slashes percent-encoded in badge label text.
var encodedDoi = preferredDoi.replace(/-/g, "--").replace(/_/g, "__").replace(/\//g, "%2F");
- var badgeHtml = '' +
- ' ';
- jQuery("#citation-doi-badge").html(badgeHtml);
- // Add copy/download action buttons
+ // Build badge using DOM construction to avoid XSS via preferredDoi
+ var $badgeLink = jQuery("")
+ .attr("href", "https://doi.org/" + preferredDoi)
+ .attr("title", "Preferred citation DOI");
+ var $badgeImg = jQuery(" ")
+ .attr("src", "https://img.shields.io/badge/DOI-" + encodedDoi + "-blue")
+ .attr("alt", "DOI badge");
+ jQuery("#citation-doi-badge").empty().append($badgeLink.append($badgeImg));
+
+ // Add copy action buttons
var actionsHtml =
'\uD83D\uDCCB Copy Text ' +
'\uD83D\uDCCB Copy BibTeX ';
@@ -369,30 +411,30 @@ var handleCitations = function () {
jQuery("#bioc-copy-text-btn").on("click", function () {
var btn = jQuery(this);
+ var statusEl = jQuery("#bioc-citation-status");
var text = jQuery("#bioc-citation").text().trim();
- navigator.clipboard.writeText(text).then(function () {
- var orig = btn.text();
- btn.text("Copied!").addClass("copied");
- setTimeout(function () { btn.text(orig).removeClass("copied"); }, 2000);
- });
+ copyToClipboardWithFeedback(btn, text, "\uD83D\uDCCB Copy Text", statusEl);
});
jQuery("#bioc-copy-bibtex-btn").on("click", function () {
var btn = jQuery(this);
+ var statusEl = jQuery("#bioc-citation-status");
+ var origLabel = "\uD83D\uDCCB Copy BibTeX";
btn.prop("disabled", true);
jQuery.ajax({
url: bibUrl,
dataType: "text",
success: function (bibData) {
- navigator.clipboard.writeText(bibData).then(function () {
- var orig = "\uD83D\uDCCB Copy BibTeX";
- btn.text("Copied!").addClass("copied");
- setTimeout(function () { btn.text(orig).removeClass("copied").prop("disabled", false); }, 2000);
- });
+ copyToClipboardWithFeedback(btn, bibData, origLabel, statusEl);
+ btn.prop("disabled", false);
},
error: function () {
- btn.text("BibTeX unavailable").prop("disabled", false);
- setTimeout(function () { btn.text("\uD83D\uDCCB Copy BibTeX"); }, 3000);
+ btn.text("BibTeX unavailable");
+ if (statusEl) { statusEl.text("BibTeX format is not available for this package."); }
+ setTimeout(function () {
+ btn.text(origLabel).prop("disabled", false);
+ if (statusEl) { statusEl.text(""); }
+ }, 3000);
},
});
});
diff --git a/content/about/index.md b/content/about/index.md
index 06da2549f..6828227f7 100644
--- a/content/about/index.md
+++ b/content/about/index.md
@@ -52,8 +52,8 @@ Smyth GK, Tenenbaum D, Waldron L, Morgan M (2015). "Orchestrating high-throughpu
genomic analysis with Bioconductor." Nature Methods , 12 (2),
115β121. doi: 10.1038/nmeth.3252 .
- π Copy Text
- π Copy BibTeX
+ π Copy Text
+ π Copy BibTeX
Gentleman RC , Carey VJ, Bates DM, Bolstad B, Dettling M, Dudoit S,
@@ -63,8 +63,8 @@ Zhang J (2004). "Bioconductor: open software development for computational biolo
bioinformatics." Genome Biology , 5 (10), R80.
doi:10.1186/gb-2004-5-10-r80 .
- π Copy Text
- π Copy BibTeX
+ π Copy Text
+ π Copy BibTeX
diff --git a/layouts/_bioc_views_package_detail.html b/layouts/_bioc_views_package_detail.html
index f37158998..508ffd3e7 100644
--- a/layouts/_bioc_views_package_detail.html
+++ b/layouts/_bioc_views_package_detail.html
@@ -38,6 +38,7 @@ <%= @package[:Title]%>
Citation (from within R, enter citation("<%=@package[:Package]%>")):
+
From c3fdc0a6671c94885d2dae1b37b93c612719cda4 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 14 May 2026 18:20:40 +0000
Subject: [PATCH 4/9] Use data attributes for static citation buttons, improve
DOI encoding and sanitization
Agent-Logs-Url: https://github.com/Bioconductor/bioconductor.org/sessions/1c891688-7cff-4ad6-9e72-04bb485a5953
Co-authored-by: LiNk-NY <4392950+LiNk-NY@users.noreply.github.com>
---
assets/js/bioconductor.js | 57 +++++++++++++++++++++++----------------
content/about/index.md | 8 +++---
2 files changed, 38 insertions(+), 27 deletions(-)
diff --git a/assets/js/bioconductor.js b/assets/js/bioconductor.js
index 2fdb199b4..16c5e68b2 100644
--- a/assets/js/bioconductor.js
+++ b/assets/js/bioconductor.js
@@ -330,7 +330,7 @@ var copyToClipboardWithFeedback = function (btn, text, label, statusEl) {
if (statusEl) { statusEl.text(""); }
}, 2000);
}).catch(function () {
- btn.text("Copy failed").prop("disabled", false);
+ btn.text("Copy failed");
if (statusEl) { statusEl.text("Copy failed. Please copy the text manually."); }
setTimeout(function () {
btn.text(label);
@@ -339,16 +339,18 @@ var copyToClipboardWithFeedback = function (btn, text, label, statusEl) {
});
};
-// Copy a static citation text to clipboard; used for hardcoded project citations.
-// Called from inline onclick handlers in content pages.
-var copyStaticCitationText = function (btn, text) {
- copyToClipboardWithFeedback(jQuery(btn), text, btn.textContent, null);
-};
-
-// Copy a static BibTeX string to clipboard; used for hardcoded project citations.
-// Called from inline onclick handlers in content pages.
-var copyStaticBibtex = function (btn, bibtex) {
- copyToClipboardWithFeedback(jQuery(btn), bibtex, btn.textContent, null);
+// Attach event listeners to static citation copy buttons that use data attributes.
+// Handles .citation-btn elements with data-citation-text or data-bibtex attributes,
+// replacing the need for inline onclick handlers in content pages.
+var handleStaticCitationButtons = function () {
+ jQuery(document).on("click", ".citation-btn[data-citation-text]", function () {
+ var btn = jQuery(this);
+ copyToClipboardWithFeedback(btn, btn.data("citation-text"), btn.text(), null);
+ });
+ jQuery(document).on("click", ".citation-btn[data-bibtex]", function () {
+ var btn = jQuery(this);
+ copyToClipboardWithFeedback(btn, btn.data("bibtex"), btn.text(), null);
+ });
};
var handleCitations = function () {
@@ -377,29 +379,37 @@ var handleCitations = function () {
jQuery("#bioc-citation").html(data);
// Extract preferred DOI from citation text.
- // Use a precise pattern that avoids capturing trailing punctuation.
+ // Use a permissive pattern (same character set as the sanitization step below).
var citationText = jQuery("#bioc-citation").text();
- var doiPattern = /\bdoi:?(10\.\d{4,}\/[^\s.,;)>]+)/i;
- var urlPattern = /https?:\/\/doi\.org\/(10\.\d{4,}\/[^\s.,;)>]+)/i;
+ var doiChars = "[\\w./:;()\\[\\]<>-]+";
+ var doiPattern = new RegExp("\\bdoi:?(10\\.\\d{4,}\\/" + doiChars + ")", "i");
+ var urlPattern = new RegExp("https?:\\/\\/doi\\.org\\/(10\\.\\d{4,}\\/" + doiChars + ")", "i");
var doiMatch = citationText.match(doiPattern) || citationText.match(urlPattern);
var preferredDoi = doiMatch ? doiMatch[1] : "10.18129/B9.bioc." + pkgName;
- // Sanitize DOI: only allow characters valid in a DOI (alphanumeric,
- // and the punctuation permitted by the DOI specification).
- if (!/^10\.\d{4,}\/[\w./:;()\[\]<>-]+$/.test(preferredDoi)) {
+ // Sanitize DOI: only allow characters valid in a DOI (alphanumeric and
+ // DOI-permitted punctuation). Falls back to the package landing page DOI.
+ if (!/^10\.\d{4,}\/[\w./:;()[\]<>-]+$/.test(preferredDoi)) {
preferredDoi = "10.18129/B9.bioc." + pkgName;
}
// Build shields.io badge URL. Shields.io requires hyphens doubled,
- // underscores doubled, and slashes percent-encoded in badge label text.
- var encodedDoi = preferredDoi.replace(/-/g, "--").replace(/_/g, "__").replace(/\//g, "%2F");
-
- // Build badge using DOM construction to avoid XSS via preferredDoi
+ // underscores doubled, slashes and other special chars percent-encoded
+ // in the badge label text.
+ var encodedDoi = preferredDoi
+ .replace(/-/g, "--")
+ .replace(/_/g, "__")
+ .replace(/[^A-Za-z0-9.-]/g, function (c) { return encodeURIComponent(c); });
+
+ // Build badge using DOM construction. encodeURI ensures the URL is valid
+ // and safe even before the DOI sanitization step above.
+ var doiHref = encodeURI("https://doi.org/" + preferredDoi);
+ var badgeSrc = encodeURI("https://img.shields.io/badge/DOI-" + encodedDoi + "-blue");
var $badgeLink = jQuery("")
- .attr("href", "https://doi.org/" + preferredDoi)
+ .attr("href", doiHref)
.attr("title", "Preferred citation DOI");
var $badgeImg = jQuery(" ")
- .attr("src", "https://img.shields.io/badge/DOI-" + encodedDoi + "-blue")
+ .attr("src", badgeSrc)
.attr("alt", "DOI badge");
jQuery("#citation-doi-badge").empty().append($badgeLink.append($badgeImg));
@@ -458,6 +468,7 @@ jQuery(function () {
});
jQuery(".rpack").tooltip({ tip: "#tooltip" }); //{ effect: 'slide'});
handleCitations();
+ handleStaticCitationButtons();
});
var submit_tryitnow = function () {
diff --git a/content/about/index.md b/content/about/index.md
index 6828227f7..b88ecd421 100644
--- a/content/about/index.md
+++ b/content/about/index.md
@@ -52,8 +52,8 @@ Smyth GK, Tenenbaum D, Waldron L, Morgan M (2015). "Orchestrating high-throughpu
genomic analysis with Bioconductor." Nature Methods , 12 (2),
115β121. doi: 10.1038/nmeth.3252 .
- π Copy Text
- π Copy BibTeX
+ π Copy Text
+ π Copy BibTeX
Gentleman RC , Carey VJ, Bates DM, Bolstad B, Dettling M, Dudoit S,
@@ -63,8 +63,8 @@ Zhang J (2004). "Bioconductor: open software development for computational biolo
bioinformatics." Genome Biology , 5 (10), R80.
doi:10.1186/gb-2004-5-10-r80 .
- π Copy Text
- π Copy BibTeX
+ π Copy Text
+ π Copy BibTeX
From 7ddc04532a729ee7f1d4fef9a30c5eb7fdc9e4f3 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 14 May 2026 18:22:04 +0000
Subject: [PATCH 5/9] Fix DOI character class to exclude angle brackets, fix
shields.io underscore encoding
Agent-Logs-Url: https://github.com/Bioconductor/bioconductor.org/sessions/1c891688-7cff-4ad6-9e72-04bb485a5953
Co-authored-by: LiNk-NY <4392950+LiNk-NY@users.noreply.github.com>
---
assets/js/bioconductor.js | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/assets/js/bioconductor.js b/assets/js/bioconductor.js
index 16c5e68b2..c5b867289 100644
--- a/assets/js/bioconductor.js
+++ b/assets/js/bioconductor.js
@@ -379,9 +379,9 @@ var handleCitations = function () {
jQuery("#bioc-citation").html(data);
// Extract preferred DOI from citation text.
- // Use a permissive pattern (same character set as the sanitization step below).
+ // Use a pattern matching only valid DOI characters per the DOI specification.
var citationText = jQuery("#bioc-citation").text();
- var doiChars = "[\\w./:;()\\[\\]<>-]+";
+ var doiChars = "[\\w./:;()\\[\\]_-]+";
var doiPattern = new RegExp("\\bdoi:?(10\\.\\d{4,}\\/" + doiChars + ")", "i");
var urlPattern = new RegExp("https?:\\/\\/doi\\.org\\/(10\\.\\d{4,}\\/" + doiChars + ")", "i");
var doiMatch = citationText.match(doiPattern) || citationText.match(urlPattern);
@@ -389,17 +389,18 @@ var handleCitations = function () {
// Sanitize DOI: only allow characters valid in a DOI (alphanumeric and
// DOI-permitted punctuation). Falls back to the package landing page DOI.
- if (!/^10\.\d{4,}\/[\w./:;()[\]<>-]+$/.test(preferredDoi)) {
+ if (!/^10\.\d{4,}\/[\w./:;()[\]_-]+$/.test(preferredDoi)) {
preferredDoi = "10.18129/B9.bioc." + pkgName;
}
- // Build shields.io badge URL. Shields.io requires hyphens doubled,
- // underscores doubled, slashes and other special chars percent-encoded
- // in the badge label text.
+ // Build shields.io badge URL. Shields.io requires hyphens doubled and
+ // underscores doubled in the badge label. Slashes and other special chars
+ // must be percent-encoded. The underscore is excluded from percent-encoding
+ // because it is doubled in the preceding step.
var encodedDoi = preferredDoi
.replace(/-/g, "--")
.replace(/_/g, "__")
- .replace(/[^A-Za-z0-9.-]/g, function (c) { return encodeURIComponent(c); });
+ .replace(/[^A-Za-z0-9._-]/g, function (c) { return encodeURIComponent(c); });
// Build badge using DOM construction. encodeURI ensures the URL is valid
// and safe even before the DOI sanitization step above.
From e1ce17a4cc4e574f42937b0ade6b068f34f71ffa Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 14 May 2026 20:35:59 +0000
Subject: [PATCH 6/9] Move seminal citations to package pages and add clipboard
fallback
Agent-Logs-Url: https://github.com/Bioconductor/bioconductor.org/sessions/f87f98f7-0089-445e-a2e7-eb77b4e8f968
Co-authored-by: LiNk-NY <4392950+LiNk-NY@users.noreply.github.com>
---
assets/js/bioconductor.js | 35 ++++++++++++++++++++++++-
content/about/index.md | 26 ------------------
layouts/_bioc_views_package_detail.html | 24 ++++++++++++++++-
3 files changed, 57 insertions(+), 28 deletions(-)
diff --git a/assets/js/bioconductor.js b/assets/js/bioconductor.js
index c5b867289..67145cdb3 100644
--- a/assets/js/bioconductor.js
+++ b/assets/js/bioconductor.js
@@ -320,9 +320,42 @@ var getHrefForSymlinks = function (href) {
}
};
+var fallbackCopyText = function (text) {
+ return new Promise(function (resolve, reject) {
+ var textarea = document.createElement("textarea");
+ textarea.value = text;
+ textarea.setAttribute("readonly", "");
+ textarea.style.position = "absolute";
+ textarea.style.left = "-9999px";
+ document.body.appendChild(textarea);
+ textarea.select();
+ textarea.setSelectionRange(0, textarea.value.length);
+ try {
+ if (document.execCommand("copy")) {
+ resolve();
+ } else {
+ reject(new Error("Copy command failed"));
+ }
+ } catch (e) {
+ reject(e);
+ } finally {
+ document.body.removeChild(textarea);
+ }
+ });
+};
+
+var writeTextToClipboard = function (text) {
+ if (navigator.clipboard && window.isSecureContext) {
+ return navigator.clipboard.writeText(text).catch(function () {
+ return fallbackCopyText(text);
+ });
+ }
+ return fallbackCopyText(text);
+};
+
// Copy text to clipboard and show brief feedback on the button
var copyToClipboardWithFeedback = function (btn, text, label, statusEl) {
- navigator.clipboard.writeText(text).then(function () {
+ writeTextToClipboard(text).then(function () {
btn.text("Copied!").addClass("copied");
if (statusEl) { statusEl.text("Copied to clipboard."); }
setTimeout(function () {
diff --git a/content/about/index.md b/content/about/index.md
index b88ecd421..7dbbdcd41 100644
--- a/content/about/index.md
+++ b/content/about/index.md
@@ -43,32 +43,6 @@ Methods 12:115-121][1] and Gentleman et al., 2004 [Genome Biology
[1]: http://www.nature.com/nmeth/journal/v12/n2/abs/nmeth.3252.html
[2]: https://genomebiology.biomedcentral.com/track/pdf/10.1186/gb-2004-5-10-r80.pdf
-
-
-
Huber W , Carey VJ, Gentleman R, Anders S, Carlson M, Carvalho BS,
-Bravo HC, Davis S, Gatto L, Girke T, Gottardo R, Hahne F, Hansen KD, Irizarry RA,
-Lawrence M, Love MI, MacDonald J, Obenchain V, OleŠAK, Pagès H, Reyes A, Shannon P,
-Smyth GK, Tenenbaum D, Waldron L, Morgan M (2015). "Orchestrating high-throughput
-genomic analysis with Bioconductor." Nature Methods , 12 (2),
-115β121. doi:10.1038/nmeth.3252 .
-
- π Copy Text
- π Copy BibTeX
-
-
-
Gentleman RC , Carey VJ, Bates DM, Bolstad B, Dettling M, Dudoit S,
-Ellis B, Gautier L, Ge Y, Gentry J, Hornik K, Hothorn T, Huber W, Iacus S, Irizarry R,
-Leisch F, Li C, Maechler M, Rossini AJ, Sawitzki G, Smith C, Smyth G, Tierney L, Yang JYH,
-Zhang J (2004). "Bioconductor: open software development for computational biology and
-bioinformatics." Genome Biology , 5 (10), R80.
-doi:10.1186/gb-2004-5-10-r80 .
-
- π Copy Text
- π Copy BibTeX
-
-
-
-
<%= render('/components/homepage/join/') %>
diff --git a/layouts/_bioc_views_package_detail.html b/layouts/_bioc_views_package_detail.html
index 508ffd3e7..35452e7b7 100644
--- a/layouts/_bioc_views_package_detail.html
+++ b/layouts/_bioc_views_package_detail.html
@@ -40,6 +40,29 @@ <%= @package[:Title]%>
+
+
Seminal Bioconductor project articles:
+
Huber W , Carey VJ, Gentleman R, Anders S, Carlson M, Carvalho BS,
+ Bravo HC, Davis S, Gatto L, Girke T, Gottardo R, Hahne F, Hansen KD, Irizarry RA,
+ Lawrence M, Love MI, MacDonald J, Obenchain V, OleŠAK, Pagès H, Reyes A, Shannon P,
+ Smyth GK, Tenenbaum D, Waldron L, Morgan M (2015). "Orchestrating high-throughput
+ genomic analysis with Bioconductor." Nature Methods , 12 (2),
+ 115β121. doi:10.1038/nmeth.3252 .
+
+ π Copy Text
+ π Copy BibTeX
+
+
Gentleman RC , Carey VJ, Bates DM, Bolstad B, Dettling M, Dudoit S,
+ Ellis B, Gautier L, Ge Y, Gentry J, Hornik K, Hothorn T, Huber W, Iacus S, Irizarry R,
+ Leisch F, Li C, Maechler M, Rossini AJ, Sawitzki G, Smith C, Smyth G, Tierney L, Yang JYH,
+ Zhang J (2004). "Bioconductor: open software development for computational biology and
+ bioinformatics." Genome Biology , 5 (10), R80.
+ doi:10.1186/gb-2004-5-10-r80 .
+
+ π Copy Text
+ π Copy BibTeX
+
+
@@ -49,4 +72,3 @@ <%= @package[:Title]%>
<%= render("/components/packages/details/", :package => @package) %>
<%= render("/components/packages/archives/", :package => @package) %>
-
From 17a0e5e0d2917b47d303feb7a66456027f66bb41 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 14 May 2026 20:38:12 +0000
Subject: [PATCH 7/9] Harden DOI parsing/encoding and add accessibility labels
for citation buttons
Agent-Logs-Url: https://github.com/Bioconductor/bioconductor.org/sessions/f87f98f7-0089-445e-a2e7-eb77b4e8f968
Co-authored-by: LiNk-NY <4392950+LiNk-NY@users.noreply.github.com>
---
assets/js/bioconductor.js | 32 ++++++++++++-------------
layouts/_bioc_views_package_detail.html | 8 +++----
2 files changed, 19 insertions(+), 21 deletions(-)
diff --git a/assets/js/bioconductor.js b/assets/js/bioconductor.js
index 67145cdb3..49e1a38cc 100644
--- a/assets/js/bioconductor.js
+++ b/assets/js/bioconductor.js
@@ -353,6 +353,13 @@ var writeTextToClipboard = function (text) {
return fallbackCopyText(text);
};
+var encodeForShieldsIO = function (text) {
+ return text
+ .replace(/-/g, "--")
+ .replace(/_/g, "__")
+ .replace(/[^A-Za-z0-9._-]/g, function (c) { return encodeURIComponent(c); });
+};
+
// Copy text to clipboard and show brief feedback on the button
var copyToClipboardWithFeedback = function (btn, text, label, statusEl) {
writeTextToClipboard(text).then(function () {
@@ -414,7 +421,7 @@ var handleCitations = function () {
// Extract preferred DOI from citation text.
// Use a pattern matching only valid DOI characters per the DOI specification.
var citationText = jQuery("#bioc-citation").text();
- var doiChars = "[\\w./:;()\\[\\]_-]+";
+ var doiChars = "[\\w.()/_-]+";
var doiPattern = new RegExp("\\bdoi:?(10\\.\\d{4,}\\/" + doiChars + ")", "i");
var urlPattern = new RegExp("https?:\\/\\/doi\\.org\\/(10\\.\\d{4,}\\/" + doiChars + ")", "i");
var doiMatch = citationText.match(doiPattern) || citationText.match(urlPattern);
@@ -422,23 +429,14 @@ var handleCitations = function () {
// Sanitize DOI: only allow characters valid in a DOI (alphanumeric and
// DOI-permitted punctuation). Falls back to the package landing page DOI.
- if (!/^10\.\d{4,}\/[\w./:;()[\]_-]+$/.test(preferredDoi)) {
+ if (!/^10\.\d{4,}\/[\w.()/_-]+$/.test(preferredDoi)) {
preferredDoi = "10.18129/B9.bioc." + pkgName;
}
- // Build shields.io badge URL. Shields.io requires hyphens doubled and
- // underscores doubled in the badge label. Slashes and other special chars
- // must be percent-encoded. The underscore is excluded from percent-encoding
- // because it is doubled in the preceding step.
- var encodedDoi = preferredDoi
- .replace(/-/g, "--")
- .replace(/_/g, "__")
- .replace(/[^A-Za-z0-9._-]/g, function (c) { return encodeURIComponent(c); });
-
- // Build badge using DOM construction. encodeURI ensures the URL is valid
- // and safe even before the DOI sanitization step above.
- var doiHref = encodeURI("https://doi.org/" + preferredDoi);
- var badgeSrc = encodeURI("https://img.shields.io/badge/DOI-" + encodedDoi + "-blue");
+ var encodedDoi = encodeForShieldsIO(preferredDoi);
+
+ var doiHref = "https://doi.org/" + encodeURIComponent(preferredDoi);
+ var badgeSrc = "https://img.shields.io/badge/DOI-" + encodedDoi + "-blue";
var $badgeLink = jQuery("")
.attr("href", doiHref)
.attr("title", "Preferred citation DOI");
@@ -449,8 +447,8 @@ var handleCitations = function () {
// Add copy action buttons
var actionsHtml =
- '\uD83D\uDCCB Copy Text ' +
- '\uD83D\uDCCB Copy BibTeX ';
+ '\uD83D\uDCCB Copy Text ' +
+ '\uD83D\uDCCB Copy BibTeX ';
jQuery("#bioc-citation-actions").html(actionsHtml);
jQuery("#bioc-copy-text-btn").on("click", function () {
diff --git a/layouts/_bioc_views_package_detail.html b/layouts/_bioc_views_package_detail.html
index 35452e7b7..d2c409950 100644
--- a/layouts/_bioc_views_package_detail.html
+++ b/layouts/_bioc_views_package_detail.html
@@ -49,8 +49,8 @@ <%= @package[:Title]%>
genomic analysis with Bioconductor." Nature Methods , 12 (2),
115β121. doi: 10.1038/nmeth.3252 .
- π Copy Text
- π Copy BibTeX
+ π Copy Text
+ π Copy BibTeX
Gentleman RC , Carey VJ, Bates DM, Bolstad B, Dettling M, Dudoit S,
Ellis B, Gautier L, Ge Y, Gentry J, Hornik K, Hothorn T, Huber W, Iacus S, Irizarry R,
@@ -59,8 +59,8 @@
<%= @package[:Title]%>
bioinformatics." Genome Biology , 5 (10), R80.
doi:10.1186/gb-2004-5-10-r80 .
- π Copy Text
- π Copy BibTeX
+ π Copy Text
+ π Copy BibTeX
From 84729477cb12510c4cc7973132fd1c72d145d559 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 14 May 2026 20:39:27 +0000
Subject: [PATCH 8/9] Refactor DOI and clipboard constants for maintainability
Agent-Logs-Url: https://github.com/Bioconductor/bioconductor.org/sessions/f87f98f7-0089-445e-a2e7-eb77b4e8f968
Co-authored-by: LiNk-NY <4392950+LiNk-NY@users.noreply.github.com>
---
assets/js/bioconductor.js | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/assets/js/bioconductor.js b/assets/js/bioconductor.js
index 49e1a38cc..fdbe64279 100644
--- a/assets/js/bioconductor.js
+++ b/assets/js/bioconductor.js
@@ -353,10 +353,15 @@ var writeTextToClipboard = function (text) {
return fallbackCopyText(text);
};
+var CLIPBOARD_EMOJI = "\uD83D\uDCCB";
+var DOI_BODY_PATTERN = "[\\w.()/_-]+";
+var DOI_PATTERN = "10\\.\\d{4,}\\/" + DOI_BODY_PATTERN;
+
var encodeForShieldsIO = function (text) {
return text
.replace(/-/g, "--")
.replace(/_/g, "__")
+ .replace(/ /g, "_")
.replace(/[^A-Za-z0-9._-]/g, function (c) { return encodeURIComponent(c); });
};
@@ -421,15 +426,14 @@ var handleCitations = function () {
// Extract preferred DOI from citation text.
// Use a pattern matching only valid DOI characters per the DOI specification.
var citationText = jQuery("#bioc-citation").text();
- var doiChars = "[\\w.()/_-]+";
- var doiPattern = new RegExp("\\bdoi:?(10\\.\\d{4,}\\/" + doiChars + ")", "i");
- var urlPattern = new RegExp("https?:\\/\\/doi\\.org\\/(10\\.\\d{4,}\\/" + doiChars + ")", "i");
+ var doiPattern = new RegExp("\\bdoi:?(" + DOI_PATTERN + ")", "i");
+ var urlPattern = new RegExp("https?:\\/\\/doi\\.org\\/(" + DOI_PATTERN + ")", "i");
var doiMatch = citationText.match(doiPattern) || citationText.match(urlPattern);
var preferredDoi = doiMatch ? doiMatch[1] : "10.18129/B9.bioc." + pkgName;
// Sanitize DOI: only allow characters valid in a DOI (alphanumeric and
// DOI-permitted punctuation). Falls back to the package landing page DOI.
- if (!/^10\.\d{4,}\/[\w.()/_-]+$/.test(preferredDoi)) {
+ if (!(new RegExp("^" + DOI_PATTERN + "$")).test(preferredDoi)) {
preferredDoi = "10.18129/B9.bioc." + pkgName;
}
@@ -447,21 +451,21 @@ var handleCitations = function () {
// Add copy action buttons
var actionsHtml =
- '\uD83D\uDCCB Copy Text ' +
- '\uD83D\uDCCB Copy BibTeX ';
+ '' + CLIPBOARD_EMOJI + ' Copy Text ' +
+ '' + CLIPBOARD_EMOJI + ' Copy BibTeX ';
jQuery("#bioc-citation-actions").html(actionsHtml);
jQuery("#bioc-copy-text-btn").on("click", function () {
var btn = jQuery(this);
var statusEl = jQuery("#bioc-citation-status");
var text = jQuery("#bioc-citation").text().trim();
- copyToClipboardWithFeedback(btn, text, "\uD83D\uDCCB Copy Text", statusEl);
+ copyToClipboardWithFeedback(btn, text, CLIPBOARD_EMOJI + " Copy Text", statusEl);
});
jQuery("#bioc-copy-bibtex-btn").on("click", function () {
var btn = jQuery(this);
var statusEl = jQuery("#bioc-citation-status");
- var origLabel = "\uD83D\uDCCB Copy BibTeX";
+ var origLabel = CLIPBOARD_EMOJI + " Copy BibTeX";
btn.prop("disabled", true);
jQuery.ajax({
url: bibUrl,
From 1854b10b4c46fe3060d968e955e2e44163e51ee5 Mon Sep 17 00:00:00 2001
From: LiNk-NY
Date: Fri, 24 Jul 2026 16:33:23 -0400
Subject: [PATCH 9/9] add Bioconductor project citations
---
layouts/_bioc_views_package_detail.html | 35 +++++++++++--------------
1 file changed, 16 insertions(+), 19 deletions(-)
diff --git a/layouts/_bioc_views_package_detail.html b/layouts/_bioc_views_package_detail.html
index d2c409950..6333be888 100644
--- a/layouts/_bioc_views_package_detail.html
+++ b/layouts/_bioc_views_package_detail.html
@@ -34,6 +34,9 @@ <%= @package[:Title]%>
Maintainer: <%= filter_emails(@package[:Maintainer])%>
+
+
+
Citation (from within R, enter citation("<%=@package[:Package]%>")):
@@ -42,25 +45,19 @@
<%= @package[:Title]%>
Seminal Bioconductor project articles:
-
Huber W , Carey VJ, Gentleman R, Anders S, Carlson M, Carvalho BS,
- Bravo HC, Davis S, Gatto L, Girke T, Gottardo R, Hahne F, Hansen KD, Irizarry RA,
- Lawrence M, Love MI, MacDonald J, Obenchain V, OleŠAK, Pagès H, Reyes A, Shannon P,
- Smyth GK, Tenenbaum D, Waldron L, Morgan M (2015). "Orchestrating high-throughput
- genomic analysis with Bioconductor." Nature Methods , 12 (2),
- 115β121. doi:10.1038/nmeth.3252 .
-
- π Copy Text
- π Copy BibTeX
-
-
Gentleman RC , Carey VJ, Bates DM, Bolstad B, Dettling M, Dudoit S,
- Ellis B, Gautier L, Ge Y, Gentry J, Hornik K, Hothorn T, Huber W, Iacus S, Irizarry R,
- Leisch F, Li C, Maechler M, Rossini AJ, Sawitzki G, Smith C, Smyth G, Tierney L, Yang JYH,
- Zhang J (2004). "Bioconductor: open software development for computational biology and
- bioinformatics." Genome Biology , 5 (10), R80.
- doi:10.1186/gb-2004-5-10-r80 .
-
-
π Copy Text
-
π Copy BibTeX
+
+
Huber W , Carey VJ, Gentleman R, Anders S, Carlson M, Carvalho BS,
+ Bravo HC, Davis S, Gatto L, Girke T, Gottardo R, Hahne F, Hansen KD, Irizarry RA,
+ Lawrence M, Love MI, MacDonald J, Obenchain V, OleŠAK, Pagès H, Reyes A, Shannon P,
+ Smyth GK, Tenenbaum D, Waldron L, Morgan M (2015). "Orchestrating high-throughput
+ genomic analysis with Bioconductor." Nature Methods , 12 (2),
+ 115β121. doi:10.1038/nmeth.3252 .
+
Gentleman RC , Carey VJ, Bates DM, Bolstad B, Dettling M, Dudoit S,
+ Ellis B, Gautier L, Ge Y, Gentry J, Hornik K, Hothorn T, Huber W, Iacus S, Irizarry R,
+ Leisch F, Li C, Maechler M, Rossini AJ, Sawitzki G, Smith C, Smyth G, Tierney L, Yang JYH,
+ Zhang J (2004). "Bioconductor: open software development for computational biology and
+ bioinformatics." Genome Biology , 5 (10), R80.
+ doi:10.1186/gb-2004-5-10-r80 .