From a241e2c201b9c7eccc5f0e9bbc2d6b0c9676b591 Mon Sep 17 00:00:00 2001 From: claude Date: Sun, 31 May 2026 16:54:56 +0000 Subject: [PATCH] Pre-install popular Quarto extensions in the Docker image MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dockerfile-base: after Quarto is installed, run 'quarto add --no-prompt' for a curated set of extensions into /opt/quarto-extensions/. Quarto writes _extensions/// in the working dir, giving us a clean shared store. Extensions included: - igorlima/charged-ieee — IEEE paper format (Typst) - quarto-ext/fontawesome — Font Awesome icons - quarto-ext/attribution — attribution footer on RevealJS slides - quarto-ext/pointer — laser pointer for presentations - quarto-ext/drop — drop-down overlay for RevealJS Adding more: one extra '&& quarto add --no-prompt /' line. QuartoRunner: before quarto render, merge /opt/quarto-extensions/_extensions/ into the compile dir's _extensions/ with 'cp -rn' (no-clobber). This makes all pre-installed extensions available to every project without any user action. Project-uploaded _extensions/ files take precedence since cp -n never overwrites existing files. Co-Authored-By: Claude Sonnet 4.6 --- server-ce/Dockerfile-base | 21 +++++++++++++++++++++ services/clsi/app/js/QuartoRunner.js | 5 +++++ 2 files changed, 26 insertions(+) diff --git a/server-ce/Dockerfile-base b/server-ce/Dockerfile-base index 929180a25b..f63cc9a8c8 100644 --- a/server-ce/Dockerfile-base +++ b/server-ce/Dockerfile-base @@ -44,6 +44,27 @@ RUN curl -fsSL "https://github.com/quarto-dev/quarto-cli/releases/download/v${QU && mkdir -p /var/www/.cache/quarto \ && chown -R www-data:www-data /var/www/.cache +# Pre-install popular Quarto extensions +# ----------------------------------------------------------------------- +# Extensions land in /opt/quarto-extensions/_extensions///. +# QuartoRunner copies them into each project's compile dir (no-clobber, +# so user-uploaded extensions in their project always take precedence). +# To add more: append another line: && quarto add --no-prompt / +# ----------------------------------------------------------------------- +RUN mkdir -p /opt/quarto-extensions \ +&& cd /opt/quarto-extensions \ + \ + # Typst document formats +&& quarto add --no-prompt igorlima/charged-ieee \ + \ + # RevealJS presentation plugins (official Quarto extensions) +&& quarto add --no-prompt quarto-ext/fontawesome \ +&& quarto add --no-prompt quarto-ext/attribution \ +&& quarto add --no-prompt quarto-ext/pointer \ +&& quarto add --no-prompt quarto-ext/drop \ + \ +&& chown -R www-data:www-data /opt/quarto-extensions + # Set up overleaf user and home directory # ----------------------------------------- diff --git a/services/clsi/app/js/QuartoRunner.js b/services/clsi/app/js/QuartoRunner.js index 1a7b60bebe..ebade99ca7 100644 --- a/services/clsi/app/js/QuartoRunner.js +++ b/services/clsi/app/js/QuartoRunner.js @@ -62,7 +62,12 @@ function _buildQuartoCommand(mainFile) { // LocalCommandRunner.replace() only replaces the FIRST $COMPILE_DIR // occurrence in the shell string, so the mv commands use relative paths // instead — the shell CWD is already set to the compile directory. + // Merge pre-installed extensions into the compile dir before rendering. + // -n (no-clobber) ensures project-uploaded extensions take precedence. + // The semicolon means a missing /opt/quarto-extensions dir doesn't abort. const cmd = + `mkdir -p _extensions && ` + + `cp -rn /opt/quarto-extensions/_extensions/. _extensions/ 2>/dev/null; ` + `quarto render ${inputPath} --embed-resources 2>&1 && ` + `(mv ${baseName}.pdf output.pdf 2>/dev/null || ` + `mv ${baseName}.html output.html 2>/dev/null)`