pl-fe: use @lexical/markdown for wysiwyg markdown export
Signed-off-by: Nicole Mikołajczyk <git@mkljczk.pl>
This commit is contained in:
@ -49,6 +49,7 @@
|
||||
"@lexical/hashtag": "^0.29.0",
|
||||
"@lexical/link": "^0.29.0",
|
||||
"@lexical/list": "^0.29.0",
|
||||
"@lexical/markdown": "^0.29.0",
|
||||
"@lexical/react": "^0.29.0",
|
||||
"@lexical/rich-text": "^0.29.0",
|
||||
"@lexical/selection": "^0.29.0",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { AutoLinkNode, LinkNode } from '@lexical/link';
|
||||
import { $convertToMarkdownString } from '@lexical/markdown';
|
||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
||||
import { $createRemarkExport } from '@mkljczk/lexical-remark';
|
||||
import { $nodesOfType, $getRoot, type EditorState, $getNodeByKey } from 'lexical';
|
||||
import debounce from 'lodash/debounce';
|
||||
import { useCallback, useEffect } from 'react';
|
||||
@ -14,6 +14,8 @@ import { useSettings } from 'pl-fe/hooks/use-settings';
|
||||
import { getStatusIdsFromLinksInContent } from 'pl-fe/utils/status';
|
||||
import Purify from 'pl-fe/utils/url-purify';
|
||||
|
||||
import { TRANSFORMERS } from '../transformers';
|
||||
|
||||
import type { LanguageIdentificationModel } from 'fasttext.wasm.js/dist/models/language-identification/common.js';
|
||||
|
||||
let lidModel: LanguageIdentificationModel;
|
||||
@ -136,21 +138,18 @@ const StatePlugin: React.FC<IStatePlugin> = ({ composeId, isWysiwyg }) => {
|
||||
useEffect(() => {
|
||||
return editor.registerUpdateListener(({ editorState }) => {
|
||||
const plainText = editorState.read(() => $getRoot().getTextContent());
|
||||
let text = plainText;
|
||||
if (isWysiwyg) {
|
||||
text = editorState.read($createRemarkExport({
|
||||
handlers: {
|
||||
hashtag: (node) => ({ type: 'text', value: node.getTextContent() }),
|
||||
mention: (node) => ({ type: 'text', value: node.getTextContent() }),
|
||||
},
|
||||
}));
|
||||
}
|
||||
const isEmpty = text === '';
|
||||
const data = isEmpty ? null : JSON.stringify(editorState.toJSON());
|
||||
dispatch(setEditorState(composeId, data, text));
|
||||
checkUrls(editorState);
|
||||
getQuoteSuggestions(plainText);
|
||||
detectLanguage(plainText);
|
||||
editor.update(() => {
|
||||
let text = plainText;
|
||||
if (isWysiwyg) {
|
||||
text = $convertToMarkdownString(TRANSFORMERS);
|
||||
}
|
||||
const isEmpty = text === '';
|
||||
const data = isEmpty ? null : JSON.stringify(editorState.toJSON());
|
||||
dispatch(setEditorState(composeId, data, text));
|
||||
checkUrls(editorState);
|
||||
getQuoteSuggestions(plainText);
|
||||
detectLanguage(plainText);
|
||||
});
|
||||
});
|
||||
}, [editor]);
|
||||
|
||||
|
||||
@ -0,0 +1,63 @@
|
||||
/**
|
||||
* This source code is derived from code from Meta Platforms, Inc.
|
||||
* and affiliates, licensed under the MIT license located in the
|
||||
* LICENSE file in the /src/features/compose/editor directory.
|
||||
*/
|
||||
|
||||
import { TRANSFORMERS as DEFAULT_TRANSFORMERS, type ElementTransformer, type TextMatchTransformer } from '@lexical/markdown';
|
||||
import { $createHorizontalRuleNode, $isHorizontalRuleNode, HorizontalRuleNode } from '@lexical/react/LexicalHorizontalRuleNode';
|
||||
import { LexicalNode } from 'lexical';
|
||||
|
||||
import { $createImageNode, $isImageNode, ImageNode } from '../nodes/image-node';
|
||||
|
||||
const IMAGE_TRANSFORMER: TextMatchTransformer = {
|
||||
dependencies: [ImageNode],
|
||||
export: (node) => {
|
||||
if ($isImageNode(node)) {
|
||||
const src = node.getSrc();
|
||||
const alt = node.getAltText();
|
||||
return `![${alt.replace(/([[\]])/g, '\\$1')}](${src})`;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
importRegExp: /!(?:\[([^[]*)\])(?:\(([^(]+)\))/,
|
||||
regExp: /!(?:\[([^[]*)\])(?:\(([^(]+)\))$/,
|
||||
replace: (textNode, match) => {
|
||||
const [, altText, src] = match;
|
||||
const imageNode = $createImageNode({
|
||||
altText,
|
||||
src,
|
||||
});
|
||||
textNode.replace(imageNode);
|
||||
},
|
||||
type: 'text-match',
|
||||
};
|
||||
|
||||
const HORIZONTAL_RULE_TRANSFORMER: ElementTransformer = {
|
||||
dependencies: [HorizontalRuleNode],
|
||||
export: (node: LexicalNode) => {
|
||||
return $isHorizontalRuleNode(node) ? '***' : null;
|
||||
},
|
||||
regExp: /^(---|\*\*\*|___)\s?$/,
|
||||
replace: (parentNode, _1, _2, isImport) => {
|
||||
const line = $createHorizontalRuleNode();
|
||||
|
||||
// TODO: Get rid of isImport flag
|
||||
if (isImport || parentNode.getNextSibling() !== null) {
|
||||
parentNode.replace(line);
|
||||
} else {
|
||||
parentNode.insertBefore(line);
|
||||
}
|
||||
|
||||
line.selectNext();
|
||||
},
|
||||
type: 'element',
|
||||
};
|
||||
|
||||
const TRANSFORMERS = [
|
||||
...DEFAULT_TRANSFORMERS,
|
||||
HORIZONTAL_RULE_TRANSFORMER,
|
||||
IMAGE_TRANSFORMER,
|
||||
];
|
||||
|
||||
export { TRANSFORMERS };
|
||||
@ -1596,7 +1596,7 @@
|
||||
"@lexical/utils" "0.29.0"
|
||||
lexical "0.29.0"
|
||||
|
||||
"@lexical/markdown@0.29.0":
|
||||
"@lexical/markdown@0.29.0", "@lexical/markdown@^0.29.0":
|
||||
version "0.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@lexical/markdown/-/markdown-0.29.0.tgz#673ca4fb1cbedf2b17e905cf9a229ce0eb505b65"
|
||||
integrity sha512-4Od8WoDoviv9DxJZVgrIORTIAzyoGOpztbGbIBXguGmwvy7NnHQDh9fZYIYRrdI1Awp1VVGdJ3ku/7KTgSOoRw==
|
||||
|
||||
Reference in New Issue
Block a user