mirror of
https://github.com/imfing/hextra.git
synced 2025-08-23 16:46:37 -04:00
feat(math): support local katex assets and improve docs (#742)
* refactor(math): update LaTeX guide and enhance KaTeX integration - Revised the LaTeX documentation for clarity and improved structure, changing section titles and descriptions for better understanding. - Added support for chemistry expressions using the mhchem extension. - Introduced a new KaTeX CSS loader partial to streamline the integration of KaTeX, allowing for configurable remote or local asset loading. - Updated the head partial to utilize the new KaTeX loader, enhancing the flexibility of math rendering options. * refactor(mathjax): simplify MathJax script URL configuration - Removed the dynamic version assignment for MathJax and set a fixed version in the script URL for consistency and clarity. * docs(latex): enhance LaTeX guide and clarify chemistry expressions - Updated section titles for better clarity, changing "Supported Functions" to "Chemistry Expressions." - Improved description of the mhchem extension for rendering chemistry equations. - Removed redundant instructions regarding the passthrough extension in Hugo. - Corrected minor typographical errors in references to MathJax.
This commit is contained in:
@@ -3,32 +3,35 @@ title: "LaTeX"
|
|||||||
weight: 4
|
weight: 4
|
||||||
---
|
---
|
||||||
|
|
||||||
By default, \(\KaTeX\) is used for rendering LaTeX math expressions.
|
LaTeX math expressions are rendered using \(\KaTeX\) by default. Simply start including them in your Markdown content without any manual configurations.
|
||||||
No manual activation is needed, you can start using LaTeX math expressions in your Markdown content right away.
|
|
||||||
|
|
||||||
## Example
|
## Usage
|
||||||
|
|
||||||
Both inline and separate paragraph LaTeX math expressions are supported in the Markdown content.
|
You can use LaTeX for both inline expressions and for larger blocks of text.
|
||||||
|
|
||||||
### Inline
|
### Inline Math
|
||||||
|
|
||||||
|
To include an expression within a line of text, wrap it in `\(` and `\)` delimiters.
|
||||||
|
|
||||||
```markdown {filename="page.md"}
|
```markdown {filename="page.md"}
|
||||||
This \(\sigma(z) = \frac{1}{1 + e^{-z}}\) is inline.
|
This \(\sigma(z) = \frac{1}{1 + e^{-z}}\) is an inline expression.
|
||||||
```
|
```
|
||||||
|
|
||||||
This \( \sigma(z) = \frac{1}{1 + e^{-z}} \) is inline.
|
This \( \sigma(z) = \frac{1}{1 + e^{-z}} \) is an inline expression.
|
||||||
|
|
||||||
### Separate Paragraph
|
### Display Math
|
||||||
|
|
||||||
|
For expressions that you want to stand on their own in a separate paragraph, use `$$` delimiters.
|
||||||
|
|
||||||
```markdown {filename="page.md"}
|
```markdown {filename="page.md"}
|
||||||
$$F(\omega) = \int_{-\infty}^{\infty} f(t) e^{-j\omega t} \, dt$$
|
$$F(\omega) = \int_{-\infty}^{\infty} f(t)\, e^{-j \omega t} \, dt$$
|
||||||
```
|
```
|
||||||
|
|
||||||
will be rendered as:
|
will be rendered as:
|
||||||
|
|
||||||
$$F(\omega) = \int\_{-\infty}^{\infty} f(t) e^{-j\omega t} \, dt$$
|
$$F(\omega) = \int_{-\infty}^{\infty} f(t)\, e^{-j \omega t} \, dt$$
|
||||||
|
|
||||||
For example, using the aligned environment:
|
You can also use LaTeX environments like `aligned` for multi-line expressions.
|
||||||
|
|
||||||
```latex {filename="page.md"}
|
```latex {filename="page.md"}
|
||||||
$$
|
$$
|
||||||
@@ -52,6 +55,23 @@ $$
|
|||||||
\end{aligned}
|
\end{aligned}
|
||||||
$$
|
$$
|
||||||
|
|
||||||
|
For a list of supported functions, see [KaTeX supported functions](https://katex.org/docs/supported.html).
|
||||||
|
|
||||||
|
### Chemistry Expressions
|
||||||
|
|
||||||
|
The [mhchem][mhchem] extension is enabled by default, allowing you to easily render chemistry equations and formulas.
|
||||||
|
|
||||||
|
Inline: \(\ce{H2O}\) is water.
|
||||||
|
|
||||||
|
Separate paragraph:
|
||||||
|
|
||||||
|
```markdown {filename="page.md"}
|
||||||
|
$$\ce{Hg^2+ ->[I-] HgI2 ->[I-] [Hg^{II}I4]^2-}$$
|
||||||
|
```
|
||||||
|
|
||||||
|
will be rendered as:
|
||||||
|
|
||||||
|
$$\ce{Hg^2+ ->[I-] HgI2 ->[I-] [Hg^{II}I4]^2-}$$
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
@@ -69,35 +89,47 @@ markup:
|
|||||||
enable: true
|
enable: true
|
||||||
```
|
```
|
||||||
|
|
||||||
## Supported Functions
|
### Math Engine
|
||||||
|
|
||||||
For a list of supported functions, see [KaTeX supported functions](https://katex.org/docs/supported.html).
|
[KaTeX][katex] is the default engine used to render LaTeX math expressions during the build process supported by [Hugo][hugo-transform-tomath].
|
||||||
|
|
||||||
## Chemistry
|
The default is KaTeX, but you can also switch to [MathJax][mathjax] if you need features only available in MathJax.
|
||||||
|
|
||||||
Chemistry expressions are supported via [mhchem](https://mhchem.github.io/MathJax-mhchem/) extension.
|
#### KaTeX
|
||||||
|
|
||||||
Inline: \(\ce{H2O}\) is water.
|
The default setup requires no configuration. Hugo fetches the KaTeX CSS from the CDN.
|
||||||
|
If you need to pin a specific version of KaTeX or use local assets, you can do so in your `hugo.yaml` file.
|
||||||
|
|
||||||
Separate paragraph:
|
##### Override CDN base URL
|
||||||
|
|
||||||
```markdown {filename="page.md"}
|
```yaml {filename="hugo.yaml"}
|
||||||
$$\ce{Hg^2+ ->[I-] HgI2 ->[I-] [Hg^{II}I4]^2-}$$
|
params:
|
||||||
|
math:
|
||||||
|
engine: katex
|
||||||
|
katex:
|
||||||
|
base: "https://cdn.jsdelivr.net/npm/katex@0.16.22/dist"
|
||||||
```
|
```
|
||||||
|
|
||||||
will be rendered as:
|
##### Use local assets
|
||||||
|
|
||||||
$$\ce{Hg^2+ ->[I-] HgI2 ->[I-] [Hg^{II}I4]^2-}$$
|
You can also place the css file under `assets` and publish additional font files required by KaTeX.
|
||||||
|
|
||||||
|
```yaml {filename="hugo.yaml"}
|
||||||
|
params:
|
||||||
|
math:
|
||||||
|
engine: katex
|
||||||
|
katex:
|
||||||
|
css: "css/katex.min.css"
|
||||||
|
assets:
|
||||||
|
- "fonts/KaTeX_Main-Regular.woff2"
|
||||||
|
# Add other font files here
|
||||||
|
```
|
||||||
|
|
||||||
## Math Engine
|
It will load the KaTeX CSS file from `assets/css/katex.min.css` instead of downloading from CDN.
|
||||||
|
|
||||||
### MathJax
|
#### MathJax
|
||||||
|
|
||||||
By default, [KaTeX][katex] is used for rendering LaTeX math expressions during the build process, which is preferred.
|
Alternatively, you can use [MathJax][mathjax] to render math expressions:
|
||||||
Alternatively, you can use [MathJax][mathjax] to render math expressions.
|
|
||||||
|
|
||||||
To use it instead, add the following to the configuration `hugo.yaml` file:
|
|
||||||
|
|
||||||
```yaml {filename="hugo.yaml"}
|
```yaml {filename="hugo.yaml"}
|
||||||
params:
|
params:
|
||||||
@@ -105,5 +137,10 @@ params:
|
|||||||
engine: mathjax
|
engine: mathjax
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> You can further customize MathJax (for example, adjust loader options, or change the CDN/source) by overriding the template at `layouts/_partials/scripts/mathjax.html` in your project. Hugo will use your version instead of the theme's default.
|
||||||
|
|
||||||
[katex]: https://katex.org/
|
[katex]: https://katex.org/
|
||||||
[mathjax]: https://www.mathjax.org/
|
[mathjax]: https://www.mathjax.org/
|
||||||
|
[mhchem]: https://mhchem.github.io/MathJax-mhchem/
|
||||||
|
[hugo-transform-tomath]: https://gohugo.io/functions/transform/tomath/
|
||||||
|
@@ -83,27 +83,11 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- KaTeX-->
|
<!-- Math engine -->
|
||||||
{{ $noop := .WordCount -}}
|
{{ $noop := .WordCount -}}
|
||||||
{{- $engine := site.Params.math.engine | default "katex" -}}
|
{{- $engine := site.Params.math.engine | default "katex" -}}
|
||||||
{{ if and (.Page.Store.Get "hasMath") (eq $engine "katex") -}}
|
{{ if and (.Page.Store.Get "hasMath") (eq $engine "katex") -}}
|
||||||
<!-- TODO: make url configurable -->
|
{{ partialCached "scripts/katex.html" . -}}
|
||||||
{{ $katexBaseUrl := "https://cdn.jsdelivr.net/npm/katex@latest/dist" }}
|
|
||||||
{{ $katexCssUrl := printf "%s/katex%s.css" $katexBaseUrl (cond hugo.IsProduction ".min" "") -}}
|
|
||||||
{{ $katexFontPattern := "url(fonts/" }}
|
|
||||||
{{ $katexFontSubstituted := printf "url(%s/fonts/" $katexBaseUrl }}
|
|
||||||
|
|
||||||
{{ with try (resources.GetRemote $katexCssUrl) -}}
|
|
||||||
{{ with .Err -}}
|
|
||||||
{{ errorf "Could not retrieve KaTeX css file from %s. Reason: %s." $katexCssUrl . -}}
|
|
||||||
{{ else with .Value -}}
|
|
||||||
{{ $katexCssContent := strings.Replace .Content $katexFontPattern $katexFontSubstituted }}
|
|
||||||
{{ with resources.FromString (printf "css/katex%s.css" (cond hugo.IsProduction ".min" "")) $katexCssContent -}}
|
|
||||||
{{ $cssHash := . | fingerprint "sha512" -}}
|
|
||||||
<link rel="stylesheet" href="{{- .RelPermalink -}}" integrity="{{- $cssHash.Data.Integrity -}}" crossorigin="anonymous" />
|
|
||||||
{{ end -}}
|
|
||||||
{{ end -}}
|
|
||||||
{{ end -}}
|
|
||||||
{{ else if and (.Page.Store.Get "hasMath") (eq $engine "mathjax") -}}
|
{{ else if and (.Page.Store.Get "hasMath") (eq $engine "mathjax") -}}
|
||||||
{{ partialCached "scripts/mathjax.html" . -}}
|
{{ partialCached "scripts/mathjax.html" . -}}
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
|
88
layouts/_partials/scripts/katex.html
Normal file
88
layouts/_partials/scripts/katex.html
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
{{- /* KaTeX CSS loader
|
||||||
|
|
||||||
|
Behavior (driven by site.params.math.katex):
|
||||||
|
- base (remote URL) + optional css:
|
||||||
|
- Construct remote CSS URL: "{{ base }}/{{ css | default "katex[.min].css" }}".
|
||||||
|
- Fetch via resources.GetRemote, rewrite font URLs to "{{ base }}/fonts/...".
|
||||||
|
- Build and fingerprint; emit <link rel="stylesheet" integrity>.
|
||||||
|
- base (local path or not set) + css (asset path):
|
||||||
|
- Read CSS from Hugo assets via resources.Get; DO NOT rewrite font URLs.
|
||||||
|
- Build and fingerprint; emit <link rel="stylesheet" integrity>.
|
||||||
|
- base (local path) only (no css):
|
||||||
|
- Link directly to "{{ base }}/katex[.min].css" (no processing).
|
||||||
|
- Nothing set:
|
||||||
|
- Default to CDN latest base; same as remote path above.
|
||||||
|
|
||||||
|
Additional:
|
||||||
|
- assets: optional list to publish extra assets. CSS/JS get tags with integrity (JS loads async).
|
||||||
|
*/ -}}
|
||||||
|
{{- $noop := .WordCount -}}
|
||||||
|
|
||||||
|
{{- $katexBase := "https://cdn.jsdelivr.net/npm/katex@latest/dist" -}}
|
||||||
|
{{- with site.Params.math.katex.base -}}
|
||||||
|
{{- $katexBase = . -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- $katexCssAsset := "" -}}
|
||||||
|
{{- with site.Params.math.katex.css -}}
|
||||||
|
{{- $katexCssAsset = . -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- $s := newScratch -}}
|
||||||
|
{{- $isRemoteBase := or (strings.HasPrefix $katexBase "http://") (strings.HasPrefix $katexBase "https://") -}}
|
||||||
|
|
||||||
|
{{- /* CSS retrieval consolidated: get raw CSS from either local asset or remote, then process once */ -}}
|
||||||
|
{{- $minSuffix := cond hugo.IsProduction ".min" "" -}}
|
||||||
|
{{- if $isRemoteBase -}}
|
||||||
|
{{- $cssPath := cond (ne $katexCssAsset "") $katexCssAsset (printf "katex%s.css" $minSuffix) -}}
|
||||||
|
{{- $katexCssUrl := printf "%s/%s" $katexBase $cssPath -}}
|
||||||
|
{{- with try (resources.GetRemote $katexCssUrl) -}}
|
||||||
|
{{- with .Err -}}
|
||||||
|
{{- errorf "Could not retrieve KaTeX css file from %s. Reason: %s." $katexCssUrl . -}}
|
||||||
|
{{- else with .Value -}}
|
||||||
|
{{- $s.Set "katexCssValue" .Content -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- else if $katexCssAsset -}}
|
||||||
|
{{- with resources.Get $katexCssAsset -}}
|
||||||
|
{{- $s.Set "katexCssValue" .Content -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- errorf "KaTeX css asset not found at %q" $katexCssAsset -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- with $s.Get "katexCssValue" -}}
|
||||||
|
{{- $cssContent := . -}}
|
||||||
|
{{- if $isRemoteBase -}}
|
||||||
|
{{- $fontPattern := "url(fonts/" -}}
|
||||||
|
{{- $fontSub := printf "url(%s/fonts/" $katexBase -}}
|
||||||
|
{{- $cssContent = strings.Replace $cssContent $fontPattern $fontSub -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- with resources.FromString (printf "css/katex%s.css" $minSuffix) $cssContent -}}
|
||||||
|
{{- $css := . | fingerprint "sha512" -}}
|
||||||
|
<link rel="stylesheet" href="{{ $css.RelPermalink }}" integrity="{{ $css.Data.Integrity }}" />
|
||||||
|
{{- end -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- if not $isRemoteBase -}}
|
||||||
|
{{- $cssPath := cond (ne $katexCssAsset "") $katexCssAsset (printf "katex%s.css" $minSuffix) -}}
|
||||||
|
<link rel="stylesheet" href="{{ printf "%s/%s" $katexBase $cssPath }}" />
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- /* Optionally publish files (fonts, css, js, etc.) from assets and emit tags for css/js with integrity and crossorigin */ -}}
|
||||||
|
{{- with site.Params.math.katex.assets -}}
|
||||||
|
{{- range . -}}
|
||||||
|
{{- with resources.Get . -}}
|
||||||
|
{{- $name := .Name | lower -}}
|
||||||
|
{{- if strings.HasSuffix $name ".css" -}}
|
||||||
|
{{- $built := . | fingerprint "sha512" -}}
|
||||||
|
<link rel="stylesheet" href="{{ $built.RelPermalink }}" integrity="{{ $built.Data.Integrity }}" crossorigin="anonymous" />
|
||||||
|
{{- else if or (strings.HasSuffix $name ".js") (strings.HasSuffix $name ".mjs") -}}
|
||||||
|
{{- $built := . | fingerprint "sha512" -}}
|
||||||
|
<script src="{{ $built.RelPermalink }}" async integrity="{{ $built.Data.Integrity }}" crossorigin="anonymous"></script>
|
||||||
|
{{- else -}}
|
||||||
|
{{- .Publish -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
@@ -1,6 +1,5 @@
|
|||||||
{{/* MathJax */}}
|
{{/* MathJax */}}
|
||||||
{{ $mathjaxVersion := site.Params.math.mathjaxVersion | default "3" -}}
|
{{ $mathjaxJsUrl := "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js" -}}
|
||||||
{{ $mathjaxJsUrl := printf "https://cdn.jsdelivr.net/npm/mathjax@%s/es5/tex-chtml.js" $mathjaxVersion -}}
|
|
||||||
<script defer id="MathJax-script" src="{{ $mathjaxJsUrl }}" crossorigin="anonymous" async></script>
|
<script defer id="MathJax-script" src="{{ $mathjaxJsUrl }}" crossorigin="anonymous" async></script>
|
||||||
<script>
|
<script>
|
||||||
MathJax = {
|
MathJax = {
|
||||||
|
Reference in New Issue
Block a user