Compare commits

...
13 Commits
Author SHA1 Message Date
Nuno C. 69014f6547 Bump version to 3.4.0 2026-08-22 09:07:41 +01:00
ZhenShuo Leo 9f8972fecf fix: medium-zoom conflict with featureImageHover 2026-08-22 09:06:46 +01:00
ZhenShuo Leo 4b42f34de5 fix: katex rendering (#3062) 2026-08-22 09:06:16 +01:00
Nuno Coração be63d03bea 3.3.0 2026-08-21 02:18:08 +01:00
ZhenShuo2021 8334f00562 fix: JS broken in v3 (#3061)
* fix: zoom broken in v3 (#3060)

* fix: buymeacoffee broken in v3
2026-08-21 02:17:22 +01:00
Nuno CoraçãoandClaude Fable 5 ca56ac78a3 🐛 Let the fullscreen mobile menu escape the floating header
The floating header's backdrop blur makes the pill a containing block
for fixed-position descendants, so the fullscreen mobile menu rendered
at the pill's height instead of filling the viewport. Lift the filter
while the menu is open. Fixes #3057.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-19 23:51:04 +01:00
Nuno CoraçãoandClaude Fable 5 587d8eec1d 🐛 Repair dependency version fields corrupted by version bumps
The 3.1.0 and 3.2.0 release bumps used an unanchored replacement that
also rewrote eight dependencies' lockfile version fields. Restore each
to the version embedded in its resolved tarball URL.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-19 23:45:59 +01:00
Nuno Coração 7245635dc1 3.2.0 2026-08-19 23:44:22 +01:00
dependabot[bot] 148837c017 📌 bump katex from 0.18.2 to 0.18.4 (#3056)
* 📌 bump katex from 0.18.2 to 0.18.4

Bumps [katex](https://github.com/KaTeX/KaTeX) from 0.18.2 to 0.18.4.
- [Release notes](https://github.com/KaTeX/KaTeX/releases)
- [Changelog](https://github.com/KaTeX/KaTeX/blob/main/CHANGELOG.md)
- [Commits](https://github.com/KaTeX/KaTeX/compare/v0.18.2...v0.18.4)

---
updated-dependencies:
- dependency-name: katex
  dependency-version: 0.18.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* 📦 Update packaged KaTeX

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-19 23:43:41 +01:00
Metalhearf 5ef4024c40 🐛 Close the mobile dropdown menu when clicking outside it (#3059)
The dropdown panel only closed through its own X button. Escape already
dismissed it, so the missing pointer equivalent left the panel stuck open
over the page after a stray tap.

Close it on any click landing outside the panel and outside the labels that
toggle it. Both early returns are load-bearing. A label forwards a synthetic
click to its checkbox, so without skipping the input the menu closes in the
same gesture that opened it. And without skipping the opener, opening then
closing with the hamburger leaves the panel open, because this handler and
the label's default action cancel each other out.

The fullscreen panel needs no special case. It covers the viewport, so
every click lands inside it and the handler stays inert.
2026-08-19 23:43:37 +01:00
Metalhearf 134a044262 🐛 Balance the padding of the desktop dropdown menu (#3058)
The submenu panel carried both `pt-2` and `p-5`. Tailwind emits shorthand
utilities before their longhand counterparts, so `padding-top` resolved to
`0.5rem` while the other three sides stayed at `1.25rem`, regardless of the
order the classes appear in the markup. The first submenu entry sat flush
against the top edge.

This went unnoticed while the panel was translucent. v3 made it opaque, which
draws the edge and exposes the imbalance.

Drop `pt-2` so the panel keeps the uniform `p-5` it was styled for. No new
utility classes, so the compiled stylesheet is unchanged.
2026-08-19 23:43:34 +01:00
Nuno Coração a4817aa442 3.1.0 2026-08-18 21:53:25 +01:00
03443c989f feat: localize 404 page quotes (#3052)
* feat: localize 404 page quotes

* 🐛 Fix 404 quote localization: build-time filtering and dub lines

Filter quotes to the page language at build time (case-insensitive,
with base-language and English fallbacks), fixing the double-encoded
language variable that made every locale fall back to English, and
correct several translations to their canonical dub lines.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Friday <friday@openclaw.local>
Co-authored-by: Nuno Coração <nunocoracao@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-18 21:53:12 +01:00
21 changed files with 1724 additions and 66 deletions

No files matched your search

+4
View File
@@ -4900,6 +4900,10 @@ body:has(#mobile-menu-toggle:checked) {
visibility: hidden;
transition: visibility 0.3s, opacity 0.3s ease-in-out;
}
header > div:has(.mobile-menu-fullscreen #mobile-menu-toggle:checked) {
-webkit-backdrop-filter: none;
backdrop-filter: none;
}
.nested-menu:nth-last-child(-n + 3) .menuhide, .mobile-header-row .menuhide {
inset-inline-end: 0;
}
+9
View File
@@ -485,6 +485,15 @@ body:has(#mobile-menu-toggle:checked) {
opacity 0.3s ease-in-out;
}
/* A backdrop-filter turns the header pill into a containing block for
position:fixed descendants, which would trap the fullscreen mobile menu
inside it. Lift the filter while that menu is open — the fullscreen
overlay covers the header anyway, so the change is invisible. */
header > div:has(.mobile-menu-fullscreen #mobile-menu-toggle:checked) {
-webkit-backdrop-filter: none;
backdrop-filter: none;
}
/* Dropdowns near the end of the bar open leftward so they stay on screen */
.nested-menu:nth-last-child(-n + 3) .menuhide,
.mobile-header-row .menuhide {
+5
View File
@@ -0,0 +1,5 @@
mediumZoom(document.querySelectorAll("img:not(.nozoom)"), {
margin: 24,
background: "rgba(0,0,0,0.5)",
scrollOffset: 0,
});
+14
View File
@@ -45,6 +45,19 @@
});
}
function setupMobileMenuOutsideClick() {
var toggle = document.getElementById("mobile-menu-toggle");
var dialog = document.getElementById("mobile-menu-dialog");
if (!toggle || !dialog) return;
document.addEventListener("click", function (event) {
if (!toggle.checked || event.target === toggle) return;
if (dialog.contains(event.target)) return;
if (event.target.closest('label[for="mobile-menu-toggle"]')) return;
toggle.checked = false;
syncCheckboxLabels(toggle);
});
}
function setupDesktopDropdowns() {
document.querySelectorAll(".nested-menu").forEach(function (menu) {
var trigger = menu.querySelector("[aria-haspopup]");
@@ -78,6 +91,7 @@
function init() {
setupCheckboxLabels();
setupMobileMenuEscape();
setupMobileMenuOutsideClick();
setupDesktopDropdowns();
}
+1 -1
View File
@@ -1 +1 @@
@font-face{font-display:block;font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url(fonts/KaTeX_AMS-Regular.woff2) format("woff2"),url(fonts/KaTeX_AMS-Regular.woff) format("woff"),url(fonts/KaTeX_AMS-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Caligraphic-Bold.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Bold.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Bold.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Caligraphic-Regular.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Regular.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Fraktur-Bold.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Bold.woff) format("woff"),url(fonts/KaTeX_Fraktur-Bold.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Fraktur-Regular.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Regular.woff) format("woff"),url(fonts/KaTeX_Fraktur-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Main-Bold.woff2) format("woff2"),url(fonts/KaTeX_Main-Bold.woff) format("woff"),url(fonts/KaTeX_Main-Bold.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Main-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Main-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Main-BoldItalic.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Main-Italic.woff2) format("woff2"),url(fonts/KaTeX_Main-Italic.woff) format("woff"),url(fonts/KaTeX_Main-Italic.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Main-Regular.woff2) format("woff2"),url(fonts/KaTeX_Main-Regular.woff) format("woff"),url(fonts/KaTeX_Main-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Math-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Math-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Math-BoldItalic.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Math-Italic.woff2) format("woff2"),url(fonts/KaTeX_Math-Italic.woff) format("woff"),url(fonts/KaTeX_Math-Italic.ttf) format("truetype")}@font-face{font-display:block;font-family:"KaTeX_SansSerif";font-style:normal;font-weight:700;src:url(fonts/KaTeX_SansSerif-Bold.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Bold.woff) format("woff"),url(fonts/KaTeX_SansSerif-Bold.ttf) format("truetype")}@font-face{font-display:block;font-family:"KaTeX_SansSerif";font-style:italic;font-weight:400;src:url(fonts/KaTeX_SansSerif-Italic.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Italic.woff) format("woff"),url(fonts/KaTeX_SansSerif-Italic.ttf) format("truetype")}@font-face{font-display:block;font-family:"KaTeX_SansSerif";font-style:normal;font-weight:400;src:url(fonts/KaTeX_SansSerif-Regular.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Regular.woff) format("woff"),url(fonts/KaTeX_SansSerif-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Script-Regular.woff2) format("woff2"),url(fonts/KaTeX_Script-Regular.woff) format("woff"),url(fonts/KaTeX_Script-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size1-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size1-Regular.woff) format("woff"),url(fonts/KaTeX_Size1-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size2-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size2-Regular.woff) format("woff"),url(fonts/KaTeX_Size2-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size3-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size3-Regular.woff) format("woff"),url(fonts/KaTeX_Size3-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size4-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size4-Regular.woff) format("woff"),url(fonts/KaTeX_Size4-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Typewriter-Regular.woff2) format("woff2"),url(fonts/KaTeX_Typewriter-ReguLine truncated
@font-face{font-display:block;font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url(fonts/KaTeX_AMS-Regular.woff2) format("woff2"),url(fonts/KaTeX_AMS-Regular.woff) format("woff"),url(fonts/KaTeX_AMS-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Caligraphic-Bold.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Bold.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Bold.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Caligraphic-Regular.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Regular.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Fraktur-Bold.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Bold.woff) format("woff"),url(fonts/KaTeX_Fraktur-Bold.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Fraktur-Regular.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Regular.woff) format("woff"),url(fonts/KaTeX_Fraktur-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Main-Bold.woff2) format("woff2"),url(fonts/KaTeX_Main-Bold.woff) format("woff"),url(fonts/KaTeX_Main-Bold.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Main-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Main-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Main-BoldItalic.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Main-Italic.woff2) format("woff2"),url(fonts/KaTeX_Main-Italic.woff) format("woff"),url(fonts/KaTeX_Main-Italic.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Main-Regular.woff2) format("woff2"),url(fonts/KaTeX_Main-Regular.woff) format("woff"),url(fonts/KaTeX_Main-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Math-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Math-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Math-BoldItalic.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Math-Italic.woff2) format("woff2"),url(fonts/KaTeX_Math-Italic.woff) format("woff"),url(fonts/KaTeX_Math-Italic.ttf) format("truetype")}@font-face{font-display:block;font-family:"KaTeX_SansSerif";font-style:normal;font-weight:700;src:url(fonts/KaTeX_SansSerif-Bold.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Bold.woff) format("woff"),url(fonts/KaTeX_SansSerif-Bold.ttf) format("truetype")}@font-face{font-display:block;font-family:"KaTeX_SansSerif";font-style:italic;font-weight:400;src:url(fonts/KaTeX_SansSerif-Italic.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Italic.woff) format("woff"),url(fonts/KaTeX_SansSerif-Italic.ttf) format("truetype")}@font-face{font-display:block;font-family:"KaTeX_SansSerif";font-style:normal;font-weight:400;src:url(fonts/KaTeX_SansSerif-Regular.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Regular.woff) format("woff"),url(fonts/KaTeX_SansSerif-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Script-Regular.woff2) format("woff2"),url(fonts/KaTeX_Script-Regular.woff) format("woff"),url(fonts/KaTeX_Script-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size1-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size1-Regular.woff) format("woff"),url(fonts/KaTeX_Size1-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size2-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size2-Regular.woff) format("woff"),url(fonts/KaTeX_Size2-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size3-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size3-Regular.woff) format("woff"),url(fonts/KaTeX_Size3-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size4-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size4-Regular.woff) format("woff"),url(fonts/KaTeX_Size4-Regular.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Typewriter-Regular.woff2) format("woff2"),url(fonts/KaTeX_Typewriter-ReguLine truncated
+1 -1
View File
@@ -1 +1 @@
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.katex=t():e.katex=t()}("undefined"!=typeof self?self:this,function(){return function(){"use strict";var e={d:function(t,r){for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}},t={};e.d(t,{default:function(){return mo}});class r extends Error{constructor(e,t){let n,o,s="KaTeX parse error: "+e;const i=t&&t.loc;if(i&&i.start<=i.end){const e=i.lexer.input;n=i.start,o=i.end,n===e.length?s+=" at end of input: ":s+=" at position "+(n+1)+": ";const t=e.slice(n,o).replace(/[^]/g,"$&\u0332");let r,l;r=n>15?"\u2026"+e.slice(n-15,n):e.slice(0,n),l=o+15<e.length?e.slice(o,o+15)+"\u2026":e.slice(o),s+=r+t+l}super(s),this.name="ParseError",this.position=void 0,this.length=void 0,this.rawMessage=void 0,Object.setPrototypeOf(this,r.prototype),this.position=n,null!=n&&null!=o&&(this.length=o-n),this.rawMessage=e}}var n=r;const o=/([A-Z])/g,s=e=>e.replace(o,"-$1").toLowerCase(),i={"&":"&amp;",">":"&gt;","<":"&lt;",'"':"&quot;","'":"&#x27;"},l=/[&><"']/g,a=e=>String(e).replace(l,e=>i[e]),c=e=>"ordgroup"===e.type||"color"===e.type?1===e.body.length?c(e.body[0]):e:"font"===e.type?c(e.body):e,h=new Set(["mathord","textord","atom"]),m=e=>h.has(c(e).type),u={displayMode:{type:"boolean",description:"Render math in display mode, which puts the math in display style (so \\int and \\sum are large, for example), and centers the math on the page on its own line.",cli:"-d, --display-mode"},output:{type:{enum:["htmlAndMathml","html","mathml"]},description:"Determines the markup language of the output.",cli:"-F, --format <type>"},leqno:{type:"boolean",description:"Render display math in leqno style (left-justified tags)."},fleqn:{type:"boolean",description:"Render display math flush left."},throwOnError:{type:"boolean",default:!0,cli:"-t, --no-throw-on-error",cliDescription:"Render errors (in the color given by --error-color) instead of throwing a ParseError exception when encountering an error."},errorColor:{type:"string",default:"#cc0000",cli:"-c, --error-color <color>",cliDescription:"A color string given in the format 'rgb' or 'rrggbb' (no #). This option determines the color of errors rendered by the -t option.",cliProcessor:e=>"#"+e},macros:{type:"object",cli:"-m, --macro <def>",cliDescription:"Define custom macro of the form '\\foo:expansion' (use multiple -m arguments for multiple macros).",cliDefault:[],cliProcessor:(e,t)=>(t.push(e),t)},minRuleThickness:{type:"number",description:"Specifies a minimum thickness, in ems, for fraction lines, `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, `\\hdashline`, `\\underline`, `\\overline`, and the borders of `\\fbox`, `\\boxed`, and `\\fcolorbox`.",processor:e=>Math.max(0,e),cli:"--min-rule-thickness <size>",cliProcessor:parseFloat},colorIsTextColor:{type:"boolean",description:"Makes \\color behave like LaTeX's 2-argument \\textcolor, instead of LaTeX's one-argument \\color mode change.",cli:"-b, --color-is-text-color"},strict:{type:[{enum:["warn","ignore","error"]},"boolean","function"],description:"Turn on strict / LaTeX faithfulness mode, which throws an error if the input uses features that are not supported by LaTeX.",cli:"-S, --strict",cliDefault:!1},trust:{type:["boolean","function"],description:"Trust the input, enabling all HTML features such as \\url.",cli:"-T, --trust"},maxSize:{type:"number",default:1/0,description:"If non-zero, all user-specified sizes, e.g. in \\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, elements and spaces can be arbitrarily large",processor:e=>Math.max(0,e),cli:"-s, --max-size <n>",cliProcessor:parseInt},maxExpand:{type:"number",default:1e3,description:"Limit the number of macro expansions to the specified number, to prevent e.g. infinite macro loops. If set to Infinity, the macro expander will try to fully expand as in LaTeX.",processor:e=>Math.max(0,e),cli:"-e, --max-expand <n>",cliProcessor:e=>"Infinity"===e?1/0:parseInt(e)},globalGroup:{type:"boolean",cli:!1}};function p(e){if(Object.prototype.hasOwnProperty.call(e,"default")&&void 0!==e.default)return e.default;return function(e){if("string"!=typeof e)return e.enum[0];switch(e){case"boolean":return!1;case"string":return"";case"number":return 0;case"object":return{};default:throw new Error("Unexpected schema type; settings must declare an explicit default.")}}(Array.isArray(e.type)?e.type[0]:e.type)}function d(e,t,r,n){const o=Object.prototype.hasOwnProperty.call(r,t)?r[t]:void 0,s=Object.prototype.hasOwnProperty.call(n,"processor")?n.processor:void 0;e[t]=void 0!==o?s?s(o):o:p(n)}class g{constructor(e){void 0===e&&(e={}),this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextCLine truncated
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.katex=t():e.katex=t()}("undefined"!=typeof self?self:this,function(){return function(){"use strict";var e={d:function(t,r){for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}},t={};e.d(t,{default:function(){return uo}});class r extends Error{constructor(e,t){let n,o,s="KaTeX parse error: "+e;const i=t&&t.loc;if(i&&i.start<=i.end){const e=i.lexer.input;n=i.start,o=i.end,n===e.length?s+=" at end of input: ":s+=" at position "+(n+1)+": ";const t=e.slice(n,o).replace(/[^]/g,"$&\u0332");let r,a;r=n>15?"\u2026"+e.slice(n-15,n):e.slice(0,n),a=o+15<e.length?e.slice(o,o+15)+"\u2026":e.slice(o),s+=r+t+a}super(s),this.name="ParseError",this.position=void 0,this.length=void 0,this.rawMessage=void 0,Object.setPrototypeOf(this,r.prototype),this.position=n,null!=n&&null!=o&&(this.length=o-n),this.rawMessage=e}}var n=r;const o=/([A-Z])/g,s=e=>e.replace(o,"-$1").toLowerCase(),i={"&":"&amp;",">":"&gt;","<":"&lt;",'"':"&quot;","'":"&#x27;"},a=/[&><"']/g,l=e=>String(e).replace(a,e=>i[e]),c=e=>"ordgroup"===e.type||"color"===e.type?1===e.body.length?c(e.body[0]):e:"font"===e.type?c(e.body):e,h=new Set(["mathord","textord","atom"]),m=e=>h.has(c(e).type),u={displayMode:{type:"boolean",description:"Render math in display mode, which puts the math in display style (so \\int and \\sum are large, for example), and centers the math on the page on its own line.",cli:"-d, --display-mode"},output:{type:{enum:["htmlAndMathml","html","mathml"]},description:"Determines the markup language of the output.",cli:"-F, --format <type>"},leqno:{type:"boolean",description:"Render display math in leqno style (left-justified tags)."},fleqn:{type:"boolean",description:"Render display math flush left."},throwOnError:{type:"boolean",default:!0,cli:"-t, --no-throw-on-error",cliDescription:"Render errors (in the color given by --error-color) instead of throwing a ParseError exception when encountering an error."},errorColor:{type:"string",default:"#cc0000",cli:"-c, --error-color <color>",cliDescription:"A color string given in the format 'rgb' or 'rrggbb' (no #). This option determines the color of errors rendered by the -t option.",cliProcessor:e=>"#"+e},macros:{type:"object",cli:"-m, --macro <def>",cliDescription:"Define custom macro of the form '\\foo:expansion' (use multiple -m arguments for multiple macros).",cliDefault:[],cliProcessor:(e,t)=>(t.push(e),t)},minRuleThickness:{type:"number",description:"Specifies a minimum thickness, in ems, for fraction lines, `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, `\\hdashline`, `\\underline`, `\\overline`, and the borders of `\\fbox`, `\\boxed`, and `\\fcolorbox`.",processor:e=>Math.max(0,e),cli:"--min-rule-thickness <size>",cliProcessor:parseFloat},colorIsTextColor:{type:"boolean",description:"Makes \\color behave like LaTeX's 2-argument \\textcolor, instead of LaTeX's one-argument \\color mode change.",cli:"-b, --color-is-text-color"},strict:{type:[{enum:["warn","ignore","error"]},"boolean","function"],description:"Turn on strict / LaTeX faithfulness mode, which throws an error if the input uses features that are not supported by LaTeX.",cli:"-S, --strict",cliDefault:!1},trust:{type:["boolean","function"],description:"Trust the input, enabling all HTML features such as \\url.",cli:"-T, --trust"},maxSize:{type:"number",default:1/0,description:"If non-zero, all user-specified sizes, e.g. in \\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, elements and spaces can be arbitrarily large",processor:e=>Math.max(0,e),cli:"-s, --max-size <n>",cliProcessor:parseInt},maxExpand:{type:"number",default:1e3,description:"Limit the number of macro expansions to the specified number, to prevent e.g. infinite macro loops. If set to Infinity, the macro expander will try to fully expand as in LaTeX.",processor:e=>Math.max(0,e),cli:"-e, --max-expand <n>",cliProcessor:e=>"Infinity"===e?1/0:parseInt(e)},globalGroup:{type:"boolean",cli:!1}};function p(e){if(Object.prototype.hasOwnProperty.call(e,"default")&&void 0!==e.default)return e.default;return function(e){if("string"!=typeof e)return e.enum[0];switch(e){case"boolean":return!1;case"string":return"";case"number":return 0;case"object":return{};default:throw new Error("Unexpected schema type; settings must declare an explicit default.")}}(Array.isArray(e.type)?e.type[0]:e.type)}function d(e,t,r,n){const o=Object.prototype.hasOwnProperty.call(r,t)?r[t]:void 0,s=Object.prototype.hasOwnProperty.call(n,"processor")?n.processor:void 0;e[t]=void 0!==o?s?s(o):o:p(n)}class g{constructor(e){void 0===e&&(e={}),this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextCLine truncated
+1620 -9
View File
File diff suppressed because it is too large. Load diff
@@ -58,6 +58,27 @@ Blowfish was built so it would be easy to add visual support to your articles. I
Blowfish is optimised for full multilingual websites and theme assets are translated into several languages out of the box. The language configuration allows you to generate multiple versions of your content to provide a customised experience to your visitors in their native language.
### 404 page quotes
The 404 page displays a random movie quote in the active site language. You can replace the bundled quotes by adding a `data/quotes404.json` file to your site. Each item needs a `line` and `source`; use `lang` to target a language. Language codes may be full codes such as `pt-PT` or base codes such as `pt`. Quotes without `lang` are treated as English for backwards compatibility.
```json
[
{
"lang": "en",
"line": "You shall not pass!",
"source": "The Fellowship of the Ring (2001)"
},
{
"lang": "pt-PT",
"line": "Não passarás!",
"source": "The Fellowship of the Ring (2001)"
}
]
```
Blowfish tries an exact language match, then the base language, then English. If none are available, it selects from any configured quote.
The theme currently supports the following languages by default:
| Language | Code |
+20 -1
View File
@@ -29,7 +29,26 @@
</div>
{{ with hugo.Data.quotes404 }}
{{ $json := . | jsonify }}
{{/* Pick the current language's quotes at build time: exact locale
first, then base language, then English. Quotes without a lang are
treated as English to preserve existing custom overrides. */}}
{{ $lang := lower site.Language.Lang }}
{{ $base := index (split $lang "-") 0 }}
{{ $localized := slice }}
{{ $english := slice }}
{{ range . }}
{{ $qlang := lower (.lang | default "en") }}
{{ if or (eq $qlang $lang) (eq $qlang $base) }}
{{ $localized = $localized | append . }}
{{ end }}
{{ if eq $qlang "en" }}
{{ $english = $english | append . }}
{{ end }}
{{ end }}
{{ $quotes := $localized }}
{{ if not $quotes }}{{ $quotes = $english }}{{ end }}
{{ if not $quotes }}{{ $quotes = . }}{{ end }}
{{ $json := $quotes | jsonify }}
<script>
(function () {
var quotes = JSON.parse({{ $json }});
+11 -27
View File
@@ -62,32 +62,16 @@
{{ end }}
</body>
{{ if site.Params.buymeacoffee.globalWidget | default false }}
{{/* Inject the third-party widget after the page is idle so it never
competes with rendering-critical resources. */}}
<script>
(function () {
var load = function () {
var s = document.createElement("script");
s.src = "https://cdnjs.buymeacoffee.com/1.0.0/widget.prod.min.js";
s.setAttribute("data-name", "BMC-Widget");
s.setAttribute("data-cfasync", "false");
s.setAttribute("data-id", {{ site.Params.buymeacoffee.identifier }});
s.setAttribute("data-description", "Support me on Buy me a coffee!");
{{ with site.Params.buymeacoffee.globalWidgetMessage }}s.setAttribute("data-message", {{ . }});{{ end }}
s.setAttribute("data-color", {{ site.Params.buymeacoffee.globalWidgetColor | default `#FFDD00` }});
{{ with site.Params.buymeacoffee.globalWidgetPosition }}s.setAttribute("data-position", {{ . }});{{ end }}
s.setAttribute("data-x_margin", "18");
s.setAttribute("data-y_margin", "18");
document.body.appendChild(s);
};
if ("requestIdleCallback" in window) {
requestIdleCallback(load, { timeout: 4000 });
} else {
window.addEventListener("load", function () {
setTimeout(load, 1500);
});
}
})();
</script>
<script
data-name="BMC-Widget"
data-cfasync="false"
src="https://cdnjs.buymeacoffee.com/1.0.0/widget.prod.min.js"
data-id="{{ site.Params.buymeacoffee.identifier }}"
data-description="Support me on Buy me a coffee!"
{{ with site.Params.buymeacoffee.globalWidgetMessage }}data-message="{{ . }}"{{ end }}
{{ with site.Params.buymeacoffee.globalWidgetColor | default `#FFDD00` }}data-color="{{ . }}"{{ end }}
{{ with site.Params.buymeacoffee.globalWidgetPosition }}data-position="{{ . }}"{{ end }}
data-x_margin="18"
data-y_margin="18"></script>
{{ end }}
</html>
@@ -98,7 +98,7 @@
loading="lazy"
decoding="async"
fetchpriority="low"
class="not-prose absolute inset-0 h-full w-full object-cover transition-transform duration-700 ease-[cubic-bezier(0.22,1,0.36,1)] {{ if $featureImageHover }}group-hover:scale-[1.03]{{ end }}"
class="nozoom not-prose absolute inset-0 h-full w-full object-cover transition-transform duration-700 ease-[cubic-bezier(0.22,1,0.36,1)] {{ if $featureImageHover }}group-hover:scale-[1.03]{{ end }}"
{{ with $featureImagePosition }}style="object-position: {{ . }};"{{ end }} />
</div>
{{ end }}
@@ -74,7 +74,7 @@
loading="lazy"
decoding="async"
fetchpriority="low"
class="not-prose absolute inset-0 h-full w-full object-cover transition-transform duration-700 ease-[cubic-bezier(0.22,1,0.36,1)] {{ if $featureImageHover }}group-hover:scale-[1.03]{{ end }}"
class="nozoom not-prose absolute inset-0 h-full w-full object-cover transition-transform duration-700 ease-[cubic-bezier(0.22,1,0.36,1)] {{ if $featureImageHover }}group-hover:scale-[1.03]{{ end }}"
{{ with $featureImagePosition }}style="object-position: {{ . }};"{{ end }} />
</div>
{{ end }}
+1 -1
View File
@@ -78,7 +78,7 @@
loading="lazy"
decoding="async"
fetchpriority="low"
class="not-prose absolute inset-0 h-full w-full object-cover transition-transform duration-700 ease-[cubic-bezier(0.22,1,0.36,1)] {{ if $featureImageHover }}group-hover:scale-[1.03]{{ end }}"
class="nozoom not-prose absolute inset-0 h-full w-full object-cover transition-transform duration-700 ease-[cubic-bezier(0.22,1,0.36,1)] {{ if $featureImageHover }}group-hover:scale-[1.03]{{ end }}"
{{ with $featureImagePosition }}style="object-position: {{ . }};"{{ end }} />
</div>
{{ end }}
+1 -1
View File
@@ -91,7 +91,7 @@
loading="lazy"
decoding="async"
fetchpriority="low"
class="not-prose absolute inset-0 h-full w-full object-cover transition-transform duration-700 ease-[cubic-bezier(0.22,1,0.36,1)] {{ if $featureImageHover }}group-hover:scale-[1.03]{{ end }}"
class="nozoom not-prose absolute inset-0 h-full w-full object-cover transition-transform duration-700 ease-[cubic-bezier(0.22,1,0.36,1)] {{ if $featureImageHover }}group-hover:scale-[1.03]{{ end }}"
{{ with $featureImagePosition }}style="object-position: {{ . }};"{{ end }} />
</div>
{{ end }}
-9
View File
@@ -60,15 +60,6 @@
</p>
{{ end }}
</div>
{{ if not .Site.Params.disableImageZoom | default true }}
<script>
mediumZoom(document.querySelectorAll("img:not(.nozoom)"), {
margin: 24,
background: "rgba(0,0,0,0.5)",
scrollOffset: 0,
});
</script>
{{ end }}
{{/* Extend footer - eg. for extra scripts, etc. */}}
{{ if templates.Exists "partials/extend-footer.html" }}
{{ partialCached "extend-footer.html" . }}
+3 -3
View File
@@ -157,6 +157,8 @@
{{ if not .Site.Params.disableImageZoom | default true }}
{{ $zoomJS := resources.Get "lib/zoom/zoom.min.umd.js" | resources.Fingerprint $alg }}
<script defer src="{{ $zoomJS.RelPermalink }}" integrity="{{ $zoomJS.Data.Integrity }}"></script>
{{ $zoomInit := resources.Get "js/medium-zoom.js" | resources.Fingerprint $alg }}
<script defer src="{{ $zoomInit.RelPermalink }}" integrity="{{ $zoomInit.Data.Integrity }}"></script>
{{ end }}
{{ $showReadingProgress := site.Params.article.showReadingProgress | default false }}
{{ if isset .Params "showreadingprogress" }}
@@ -186,9 +188,7 @@
{{ if .Site.Params.rtl | default false }}
{{ $jsResources = $jsResources | append (resources.Get "js/rtl.js") }}
{{ end }}
{{ if .Page.HasShortcode "katex" }}
{{ $jsResources = $jsResources | append (resources.Get "js/katex-render.js") }}
{{ end }}
{{ $jsResources = $jsResources | append (resources.Get "js/katex-render.js") }}
{{ $jsResources = $jsResources | append (resources.Get "js/menu-a11y.js") }}
{{ $jsResources = $jsResources | append (resources.Get "js/print-support.js") }}
{{ $jsResources = $jsResources | append (resources.Get "js/email.js") }}
@@ -77,7 +77,7 @@
</a>
</div>
<div class="menuhide">
<div class="pt-2 p-5 mt-2 rounded-xl border border-neutral-200/80 bg-neutral/95 shadow-2xl shadow-neutral-900/20 dark:border-neutral-700/80 dark:bg-neutral-800/95">
<div class="p-5 mt-2 rounded-xl border border-neutral-200/80 bg-neutral/95 shadow-2xl shadow-neutral-900/20 dark:border-neutral-700/80 dark:bg-neutral-800/95">
<div class="flex flex-col space-y-3">
{{ range .Children }}
<a
@@ -1,5 +1,5 @@
{{ $mobileMenuStyle := .Site.Params.header.mobileMenuStyle | default "fullscreen" }}
<div class="mobile-header-row relative flex items-center h-14 gap-4">
<div class="mobile-header-row{{ if eq $mobileMenuStyle "fullscreen" }} mobile-menu-fullscreen{{ end }} relative flex items-center h-14 gap-4">
{{ if hugo.IsMultilingual }}
{{ partial "header/components/translations.html" . }}
{{ end }}
+1 -1
View File
@@ -49,7 +49,7 @@
loading="lazy"
decoding="async"
fetchpriority="low"
class="not-prose absolute inset-0 h-full w-full object-cover transition-transform duration-700 ease-[cubic-bezier(0.22,1,0.36,1)] {{ if $featureImageHover }}group-hover:scale-[1.03]{{ end }}"
class="nozoom not-prose absolute inset-0 h-full w-full object-cover transition-transform duration-700 ease-[cubic-bezier(0.22,1,0.36,1)] {{ if $featureImageHover }}group-hover:scale-[1.03]{{ end }}"
{{ with $featureImagePosition }}style="object-position: {{ . }};"{{ end }} />
</figure>
{{ end }}
+6 -6
View File
@@ -1,12 +1,12 @@
{
"name": "hugo-blowfish-theme",
"version": "3.0.0",
"version": "3.3.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "hugo-blowfish-theme",
"version": "3.0.0",
"version": "3.3.0",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
@@ -20,7 +20,7 @@
"@tailwindcss/typography": "^0.5.20",
"chart.js": "^4.5.1",
"fuse.js": "~7.5.0",
"katex": "^0.18.2",
"katex": "^0.18.4",
"lite-youtube-embed": "^0.3.4",
"medium-zoom": "^1.1.0",
"mermaid": "^11.16.0",
@@ -2402,9 +2402,9 @@
}
},
"node_modules/katex": {
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/katex/-/katex-0.18.2.tgz",
"integrity": "sha512-3snve4y0SXTMequLim1FMiPvLGElySam0blN5xQZBqEY3lOJz1TnuaaiugnBZBqHzlSAGmFTYL7MCQkORuLKCA==",
"version": "0.18.4",
"resolved": "https://registry.npmjs.org/katex/-/katex-0.18.4.tgz",
"integrity": "sha512-IMPntbRLOU+eu88XDiFKqQ8Akhr9Tv7jDMXqPhjG9SI1JMA4DIgXk4x9k4skJz2NZJXBRbC+2pYBLj9olqcZow==",
"dev": true,
"funding": [
"https://opencollective.com/katex",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "hugo-blowfish-theme",
"version": "3.0.0",
"version": "3.4.0",
"description": "Blowfish theme for Hugo.",
"scripts": {
"postinstall": "vendor-copy",
@@ -40,7 +40,7 @@
"@tailwindcss/typography": "^0.5.20",
"chart.js": "^4.5.1",
"fuse.js": "~7.5.0",
"katex": "^0.18.2",
"katex": "^0.18.4",
"lite-youtube-embed": "^0.3.4",
"medium-zoom": "^1.1.0",
"mermaid": "^11.16.0",