Skip to content

Commit

Permalink
Small custom extension to allow for popout tables
Browse files Browse the repository at this point in the history
  • Loading branch information
AKuederle committed Nov 14, 2024
1 parent b7f55eb commit d28a583
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 28 deletions.
Empty file added docs/_ext/__init__.py
Empty file.
67 changes: 67 additions & 0 deletions docs/_ext/fullscreen_gallery/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"""
A Sphinx extension that adds fullscreen buttons to gallery outputs.
"""

from pathlib import Path

from sphinx.util import logging
from sphinx.util.fileutil import copy_asset

logger = logging.getLogger(__name__)


def setup(app):
"""Setup the extension"""
# Add static files
app.add_css_file("gallery_fullscreen.css")
app.add_js_file("gallery_fullscreen.js")

# Add our custom post-processing function
app.connect("build-finished", add_fullscreen_buttons)

return {"version": "0.1", "parallel_read_safe": True, "parallel_write_safe": True}


def add_fullscreen_buttons(app, exception):
"""Add fullscreen buttons to gallery outputs after build"""
if exception is not None:
return

if app.builder.name != "html":
return

# Copy our static files
static_dir = Path(__file__).parent / "static"
copy_asset(str(static_dir / "gallery_fullscreen.css"), str(Path(app.outdir) / "_static"))
copy_asset(str(static_dir / "gallery_fullscreen.js"), str(Path(app.outdir) / "_static"))

# Process HTML files
for html_file in Path(app.outdir).rglob("*.html"):
process_html_file(html_file)


def process_html_file(html_file):
"""Add fullscreen buttons to a single HTML file"""
content = html_file.read_text()

# Don't process files that don't contain gallery outputs
if "output_html rendered_html" not in content and "sphx-glr-single-img" not in content:
return

# Add fullscreen buttons to images and tables
modified = add_buttons_to_content(content)

html_file.write_text(modified)


def add_buttons_to_content(content):
"""Add fullscreen buttons to gallery outputs in HTML content"""
# Add buttons to tables
content = content.replace(
'<div class="output_subarea output_html rendered_html output_result">',
'<div class="output_subarea output_html rendered_html output_result gallery-fullscreen-wrapper">'
'<button class="gallery-fullscreen-btn" title="View fullscreen">'
"<span>⤢</span></button>",
)

return content
70 changes: 70 additions & 0 deletions docs/_ext/fullscreen_gallery/static/gallery_fullscreen.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
.gallery-fullscreen-wrapper {
position: relative;
}

.gallery-fullscreen-btn {
position: absolute;
top: 10px;
right: 10px;
background: rgba(255, 255, 255, 0.8);
border: 1px solid #ccc;
border-radius: 4px;
padding: 5px 8px;
cursor: pointer;
z-index: 100;
transition: all 0.2s ease;
}

.gallery-fullscreen-btn:hover {
background: rgba(255, 255, 255, 0.95);
transform: scale(1.1);
}

.gallery-fullscreen-modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.9);
z-index: 1000;
justify-content: center;
align-items: center;
}

.gallery-fullscreen-modal.active {
display: flex;
}

.gallery-fullscreen-content {
max-width: 95%;
max-height: 95vh;
margin: auto;
background: white;
padding: 20px;
border-radius: 4px;
overflow: auto;
}

.gallery-fullscreen-close {
position: absolute;
top: 80px;
right: 20px;
font-size: 40px;
cursor: pointer;
background: white;
border-radius: 50%;
border: none;
padding: 10px;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
}

.gallery-fullscreen-close.round-button span {
font-size: 20px;
line-height: 1;
}
40 changes: 40 additions & 0 deletions docs/_ext/fullscreen_gallery/static/gallery_fullscreen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
document.addEventListener('DOMContentLoaded', function() {
// Create modal container
const modal = document.createElement('div');
modal.className = 'gallery-fullscreen-modal';
modal.innerHTML = `
<button class="gallery-fullscreen-close"><span>×</span></button>
<div class="gallery-fullscreen-content"></div>
`;
document.body.appendChild(modal);

// Add click handlers to all fullscreen buttons
document.querySelectorAll('.gallery-fullscreen-btn').forEach(btn => {
btn.addEventListener('click', function(e) {
e.preventDefault();
const wrapper = this.closest('.gallery-fullscreen-wrapper');
const content = wrapper.querySelector('img, div');

if (content) {
const clone = content.cloneNode(true);
modal.querySelector('.gallery-fullscreen-content').innerHTML = '';
modal.querySelector('.gallery-fullscreen-content').appendChild(clone);
modal.classList.add('active');
}
});
});

// Close modal on click outside or close button
modal.addEventListener('click', function(e) {
if (e.target === modal || e.target.closest('.gallery-fullscreen-close')) {
modal.classList.remove('active');
}
});

// Close modal on escape key
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape' && modal.classList.contains('active')) {
modal.classList.remove('active');
}
});
});
29 changes: 1 addition & 28 deletions docs/_static/custom_css/pandas.css
Original file line number Diff line number Diff line change
@@ -1,30 +1,3 @@
@media (min-width: 1200px) {
.bd-sidebar-primary {
font-size: var(--pst-sidebar-font-size);
max-width: 25em;
}
.bd-page-width {
max-width: 200em;
}
.bd-main .bd-content .bd-article-container {
max-width: 100%;
}
.bd-main .bd-content {
justify-content: left;
}
.bd-main .bd-content .bd-article-container article section > *:not(section, img, .output_html) {
max-width: 60em;
}
.bd-main .bd-content .bd-article-container article :is(h1, h2, h3, h4, h5, h6) {
max-width: 60em;
}
.bd-main .bd-content .bd-article-container .admonition {
margin-left: 0;
margin-right: 0;
max-width: 60em;
}
}

.output_html {
.output_html > div {
overflow-y: auto
}
2 changes: 2 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

sys.path.insert(0, str(HERE.parent))
sys.path.insert(0, str(HERE.parent.parent))
sys.path.insert(0, str(HERE.parent / "_ext"))


def convert_github_links(base_url, text):
Expand Down Expand Up @@ -93,6 +94,7 @@ def substitute(matchobj) -> str:
# "sphinx.ext.imgconverter",
"sphinx_gallery.gen_gallery",
"myst_parser",
"fullscreen_gallery",
]

# Taken from sklearn config
Expand Down

0 comments on commit d28a583

Please sign in to comment.