mirror of
https://github.com/laurent22/joplin.git
synced 2026-06-06 20:10:22 +00:00
Signed-off-by: justin212407 <charlesjustin2124@gmail.com> Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
86 lines
2.5 KiB
TypeScript
86 lines
2.5 KiB
TypeScript
import { tags, Tag } from '@lezer/highlight';
|
|
import { MarkdownConfig, InlineContext, MarkdownExtension } from '@lezer/markdown';
|
|
|
|
const equalsSignCharcode = 61;
|
|
const plusSignCharcode = 43;
|
|
|
|
export const highlightTagName = 'Highlight';
|
|
export const highlightMarkerTagName = 'HighlightMarker';
|
|
|
|
export const insertTagName = 'Insert';
|
|
export const insertMarkerTagName = 'InsertMarker';
|
|
|
|
export const highlightTag = Tag.define();
|
|
export const highlightMarkerTag = Tag.define(tags.meta);
|
|
|
|
export const insertTag = Tag.define();
|
|
export const insertMarkerTag = Tag.define(tags.meta);
|
|
|
|
const HighlightDelimiter = { resolve: highlightTagName, mark: highlightMarkerTagName };
|
|
const InsertDelimiter = { resolve: insertTagName, mark: insertMarkerTagName };
|
|
|
|
const isSpaceOrEmpty = (text: string) => text.match(/^\s*$/);
|
|
|
|
// Markdown extension for recognizing highlighting. This is similar to the upstream
|
|
// extension for strikethrough:
|
|
// https://github.com/lezer-parser/markdown/blob/d6f0aa095722329a0188b9c7afe207dab4835e55/src/extension.ts#L10
|
|
const createDoubleCharInlineConfig = (
|
|
charCode: number,
|
|
tagName: string,
|
|
delimiter: { resolve: string; mark: string },
|
|
): MarkdownConfig => ({
|
|
defineNodes: [
|
|
{
|
|
name: delimiter.resolve,
|
|
style: tagName === highlightTagName ? highlightTag : insertTag,
|
|
},
|
|
{
|
|
name: delimiter.mark,
|
|
style: tagName === highlightTagName ? highlightMarkerTag : insertMarkerTag,
|
|
},
|
|
],
|
|
parseInline: [{
|
|
name: tagName,
|
|
|
|
parse(cx: InlineContext, current: number, pos: number): number {
|
|
const nextCharCode = cx.char(pos + 1);
|
|
const nextNextCharCode = cx.char(pos + 2);
|
|
if (current !== charCode || nextCharCode !== charCode || nextNextCharCode === charCode) {
|
|
return -1;
|
|
}
|
|
|
|
const before = cx.slice(pos - 1, pos);
|
|
const after = cx.slice(pos + 2, pos + 3);
|
|
|
|
const spaceBefore = isSpaceOrEmpty(before);
|
|
const spaceAfter = isSpaceOrEmpty(after);
|
|
const canStart = !spaceAfter;
|
|
const canEnd = !spaceBefore;
|
|
|
|
if (!canStart && !canEnd) {
|
|
return -1;
|
|
}
|
|
|
|
return cx.addDelimiter(
|
|
delimiter,
|
|
pos, pos + 2,
|
|
canStart,
|
|
canEnd,
|
|
);
|
|
},
|
|
}],
|
|
});
|
|
|
|
const highlightConfig = createDoubleCharInlineConfig(equalsSignCharcode, highlightTagName, HighlightDelimiter);
|
|
const insertConfig = createDoubleCharInlineConfig(plusSignCharcode, insertTagName, InsertDelimiter);
|
|
|
|
const markdownHighlightExtension: MarkdownExtension = [
|
|
highlightConfig,
|
|
];
|
|
|
|
export const markdownInsertExtension: MarkdownExtension = [
|
|
insertConfig,
|
|
];
|
|
|
|
export default markdownHighlightExtension;
|