Skip to content

Commit

Permalink
feat: KaTeX render compatibility #6
Browse files Browse the repository at this point in the history
  • Loading branch information
xinkeng0 committed Jul 10, 2023
1 parent eb933aa commit 92aff5a
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 56 deletions.
12 changes: 6 additions & 6 deletions console/src/editor/katex/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,16 @@ export const ExtensionKatexInline = Node.create({
parseHTML() {
return [
{
tag: "span[display-inline]",
tag: "span[math-inline]",
},
];
},

renderHTML({ HTMLAttributes }) {
return [
"span",
mergeAttributes(HTMLAttributes, { "display-inline": "" }),
`$${HTMLAttributes.content}$`,
mergeAttributes(HTMLAttributes, { "math-inline": "" }),
`${HTMLAttributes.content}`,
];
},

Expand Down Expand Up @@ -105,16 +105,16 @@ export const ExtensionKatexBlock = Node.create({
parseHTML() {
return [
{
tag: "div[display-block]",
tag: "div[math-display]",
},
];
},

renderHTML({ HTMLAttributes }) {
return [
"div",
mergeAttributes(HTMLAttributes, { "display-block": "" }),
`$$${HTMLAttributes.content}$$`,
mergeAttributes(HTMLAttributes, { "math-display": "" }),
`${HTMLAttributes.content}`,
];
},

Expand Down
9 changes: 9 additions & 0 deletions src/main/java/run/halo/katex/BasicConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package run.halo.katex;

import lombok.Data;

@Data
public class BasicConfig {
String inline_selector;
String display_selector;
}
48 changes: 23 additions & 25 deletions src/main/java/run/halo/katex/DefaultPostContentHandler.java
Original file line number Diff line number Diff line change
@@ -1,38 +1,36 @@
package run.halo.katex;

import com.google.common.base.Throwables;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
import run.halo.app.plugin.ReactiveSettingFetcher;
import run.halo.app.theme.ReactivePostContentHandler;

@Component
@RequiredArgsConstructor
@Slf4j
public class DefaultPostContentHandler implements ReactivePostContentHandler {

@Override
public Mono<PostContentContext> handle(PostContentContext postContent) {
private final ReactiveSettingFetcher reactiveSettingFetcher;

String katexScript = """
<link rel="stylesheet" href="/plugins/plugin-katex/assets/static/katex.min.css">
<script defer src="/plugins/plugin-katex/assets/static/katex.min.js"></script>
<script defer src="/plugins/plugin-katex/assets/static/contrib/auto-render.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
renderMathInElement(document.body, {
// customised options
// • auto-render specific keys, e.g.:
delimiters: [
{left: '$$', right: '$$', display: true},
{left: '$', right: '$', display: false},
{left: '\\(', right: '\\)', display: false},
{left: '\\[', right: '\\]', display: true}
],
// • rendering keys, e.g.:
throwOnError : false
});
});
</script>
""";
private static void injectJS(PostContentContext contentContext, String inline_selector,
String display_selector) {
String parsedKatexScript =
KaTeXJSInjector.getParsedKatexScript(inline_selector, display_selector);
contentContext.setContent(parsedKatexScript + "\n" + contentContext.getContent());
}

postContent.setContent(katexScript + "\n" + postContent.getContent());
return Mono.just(postContent);
@Override
public Mono<PostContentContext> handle(PostContentContext contentContext) {
return reactiveSettingFetcher.fetch("basic", BasicConfig.class).map(basicConfig -> {
injectJS(contentContext, basicConfig.getInline_selector(),
basicConfig.getDisplay_selector());
return contentContext;
}).onErrorResume(e -> {
log.error("KaTeX PostContent handle failed", Throwables.getRootCause(e));
return Mono.just(contentContext);
});
}
}
48 changes: 23 additions & 25 deletions src/main/java/run/halo/katex/DefaultSinglePageContentHandler.java
Original file line number Diff line number Diff line change
@@ -1,38 +1,36 @@
package run.halo.katex;

import com.google.common.base.Throwables;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
import run.halo.app.plugin.ReactiveSettingFetcher;
import run.halo.app.theme.ReactiveSinglePageContentHandler;

@Component
@RequiredArgsConstructor
@Slf4j
public class DefaultSinglePageContentHandler implements ReactiveSinglePageContentHandler {

@Override
public Mono<SinglePageContentContext> handle(SinglePageContentContext singlePageContentContext) {
private final ReactiveSettingFetcher reactiveSettingFetcher;

String katexScript = """
<link rel="stylesheet" href="/plugins/plugin-katex/assets/static/katex.min.css">
<script defer src="/plugins/plugin-katex/assets/static/katex.min.js"></script>
<script defer src="/plugins/plugin-katex/assets/static/contrib/auto-render.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
renderMathInElement(document.body, {
// customised options
// • auto-render specific keys, e.g.:
delimiters: [
{left: '$$', right: '$$', display: true},
{left: '$', right: '$', display: false},
{left: '\\(', right: '\\)', display: false},
{left: '\\[', right: '\\]', display: true}
],
// • rendering keys, e.g.:
throwOnError : false
});
});
</script>
""";
private static void injectJS(SinglePageContentContext contentContext, String inline_selector,
String display_selector) {
String parsedKatexScript =
KaTeXJSInjector.getParsedKatexScript(inline_selector, display_selector);
contentContext.setContent(parsedKatexScript + "\n" + contentContext.getContent());
}

singlePageContentContext.setContent(katexScript + "\n" + singlePageContentContext.getContent());
return Mono.just(singlePageContentContext);
@Override
public Mono<SinglePageContentContext> handle(SinglePageContentContext contentContext) {
return reactiveSettingFetcher.fetch("basic", BasicConfig.class).map(basicConfig -> {
injectJS(contentContext, basicConfig.getInline_selector(),
basicConfig.getDisplay_selector());
return contentContext;
}).onErrorResume(e -> {
log.error("KaTeX PostContent handle failed", Throwables.getRootCause(e));
return Mono.just(contentContext);
});
}
}
26 changes: 26 additions & 0 deletions src/main/java/run/halo/katex/KaTeXJSInjector.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package run.halo.katex;

public class KaTeXJSInjector {
static String getParsedKatexScript(String inline_selector, String display_selector) {
String katexScript = """
<link rel="stylesheet" href="/plugins/plugin-katex/assets/static/katex.min.css">
<script defer src="/plugins/plugin-katex/assets/static/katex.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
const postBody = document.body
const renderMath = (selector,displayMode) => {
const els = postBody.querySelectorAll(selector)
els.forEach((el) => {
katex.render(el.innerText, el, { displayMode })
})
}
if (postBody) {
renderMath("%s",false);
renderMath("%s",true);
}
});
</script>
""";
return String.format(katexScript, inline_selector, display_selector);
}
}
19 changes: 19 additions & 0 deletions src/main/resources/extensions/settings.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apiVersion: v1alpha1
kind: Setting
metadata:
name: plugin-katex-settings
spec:
forms:
- group: basic
label: 基本设置
formSchema:
- $formkit: text
name: inline_selector
label: 行内公式CSS选择器
value: "[math-inline]"
help: 用于匹配行内公式的CSS选择器
- $formkit: text
name: display_selector
label: 块级公式CSS选择器
value: "[math-display]"
help: 用于匹配块级公式的CSS选择器
2 changes: 2 additions & 0 deletions src/main/resources/plugin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ spec:
homepage: https://github.com/halo-sigs/plugin-katex
displayName: "KaTeX"
description: "为编辑器和文章渲染提供 KaTeX 支持"
settingName: plugin-katex-settings
configMapName: plugin-katex-configMap
license:
- name: "GPL-3.0"
url: "https://github.com/halo-sigs/plugin-katex/blob/main/LICENSE"

0 comments on commit 92aff5a

Please sign in to comment.