You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
5.6 KiB
156 lines
5.6 KiB
import './bootstrap.js'; |
|
/* |
|
* Welcome to your app's main JavaScript file! |
|
* |
|
* This file will be included onto the page via the importmap() Twig function, |
|
* which should already be in your base.html.twig. |
|
*/ |
|
|
|
// 01 - Base styles (theme, fonts, typography, reset) |
|
import './styles/01-base/fonts.css'; |
|
import './styles/01-base/theme.css'; |
|
import './styles/01-base/spacing.css'; |
|
import './styles/01-base/reset.css'; |
|
import './styles/01-base/typography.css'; |
|
|
|
// 02 - Layout (grid, header, navigation, main content) |
|
import './styles/02-layout/layout.css'; |
|
import './styles/02-layout/header.css'; |
|
|
|
// 03 - Components (reusable UI components) |
|
import './styles/03-components/button.css'; |
|
import './styles/03-components/cards-shared.css'; |
|
import './styles/03-components/card.css'; |
|
import './styles/03-components/dropdown.css'; |
|
import './styles/03-components/form.css'; |
|
import './styles/03-components/article.css'; |
|
import './styles/03-components/modal.css'; |
|
import './styles/03-components/notice.css'; |
|
import './styles/03-components/spinner.css'; |
|
import './styles/03-components/a2hs.css'; |
|
import './styles/03-components/og.css'; |
|
import './styles/03-components/nostr-previews.css'; |
|
import './styles/reading-lists.css'; |
|
import './styles/03-components/nip05-badge.css'; |
|
import './styles/03-components/picture-event.css'; |
|
import './styles/03-components/video-event.css'; |
|
import './styles/03-components/search.css'; |
|
import './styles/03-components/image-upload.css'; |
|
import './styles/03-components/zaps.css'; |
|
|
|
// 04 - Page-specific styles |
|
import './styles/04-pages/landing.css'; |
|
import './styles/04-pages/admin.css'; |
|
import './styles/04-pages/analytics.css'; |
|
import './styles/04-pages/author-media.css'; |
|
import './styles/04-pages/forum.css'; |
|
import './styles/04-pages/highlights.css'; |
|
import './styles/04-pages/discover.css'; |
|
|
|
// 05 - Utilities (last for highest specificity) |
|
import './styles/05-utilities/utilities.css'; |
|
|
|
console.log('This log comes from assets/app.js - welcome to AssetMapper! 🎉'); |
|
|
|
import 'katex/dist/katex.min.css'; |
|
import renderMathInElement from 'katex/dist/contrib/auto-render.mjs'; |
|
|
|
// Detect math blocks in text content while avoiding common currency patterns |
|
function hasRealMath(text) { |
|
if (!text) return false; |
|
const t = text; |
|
|
|
// Skip plain currency-like $123.45 or $ 1,234 patterns |
|
const currency = /\$\s*[\d.,]+(?:\b|\s)/g; |
|
|
|
// Detect LaTeX-style delimiters with likely math content inside |
|
const inlineDollar = /\$(?<body>(?:[^$\\]|\\.)+)\$/g; // $ ... $ |
|
const doubleDollar = /\$\$(?<body>(?:[^$\\]|\\.)+)\$\$/g; // $$ ... $$ |
|
const parenMath = /\\\((?<body>(?:[^\\]|\\.)+)\\\)/g; // \( ... \) |
|
const bracketMath = /\\\[(?<body>(?:[^\\]|\\.)+)\\\]/g; // \[ ... \] |
|
|
|
// Heuristic: content contains typical math tokens (command, ^, _, { }, fractions) |
|
const looksMathy = (s) => /\\[a-zA-Z]+|[\^_]|[{}]|\\frac|\\sum|\\int|\\lim|\\alpha|\\beta|\\gamma|\\rightarrow|\\matrm|\\mathrm|\\mathbb|\\mathbf/.test(s); |
|
|
|
// If text has only currency-like $... patterns and no delimiters, don't mark as math |
|
const hasNonCurrencyDollar = (() => { |
|
let m; |
|
// Any $...$ that isn't just numbers |
|
const dollarAny = /\$(?:[^$]+)\$/g; |
|
while ((m = dollarAny.exec(t)) !== null) { |
|
const inner = m[0].slice(1, -1); |
|
if (!/^\s*[\d.,]+\s*$/.test(inner) && looksMathy(inner)) return true; |
|
} |
|
return false; |
|
})(); |
|
|
|
// Check each delimiter type |
|
const checkDelim = (regex) => { |
|
let m; |
|
while ((m = regex.exec(t)) !== null) { |
|
const inner = m.groups?.body ?? ''; |
|
if (looksMathy(inner)) return true; |
|
} |
|
return false; |
|
}; |
|
|
|
if (checkDelim(doubleDollar)) return true; |
|
if (checkDelim(parenMath)) return true; |
|
if (checkDelim(bracketMath)) return true; |
|
if (hasNonCurrencyDollar) return true; |
|
|
|
// Also allow $...$ where the inner isn't currency and includes letters with math markers |
|
const inlineDollarLoose = /\$(?<body>[^$]+)\$/g; |
|
let m; |
|
while ((m = inlineDollarLoose.exec(t)) !== null) { |
|
const inner = m.groups?.body ?? ''; |
|
if (!/^\s*[\d.,]+\s*$/.test(inner) && /[A-Za-z]/.test(inner) && /[\^_{}]|\\[a-zA-Z]+/.test(inner)) return true; |
|
} |
|
|
|
return false; |
|
} |
|
|
|
document.addEventListener('DOMContentLoaded', () => { |
|
// Identify containers that may include math and add the .math class when detected |
|
const root = document.querySelector('.article-main'); // main article container |
|
const summaries = document.querySelectorAll('.lede'); // article summaries |
|
|
|
if (root && hasRealMath(root.textContent || '')) { |
|
root.classList.add('math'); |
|
} |
|
if (summaries && summaries.length) { |
|
summaries.forEach((summary) => { |
|
if (summary && hasRealMath(summary.textContent || '')) { |
|
summary.classList.add('math'); |
|
} |
|
}); |
|
} |
|
|
|
// Render KaTeX inside elements marked with .math |
|
const mathRoot = document.querySelector('.article-main.math'); |
|
const mathSummaries = document.querySelectorAll('.lede.math'); |
|
|
|
if (mathSummaries && mathSummaries.length) { |
|
mathSummaries.forEach((summary) => { |
|
renderMathInElement(summary, { |
|
delimiters: [ |
|
{ left: '$$', right: '$$', display: false }, |
|
{ left: '$', right: '$', display: false }, |
|
], |
|
throwOnError: false, // don’t explode on unknown commands |
|
}); |
|
}); |
|
} |
|
|
|
if (mathRoot) { |
|
renderMathInElement(mathRoot, { |
|
// Delimiters: inline $…$, display $$…$$ and the LaTeX \(…\)/\[…\] forms |
|
delimiters: [ |
|
{ left: '$$', right: '$$', display: true }, |
|
{ left: '$', right: '$', display: false }, |
|
{ left: '\\[', right: '\\]', display: true }, |
|
], |
|
throwOnError: false, // don’t explode on unknown commands |
|
}); |
|
} |
|
});
|
|
|