gitea源码

math.ts 1.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. import {displayError} from './common.ts';
  2. import {queryElems} from '../utils/dom.ts';
  3. function targetElement(el: Element): {target: Element, displayAsBlock: boolean} {
  4. // The target element is either the parent "code block with loading indicator", or itself
  5. // It is designed to work for 2 cases (guaranteed by backend code):
  6. // * <pre class="code-block is-loading"><code class="language-math display">...</code></pre>
  7. // * <code class="language-math">...</code>
  8. return {
  9. target: el.closest('.code-block.is-loading') ?? el,
  10. displayAsBlock: el.classList.contains('display'),
  11. };
  12. }
  13. export async function initMarkupCodeMath(elMarkup: HTMLElement): Promise<void> {
  14. // .markup code.language-math'
  15. queryElems(elMarkup, 'code.language-math', async (el) => {
  16. const [{default: katex}] = await Promise.all([
  17. import(/* webpackChunkName: "katex" */'katex'),
  18. import(/* webpackChunkName: "katex" */'katex/dist/katex.css'),
  19. ]);
  20. const MAX_CHARS = 1000;
  21. const MAX_SIZE = 25;
  22. const MAX_EXPAND = 1000;
  23. const {target, displayAsBlock} = targetElement(el);
  24. if (target.hasAttribute('data-render-done')) return;
  25. const source = el.textContent;
  26. if (source.length > MAX_CHARS) {
  27. displayError(target, new Error(`Math source of ${source.length} characters exceeds the maximum allowed length of ${MAX_CHARS}.`));
  28. return;
  29. }
  30. try {
  31. const tempEl = document.createElement(displayAsBlock ? 'p' : 'span');
  32. katex.render(source, tempEl, {
  33. maxSize: MAX_SIZE,
  34. maxExpand: MAX_EXPAND,
  35. displayMode: displayAsBlock, // katex: true for display (block) mode, false for inline mode
  36. });
  37. target.replaceWith(tempEl);
  38. } catch (error) {
  39. displayError(target, error);
  40. }
  41. });
  42. }