From aa27b1f41c1aad94a1ae9e60d5d70e921f35017c Mon Sep 17 00:00:00 2001 From: Ananya gupta Date: Mon, 10 Nov 2025 21:36:18 +0530 Subject: [PATCH] Add copy button feature to documentation code blocks --- docs/requirements.txt | 1 + docs/src/conf.py | 25 ++++++++++++++++- docs/src/static/copybutton.css | 50 ++++++++++++++++++++++++++++++++++ package-lock.json | 6 ++++ 4 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 docs/src/static/copybutton.css create mode 100644 package-lock.json diff --git a/docs/requirements.txt b/docs/requirements.txt index 0319b3087..dce5387bc 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,6 +1,7 @@ # primary furo==2024.8.6 Sphinx==7.0.1 +sphinx-copybutton==0.5.2 # dependencies alabaster==0.7.16 diff --git a/docs/src/conf.py b/docs/src/conf.py index 354759a23..5481d1509 100644 --- a/docs/src/conf.py +++ b/docs/src/conf.py @@ -48,7 +48,7 @@ sys.path.insert(0, os.path.abspath('sphinx-plugins')) # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = ['manpage'] +extensions = ['manpage', 'sphinx_copybutton'] # Add any paths that contain templates here, relative to this directory. templates_path = ['templates'] @@ -149,6 +149,12 @@ html_favicon = 'static/favicon.ico' # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['static'] +# Add a tiny CSS override for the copy button so it positions nicely +# and matches the docs' minimal style. The file lives under static/. +html_css_files = [ + 'copybutton.css', +] + # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. @@ -326,6 +332,23 @@ epub_basename = u'libuv' # A list of files that should not be packed into the epub file. epub_exclude_files = ['search.html'] +# ------------------------------------------------------------------ +# sphinx-copybutton configuration +# Adds a small, accessible "Copy" button to code blocks in the HTML +# output. Install with: pip install sphinx-copybutton +# ------------------------------------------------------------------ +# Selector targets the
 elements created by the Pygments highlight
+# integration. Keep this selector minimal so it matches the project's
+# highlighted code blocks across themes.
+copybutton_selector = "div.highlight pre, div.highlighted pre, pre.literal-block"
+
+# Treat the prompt text as a regular expression so common REPL prompts
+# (>>>, $) are stripped when copying. This keeps copied snippets
+# clean for pasting into shells or editors.
+copybutton_prompt_text = r"^\s*(>>> |\$ |\.\.\. )"
+copybutton_prompt_is_regexp = True
+
+
 # The depth of the table of contents in toc.ncx.
 #epub_tocdepth = 3
 
diff --git a/docs/src/static/copybutton.css b/docs/src/static/copybutton.css
new file mode 100644
index 000000000..45d58c2fa
--- /dev/null
+++ b/docs/src/static/copybutton.css
@@ -0,0 +1,50 @@
+/* Minimal, theme-agnostic styles for the copy button added by
+   sphinx-copybutton. Keeps the UI small and accessible. */
+
+/* Ensure the code block container is the positioning context */
+.highlight, .highlighted, pre.literal-block {
+  position: relative;
+}
+
+/* Target possible copy button class names used by extensions */
+button.copybutton, button.copybtn, .copybutton, .copybtn {
+  position: absolute;
+  top: 0.5rem;
+  right: 0.5rem;
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  padding: 0.35rem;
+  border-radius: 6px;
+  border: 1px solid rgba(0,0,0,0.12);
+  background: rgba(255,255,255,0.02);
+  color: inherit;
+  font-size: 0.9rem;
+  line-height: 1;
+  cursor: pointer;
+  transition: background-color 120ms ease, transform 80ms ease;
+  /* Make sure it doesn't overlap long code selection */
+  z-index: 3;
+}
+
+button.copybutton:hover, button.copybtn:hover,
+.copybutton:hover, .copybtn:hover {
+  background: rgba(255,255,255,0.04);
+  transform: translateY(-1px);
+}
+
+/* Focus styles for keyboard users */
+button.copybutton:focus, button.copybtn:focus,
+.copybutton:focus, .copybtn:focus {
+  outline: 3px solid Highlight;
+  outline-offset: 2px;
+}
+
+/* Smaller visual footprint on narrow screens */
+@media (max-width: 520px) {
+  button.copybutton, button.copybtn, .copybutton, .copybtn {
+    top: 0.35rem;
+    right: 0.35rem;
+    padding: 0.25rem;
+  }
+}
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 000000000..c1b373c0b
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,6 @@
+{
+  "name": "libuv",
+  "lockfileVersion": 3,
+  "requires": true,
+  "packages": {}
+}