Skip to content

Commit ca311d9

Browse files
authored
Replace custom markdown parsing with marked, KaTeX, and some custom plugins for matrix things (#727)
<!-- Please read https://github.com/SableClient/Sable/blob/dev/CONTRIBUTING.md before submitting your pull request --> ### Description <!-- Please include a summary of the change. Please also include relevant motivation and context. List any dependencies that are required for this change. --> Replaced Cinny's custom markdown parsing with marked which should drastically reduce the various random obscure errors and crashes caused by it. Added math rendering support with KaTeX, sent using standard formatting of $ for inline and $$ for block with LaTeX. Supersedes #726 Fixes #711 Fixes #587 Fixes #467 Fixes #684 Tbh I doubt I've tested this enough so there's probably still a bunch of bugs, especially in parsing html back to markdown, but hopefully it's less than our current system? Might consider using another library like Turndown for converting html into markdown, currently using a partial custom parser with... well okay results. Updated to also remove the WYSIWYG editor because it's largely unused, can be entirely covered by markdown, and complicates translating html to markdown. Keyboard shortcuts from the editor have been rewritten to instead apply markdown syntax. #### Type of change - [x] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [x] Breaking change - removes the WYSIWYG editor. - [ ] This change requires a documentation update ### Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings ### AI disclosure: - [x] Partially AI assisted (clarify which code was AI assisted and briefly explain what it does). - [ ] Fully AI generated (explain what all the generated code does in moderate detail). <!-- Write any explanation required here, but do not generate the explanation using AI!! You must prove you understand what the code in this PR does. --> Tests were AI generated and then reviewed by me. I can confirm that the tests probably test the right stuff. I had AI do the initial merge and write the marked plugins for the link preview hiding and spoiler hiding features, which I then tested and reviewed.
2 parents 48cd173 + 5991790 commit ca311d9

56 files changed

Lines changed: 1899 additions & 2539 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
default: minor
3+
---
4+
5+
# Markdown parser and render updates
6+
7+
Migrated markdown parsing and rendering to use marked, which should fix most (all?) markdown issues involving lists/nested structures, inconsistent/inaccurate code blocks, escape sequences, and all the other bugs with literally everything.
8+
9+
Added math rendering support via marked and KaTeX, uses standard `$$` and `$` delimiters. Only renders a subset of latex tags that will likely need to be expanded so feel free to make issues if needed.
10+
11+
Also adds support for sending markdown tables (although they're rendered rather plainly at the moment), sending valid html directly (such as for colored text), and properly escaping anything with backslashes.
12+
13+
Fixes link previews appearing in code blocks, fixes pmp new line behavior, fixes links not opening in new tabs, and fixes editing arbitrary html messages, probably.
14+
15+
Finally, the old WYSIWYG editor has been completely removed.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,10 @@
7070
"immer": "^9.0.21",
7171
"is-hotkey": "^0.2.0",
7272
"jotai": "^2.18.0",
73+
"katex": "^0.16.45",
7374
"linkify-react": "^4.3.2",
7475
"linkifyjs": "^4.3.2",
76+
"marked": "^18.0.2",
7577
"matrix-js-sdk": "^38.4.0",
7678
"matrix-widget-api": "^1.16.1",
7779
"pdfjs-dist": "^5.4.624",

pnpm-lock.yaml

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/components/editor/Elements.tsx

Lines changed: 3 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Scroll, Text } from 'folds';
1+
import { Text } from 'folds';
22
import type { RenderElementProps, RenderLeafProps } from 'slate-react';
33
import { useFocused, useSelected, useSlate } from 'slate-react';
44
import { useAtomValue } from 'jotai';
@@ -130,72 +130,6 @@ export function RenderElement({ attributes, element, children }: RenderElementPr
130130
{children}
131131
</Text>
132132
);
133-
case BlockType.Heading:
134-
if (element.level === 1)
135-
return (
136-
<Text className={css.Heading} as="h2" size="H2" {...attributes}>
137-
{children}
138-
</Text>
139-
);
140-
if (element.level === 2)
141-
return (
142-
<Text className={css.Heading} as="h3" size="H3" {...attributes}>
143-
{children}
144-
</Text>
145-
);
146-
if (element.level === 3)
147-
return (
148-
<Text className={css.Heading} as="h4" size="H4" {...attributes}>
149-
{children}
150-
</Text>
151-
);
152-
return (
153-
<Text className={css.Heading} as="h3" size="H3" {...attributes}>
154-
{children}
155-
</Text>
156-
);
157-
case BlockType.CodeLine:
158-
return <div {...attributes}>{children}</div>;
159-
case BlockType.CodeBlock:
160-
return (
161-
<Text as="pre" className={css.CodeBlock} {...attributes}>
162-
<Scroll
163-
direction="Horizontal"
164-
variant="SurfaceVariant"
165-
size="300"
166-
visibility="Hover"
167-
hideTrack
168-
>
169-
<div className={css.CodeBlockInternal}>{children}</div>
170-
</Scroll>
171-
</Text>
172-
);
173-
case BlockType.QuoteLine:
174-
return <div {...attributes}>{children}</div>;
175-
case BlockType.BlockQuote:
176-
return (
177-
<Text as="blockquote" className={css.BlockQuote} {...attributes}>
178-
{children}
179-
</Text>
180-
);
181-
case BlockType.ListItem:
182-
return (
183-
<Text as="li" {...attributes}>
184-
{children}
185-
</Text>
186-
);
187-
case BlockType.OrderedList:
188-
return (
189-
<ol className={css.List} {...attributes}>
190-
{children}
191-
</ol>
192-
);
193-
case BlockType.UnorderedList:
194-
return (
195-
<ul className={css.List} {...attributes}>
196-
{children}
197-
</ul>
198-
);
199133
case BlockType.Mention:
200134
return (
201135
<RenderMentionElement attributes={attributes} element={element}>
@@ -220,19 +154,6 @@ export function RenderElement({ attributes, element, children }: RenderElementPr
220154
{children}
221155
</RenderCommandElement>
222156
);
223-
case BlockType.Small:
224-
return (
225-
<Text {...attributes} className={css.Small}>
226-
{children}
227-
</Text>
228-
);
229-
case BlockType.HorizontalRule:
230-
return (
231-
<div {...attributes}>
232-
<div contentEditable={false} className={css.HorizontalRule} />
233-
{children}
234-
</div>
235-
);
236157
default:
237158
return (
238159
<Text
@@ -246,52 +167,6 @@ export function RenderElement({ attributes, element, children }: RenderElementPr
246167
}
247168
}
248169

249-
export function RenderLeaf({ attributes, leaf, children }: RenderLeafProps) {
250-
let child = children;
251-
if (leaf.bold)
252-
child = (
253-
<strong {...attributes}>
254-
<InlineChromiumBugfix />
255-
{child}
256-
</strong>
257-
);
258-
if (leaf.italic)
259-
child = (
260-
<i {...attributes}>
261-
<InlineChromiumBugfix />
262-
{child}
263-
</i>
264-
);
265-
if (leaf.underline)
266-
child = (
267-
<u {...attributes}>
268-
<InlineChromiumBugfix />
269-
{child}
270-
</u>
271-
);
272-
if (leaf.strikeThrough)
273-
child = (
274-
<s {...attributes}>
275-
<InlineChromiumBugfix />
276-
{child}
277-
</s>
278-
);
279-
if (leaf.code)
280-
child = (
281-
<code className={css.Code} {...attributes}>
282-
<InlineChromiumBugfix />
283-
{child}
284-
</code>
285-
);
286-
if (leaf.spoiler)
287-
child = (
288-
<span className={css.Spoiler()} {...attributes}>
289-
<InlineChromiumBugfix />
290-
{child}
291-
</span>
292-
);
293-
294-
if (child !== children) return child;
295-
296-
return <span {...attributes}>{child}</span>;
170+
export function RenderLeaf({ attributes, children }: RenderLeafProps) {
171+
return <span {...attributes}>{children}</span>;
297172
}

0 commit comments

Comments
 (0)