mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-26 10:45:57 +08:00
feat(editor): support footnote adapter (#9844)
[BS-2373](https://linear.app/affine-design/issue/BS-2373/适配-footnote-adapter)
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
export * from './inline-delta';
|
||||
export * from './markdown-inline';
|
||||
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
FOOTNOTE_DEFINITION_PREFIX,
|
||||
InlineDeltaToMarkdownAdapterExtension,
|
||||
TextUtils,
|
||||
} from '@blocksuite/affine-shared/adapters';
|
||||
@@ -146,6 +147,46 @@ export const latexDeltaToMarkdownAdapterMatcher =
|
||||
},
|
||||
});
|
||||
|
||||
export const footnoteReferenceDeltaToMarkdownAdapterMatcher =
|
||||
InlineDeltaToMarkdownAdapterExtension({
|
||||
name: 'footnote-reference',
|
||||
match: delta => !!delta.attributes?.footnote,
|
||||
toAST: (delta, context) => {
|
||||
const mdast: PhrasingContent = {
|
||||
type: 'text',
|
||||
value: delta.insert,
|
||||
};
|
||||
const footnote = delta.attributes?.footnote;
|
||||
if (!footnote) {
|
||||
return mdast;
|
||||
}
|
||||
const footnoteDefinitionKey = `${FOOTNOTE_DEFINITION_PREFIX}${footnote.label}`;
|
||||
const { configs } = context;
|
||||
// FootnoteReference should be paired with FootnoteDefinition
|
||||
// If the footnoteDefinition is not in the configs, set it to configs
|
||||
// We should add the footnoteDefinition markdown ast nodes to tree after all the footnoteReference markdown ast nodes are added
|
||||
if (!configs.has(footnoteDefinitionKey)) {
|
||||
// clone the footnote reference
|
||||
const clonedFootnoteReference = { ...footnote.reference };
|
||||
// If the footnote reference contains url, encode it
|
||||
if (clonedFootnoteReference.url) {
|
||||
clonedFootnoteReference.url = encodeURIComponent(
|
||||
clonedFootnoteReference.url
|
||||
);
|
||||
}
|
||||
configs.set(
|
||||
footnoteDefinitionKey,
|
||||
JSON.stringify(clonedFootnoteReference)
|
||||
);
|
||||
}
|
||||
return {
|
||||
type: 'footnoteReference',
|
||||
label: footnote.label,
|
||||
identifier: footnote.label,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const InlineDeltaToMarkdownAdapterExtensions = [
|
||||
referenceDeltaToMarkdownAdapterMatcher,
|
||||
linkDeltaToMarkdownAdapterMatcher,
|
||||
@@ -154,4 +195,5 @@ export const InlineDeltaToMarkdownAdapterExtensions = [
|
||||
italicDeltaToMarkdownAdapterMatcher,
|
||||
strikeDeltaToMarkdownAdapterMatcher,
|
||||
latexDeltaToMarkdownAdapterMatcher,
|
||||
footnoteReferenceDeltaToMarkdownAdapterMatcher,
|
||||
];
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { MarkdownASTToDeltaExtension } from '@blocksuite/affine-shared/adapters';
|
||||
import { FootNoteReferenceParamsSchema } from '@blocksuite/affine-model';
|
||||
import {
|
||||
FOOTNOTE_DEFINITION_PREFIX,
|
||||
MarkdownASTToDeltaExtension,
|
||||
} from '@blocksuite/affine-shared/adapters';
|
||||
|
||||
export const markdownTextToDeltaMatcher = MarkdownASTToDeltaExtension({
|
||||
name: 'text',
|
||||
@@ -138,6 +142,43 @@ export const markdownInlineMathToDeltaMatcher = MarkdownASTToDeltaExtension({
|
||||
},
|
||||
});
|
||||
|
||||
export const markdownFootnoteReferenceToDeltaMatcher =
|
||||
MarkdownASTToDeltaExtension({
|
||||
name: 'footnote-reference',
|
||||
match: ast => ast.type === 'footnoteReference',
|
||||
toDelta: (ast, context) => {
|
||||
if (ast.type !== 'footnoteReference') {
|
||||
return [];
|
||||
}
|
||||
try {
|
||||
const { configs } = context;
|
||||
const footnoteDefinitionKey = `${FOOTNOTE_DEFINITION_PREFIX}${ast.identifier}`;
|
||||
const footnoteDefinition = configs.get(footnoteDefinitionKey);
|
||||
if (!footnoteDefinition) {
|
||||
return [];
|
||||
}
|
||||
const footnoteDefinitionJson = JSON.parse(footnoteDefinition);
|
||||
// If the footnote definition contains url, decode it
|
||||
if (footnoteDefinitionJson.url) {
|
||||
footnoteDefinitionJson.url = decodeURIComponent(
|
||||
footnoteDefinitionJson.url
|
||||
);
|
||||
}
|
||||
const footnoteReference = FootNoteReferenceParamsSchema.parse(
|
||||
footnoteDefinitionJson
|
||||
);
|
||||
const footnote = {
|
||||
label: ast.identifier,
|
||||
reference: footnoteReference,
|
||||
};
|
||||
return [{ insert: ' ', attributes: { footnote } }];
|
||||
} catch (error) {
|
||||
console.error('Error parsing footnote reference', error);
|
||||
return [];
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export const MarkdownInlineToDeltaAdapterExtensions = [
|
||||
markdownTextToDeltaMatcher,
|
||||
markdownInlineCodeToDeltaMatcher,
|
||||
@@ -147,4 +188,5 @@ export const MarkdownInlineToDeltaAdapterExtensions = [
|
||||
markdownLinkToDeltaMatcher,
|
||||
markdownInlineMathToDeltaMatcher,
|
||||
markdownListToDeltaMatcher,
|
||||
markdownFootnoteReferenceToDeltaMatcher,
|
||||
];
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
export * from './adapters/extensions';
|
||||
export * from './adapters/html/html-inline';
|
||||
export * from './adapters/html/inline-delta';
|
||||
export * from './adapters/markdown/inline-delta';
|
||||
export * from './adapters/markdown/markdown-inline';
|
||||
export * from './adapters/markdown';
|
||||
export * from './adapters/notion-html/html-inline';
|
||||
export * from './adapters/plain-text/inline-delta';
|
||||
export * from './presets/affine-inline-specs';
|
||||
|
||||
Reference in New Issue
Block a user