Skip to content

Commit

Permalink
feat!: use diplodoc/latex-extension instead of markdown-it-katex (#184)
Browse files Browse the repository at this point in the history
- added packages to peerDependencies: `@diplodoc/latex-extension`, `katex`, `markdown-it`
- editor's Math extension now use `@diplodoc/latex-extension` instead of `markdown-it-katex`
- Math extension removed from YfmPreset/YfmSpecsPreset and package root export
- added options to Math extension

Example of using a Math extension:

```js
import {Math} from '@doc-tools/yfm-editor/_/extensions/yfm/Math';

// ...

builder.use(Math, {
  // required
  loadRuntimeScript: async () => {
    await Promise.all([
      import('@diplodoc/latex-extension/runtime'),
      import('@diplodoc/latex-extension/runtime/styles'),
    ]);
  },
  // optional; if you need custom sanitizing
  sanitize: (html) => /* sanitize html */ html,
  // optional; options to be passed to katex
  katexOptions: {},
});
```
  • Loading branch information
d3m1d0v authored Feb 6, 2024
1 parent 881c181 commit 4b742c9
Show file tree
Hide file tree
Showing 15 changed files with 246 additions and 116 deletions.
31 changes: 27 additions & 4 deletions demo/HtmlPreview.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React from 'react';

import {useLatex} from '@diplodoc/latex-extension/react';
import transform from '@diplodoc/transform';

import {MarkupString, colorClassName} from '../src';
import type {ClassNameProps} from '../src/classname';

import {plugins} from './md-plugins';
import {LATEX_RUNTIME, plugins} from './md-plugins';

type PlaygroundHtmlPreviewProps = ClassNameProps & {
value: MarkupString;
Expand All @@ -15,20 +16,42 @@ type PlaygroundHtmlPreviewProps = ClassNameProps & {
linkifyTlds?: string | string[];
};

type Meta = {script?: string[]; style?: string[]};

export const PlaygroundHtmlPreview: React.FC<PlaygroundHtmlPreviewProps> =
function PlaygroundHtmlPreview({value, allowHTML, breaks, linkify, linkifyTlds, className}) {
const divRef = React.useRef<HTMLDivElement>(null);
const renderLatex = useLatex();

const html = React.useMemo(() => {
const result = React.useMemo(() => {
return transform(value, {
allowHTML,
breaks,
plugins,
linkify,
linkifyTlds,
defaultClassName: colorClassName, // markdown-it-color
}).result.html;
}).result;
}, [allowHTML, breaks, linkify, linkifyTlds, value]);

return <div ref={divRef} className={className} dangerouslySetInnerHTML={{__html: html}} />;
// Load katex only if one or more formulas should be rendered
if (((result.meta ?? {}) as Meta).script?.includes(LATEX_RUNTIME)) {
import('@diplodoc/latex-extension/runtime');
}
if (((result.meta ?? {}) as Meta).style?.includes(LATEX_RUNTIME)) {
// @ts-expect-error
import('@diplodoc/latex-extension/runtime/styles');
}

React.useEffect(() => {
renderLatex({throwOnError: false});
}, [result.html, renderLatex]);

return (
<div
ref={divRef}
className={className}
dangerouslySetInnerHTML={{__html: result.html}}
/>
);
};
11 changes: 10 additions & 1 deletion demo/Playground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
logger,
useYfmEditor,
} from '../src';
import {Math} from '../src/extensions/yfm/Math';
import {wHiddenData, wToolbarConfig} from '../src/toolbar/config/wysiwyg';

import {PlaygroundHtmlPreview} from './HtmlPreview';
Expand Down Expand Up @@ -92,7 +93,15 @@ const Playground = React.memo<PlaygroundProps>((props) => {
underline: {underlineKey: keys.underline},
code: {codeKey: keys.code},
})
.use(YfmPreset, {}),
.use(YfmPreset, {})
.use(Math, {
loadRuntimeScript: async () => {
await Promise.all([
import('@diplodoc/latex-extension/runtime'), // @ts-expect-error
import('@diplodoc/latex-extension/runtime/styles'),
]);
},
}),
[breaks, renderStorage],
);

Expand Down
13 changes: 5 additions & 8 deletions demo/md-content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,13 @@ export const initialMdContent = `
А это блочная формула:
$$\\begin{array}{c}
$$
\\nabla \\times \\vec{\\mathbf{B}} -\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{E}}}{\\partial t} &
= \\frac{4\\pi}{c}\\vec{\\mathbf{j}} \\nabla \\cdot \\vec{\\mathbf{E}} & = 4 \\pi \\rho \\\\
f(\\relax{x}) = \\int_{-\\infty}^\\infty
\\hat f(\\xi)\\,e^{2 \\pi i \\xi x}
\\,d\\xi
\\nabla \\times \\vec{\\mathbf{E}}\\, +\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{B}}}{\\partial t} & = \\vec{\\mathbf{0}} \\\\
\\nabla \\cdot \\vec{\\mathbf{B}} & = 0
\\end{array}$$
$$
_Кликни в формулу, чтобы отредактировать её_
Expand Down
12 changes: 10 additions & 2 deletions demo/md-plugins.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {transform as latex} from '@diplodoc/latex-extension';
import anchors from '@diplodoc/transform/lib/plugins/anchors';
import checkbox from '@diplodoc/transform/lib/plugins/checkbox';
import code from '@diplodoc/transform/lib/plugins/code';
Expand All @@ -15,10 +16,11 @@ import video from '@diplodoc/transform/lib/plugins/video';
import type {PluginWithParams} from 'markdown-it/lib';
import color from 'markdown-it-color';
import ins from 'markdown-it-ins';
import math from 'markdown-it-katex';
import mark from 'markdown-it-mark';
import sub from 'markdown-it-sub';

export const LATEX_RUNTIME = 'extension:latex';

const defaultPlugins: PluginWithParams[] = [
meta,
deflist,
Expand All @@ -35,6 +37,12 @@ const defaultPlugins: PluginWithParams[] = [
imsize,
checkbox,
];
const extendedPlugins = defaultPlugins.concat(sub, ins, mark, math, color);
const extendedPlugins = defaultPlugins.concat(
sub,
ins,
mark,
latex({bundle: false, validate: false, runtime: LATEX_RUNTIME}),
color,
);

export {extendedPlugins as plugins};
66 changes: 44 additions & 22 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 13 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@
"require": "./build/cjs/markdown-it/*",
"import": "./build/esm/markdown-it/*"
},
"./_/*": {
"types": "./build/esm/*",
"require": "./build/cjs/*",
"import": "./build/esm/*"
},
"./styles/*": "./build/esm/styles/*"
},
"main": "build/cjs/index.js",
Expand All @@ -71,6 +76,9 @@
],
"markdown-it/*": [
"./build/esm/markdown-it/*"
],
"_/*": [
"./build/esm/*"
]
}
},
Expand All @@ -93,7 +101,6 @@
"is-number": "^7.0.0",
"markdown-it-color": "^2.1.1",
"markdown-it-ins": "^3.0.1",
"markdown-it-katex": "2.0.3",
"markdown-it-mark": "^3.0.1",
"markdown-it-sub": "^1.0.0",
"prosemirror-codemark": "0.4.2",
Expand All @@ -113,6 +120,7 @@
"tslib": "^2.3.1"
},
"devDependencies": {
"@diplodoc/latex-extension": "1.0.3",
"@diplodoc/transform": "4.5.0",
"@gravity-ui/components": "2.0.0",
"@gravity-ui/eslint-config": "3.1.1",
Expand All @@ -127,7 +135,7 @@
"@types/gulp": "4.0.9",
"@types/gulp-sass": "5.0.0",
"@types/jest": "^27.0.3",
"@types/katex": "0.5.0",
"@types/katex": "0.16.7",
"@types/lodash": "^4.14.177",
"@types/react": "18.0.28",
"@types/react-dom": "18.0.11",
Expand Down Expand Up @@ -160,9 +168,12 @@
},
"peerDependencies": {
"@diplodoc/transform": "^4.5.0",
"@diplodoc/latex-extension": "^1.0.3",
"@gravity-ui/components": "^2.0.0",
"@gravity-ui/uikit": "^5.0.0",
"katex": "^0.16.9",
"lodash": "^4.17.20",
"markdown-it": "^13.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
Expand Down
4 changes: 2 additions & 2 deletions src/extensions/yfm/Math/MathSpecs/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import mathMdPlugin from 'markdown-it-katex';
import {transform} from '@diplodoc/latex-extension';

import type {ExtensionAuto} from '../../../../core';
import {nodeTypeFactory} from '../../../../utils/schema';
Expand All @@ -10,7 +10,7 @@ export const mathIType = nodeTypeFactory(MathNode.Inline);
export const mathBType = nodeTypeFactory(MathNode.Block);

export const MathSpecs: ExtensionAuto = (builder) => {
builder.configureMd((md) => md.use(mathMdPlugin));
builder.configureMd((md) => md.use(transform({bundle: false, validate: false}), {output: ''}));
builder
.addNode(MathNode.Inline, () => ({
spec: {
Expand Down
16 changes: 13 additions & 3 deletions src/extensions/yfm/Math/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
removeEmptyMathInlineIfCursorIsAtBeginning,
} from './commands';
import {mathBType, mathIType} from './const';
import {mathViewAndEditPlugin} from './view-and-edit';
import {MathNodeViewOptions, mathViewAndEditPlugin} from './view-and-edit';

import './index.scss';

Expand All @@ -26,7 +26,14 @@ const mathBAction = 'toMathBlock';

const mathITemplate = 'f(x)=';

export const Math: ExtensionAuto = (builder) => {
// !!! YfmPreset/YfmSpecsPreset does not use or re-export the Math extension

export type MathOptions = Pick<
MathNodeViewOptions,
'loadRuntimeScript' | 'sanitize' | 'katexOptions'
>;

export const Math: ExtensionAuto<MathOptions> = (builder, opts) => {
builder.use(MathSpecs);

builder.addKeymap(() => ({
Expand All @@ -39,7 +46,10 @@ export const Math: ExtensionAuto = (builder) => {

builder
.addPlugin(() =>
mathViewAndEditPlugin({reactRenderer: builder.context.get('reactrenderer')!}),
mathViewAndEditPlugin({
...opts,
reactRenderer: builder.context.get('reactrenderer')!,
}),
)
.addInputRules((deps) => ({
rules: [
Expand Down
Loading

0 comments on commit 4b742c9

Please sign in to comment.