Skip to content

Conversation

@ZiuChen
Copy link

@ZiuChen ZiuChen commented Dec 11, 2025

This pull request adds targeted support for detecting and embedding fonts from popular math rendering libraries such as KaTeX and MathJax. The main change is the improved ability to recognize stylesheets from these libraries as font providers, ensuring that their fonts are properly embedded even when loaded from various CDNs. The update also introduces comprehensive tests to verify this behavior for multiple CDN sources.

Font detection improvements:

  • Added a new constant FONT_LIBRARIES to src/modules/fonts.js that lists common libraries (katex, mathjax, mathml) known to provide web fonts.
  • Updated the isLikelyFontStylesheet function in src/modules/fonts.js to recognize stylesheets from these libraries by checking the stylesheet path for library names, improving cross-origin font detection for math rendering libraries.

Testing enhancements:

Fixed: #344

@ZiuChen
Copy link
Author

ZiuChen commented Dec 11, 2025

Perhaps we could solve this problem more universally by introducing a new Plugin Hook like beforeFontCollection ?

I'm not entirely sure, this might increase complexity, but in the future if others have similar needs, they won't need to frequently submit PRs to the repository.

GPT's answer about introducing a new Plugin Hook like beforeFontCollection:

Details

@copilot Can this be solved using the existing Plugin mechanism? Or is it difficult to achieve by extending the existing Plugin mechanism? Please evaluate.

From a technical perspective, the existing Plugin mechanism cannot directly solve this problem for the following reasons:

Why Plugins Cannot Solve This

  1. The problem occurs before the core font collection stage

    • isLikelyFontStylesheet is called inside the embedCustomFonts function (occurs at line 125 of captureDOM)
    • Plugin hooks can run at beforeSnap/afterClone stages but cannot influence the internal logic of embedCustomFonts
    • This is a filtering decision problem, not a DOM modification problem
  2. Font embedding is a core feature, not an optional extension

    • embedCustomFonts is a core module directly called in the capture process
    • It needs to access all <link> tags and decide which ones to process
    • Plugins cannot intercept or modify this decision logic

If Implementing Through Plugin Mechanism Extension

The following major changes would be required:

  1. Add new hooks: beforeFontCollection(context) or fontStylesheetFilter(url, context)

    • Allow plugins to register additional URL filtering rules
    • Need to modify embedCustomFonts to support reading custom rules from context
  2. Modify the embedCustomFonts function:

    // In isLikelyFontStylesheet, need:
    const customFilters = context.plugins?.flatMap(p => p.fontStylesheetFilters || [])
    if (customFilters.some(filter => filter(href))) return true
  3. Users need to register plugins:

    snapdom.plugins({
      name: 'katex-fonts',
      fontStylesheetFilters: [
        (url) => url.includes('katex') || url.includes('mathjax')
      ]
    })

Difficulty Assessment

  • Implementation difficulty: Medium (requires modifying core API and adding new hooks)
  • Maintenance cost: High (increases API complexity)
  • Backward compatibility: Requires careful handling
  • Compared to direct fix: The current direct fix solution is simpler and more efficient

Conclusion

The current direct fix solution (adding FONT_LIBRARIES check in isLikelyFontStylesheet) is the better solution:

  • ✅ Minimal code changes (6 lines)
  • ✅ Zero additional configuration
  • ✅ Immediately effective for all users
  • ✅ No need to learn new APIs
  • ✅ Covers common usage scenarios (KaTeX, MathJax, MathML)

The Plugin mechanism is more suitable for handling optional, user-specific extension features rather than fixing bugs in core functionality.

@tinchox5
Copy link
Member

Hi @ZiuChen thank you for this proposal! I think MathJax is working good without using need to embed special fonts. AS you know I'm still stuck with my moving but please point this PR to dev branch

@ZiuChen ZiuChen changed the base branch from main to dev December 12, 2025 00:34
@ZiuChen
Copy link
Author

ZiuChen commented Dec 12, 2025

Of course, I have changed the target branch to the dev branch. Please review the code at your convenience.

The temporary solution is to patch snapdom (this is what I'm currently doing).

But in the long term, I hope to introduce a similar whitelist mechanism, because there will definitely be users who inject font support libraries like KateX through CDN addresses.

Best regards :D

@ZiuChen ZiuChen closed this Dec 12, 2025
@ZiuChen ZiuChen force-pushed the fix/remote-katex-font branch from f7062f8 to bcb719a Compare December 12, 2025 01:04
…tylesheets

- Added unit tests for KaTeX and MathJax font support
@ZiuChen ZiuChen reopened this Dec 12, 2025
@ZiuChen
Copy link
Author

ZiuChen commented Dec 12, 2025

ZiuChen#1

GPT has provided the implementation for the new Plugin Hook feature.
Please review it at your convenience. Thank you very much!

@jiaopengzi
Copy link

@tinchox5 Can we merge this PR?

@tinchox5
Copy link
Member

Sorry! I had just landed in NYC and I need time to settle down

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Capturing screenshots of DOM elements containing KateX formulas, the output image lacks proper font styling in the formulas.

3 participants