Skip to content

Commit 100a548

Browse files
authored
feat(YfmHeading): support folding attribute (#285)
1 parent 6948cc4 commit 100a548

File tree

4 files changed

+21
-8
lines changed

4 files changed

+21
-8
lines changed

src/extensions/yfm/YfmHeading/YfmHeadingSpecs/const.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ export const YfmHeadingAttr = {
77
Level: headingLevelAttr,
88
Id: 'id',
99
DataLine: 'data-line',
10+
Folding: 'folding',
1011
} as const;

src/extensions/yfm/YfmHeading/YfmHeadingSpecs/index.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export const YfmHeadingSpecs: ExtensionAuto<YfmHeadingSpecsOptions> = (builder,
2424
[YfmHeadingAttr.Id]: {default: ''},
2525
[YfmHeadingAttr.Level]: {default: 1},
2626
[YfmHeadingAttr.DataLine]: {default: null},
27+
[YfmHeadingAttr.Folding]: {default: false},
2728
},
2829
content: '(text | inline)*',
2930
group: 'block',
@@ -40,11 +41,13 @@ export const YfmHeadingSpecs: ExtensionAuto<YfmHeadingSpecsOptions> = (builder,
4041
toDOM(node) {
4142
const id = node.attrs[YfmHeadingAttr.Id];
4243
const lineNumber = node.attrs[YfmHeadingAttr.DataLine];
44+
const folding = node.attrs[YfmHeadingAttr.Folding];
4345
return [
4446
'h' + node.attrs[YfmHeadingAttr.Level],
4547
{
4648
id: id || null,
4749
[YfmHeadingAttr.DataLine]: lineNumber,
50+
[`data-${YfmHeadingAttr.Folding}`]: folding ? '' : null,
4851
},
4952
0,
5053
// [
@@ -84,13 +87,17 @@ export const YfmHeadingSpecs: ExtensionAuto<YfmHeadingSpecsOptions> = (builder,
8487
// attrs have id only if it explicitly specified manually
8588
return {
8689
[YfmHeadingAttr.Level]: Number(token.tag.slice(1)),
90+
[YfmHeadingAttr.Folding]: token.meta?.folding,
8791
...attrs,
8892
};
8993
},
9094
},
9195
},
9296
toMd: (state, node) => {
93-
state.write(state.repeat('#', node.attrs[YfmHeadingAttr.Level]) + ' ');
97+
const folding = node.attrs[YfmHeadingAttr.Folding];
98+
const level = node.attrs[YfmHeadingAttr.Level];
99+
100+
state.write(state.repeat('#', level) + (folding ? '+' : '') + ' ');
94101
state.renderInline(node);
95102

96103
const anchor = node.attrs[YfmHeadingAttr.Id];

src/extensions/yfm/YfmHeading/YfmHeadingSpecs/utils.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ export const getNodeAttrs =
88
(level: HeadingLevel): TagParseRule['getAttrs'] =>
99
(node) => ({
1010
[YfmHeadingAttr.Level]: level,
11-
[YfmHeadingAttr.Id]: (node as Element).getAttribute('id') || '',
11+
[YfmHeadingAttr.Id]: node.getAttribute('id') || '',
12+
[YfmHeadingAttr.Folding]: node.hasAttribute(`data-${YfmHeadingAttr.Folding}`),
1213
});
1314

1415
// export const slugify = (str: string) =>

src/extensions/yfm/YfmHeading/commands.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,20 @@ export {resetHeading} from '../../markdown/Heading/commands';
1212
export const toHeading =
1313
(level: HeadingLevel): Command =>
1414
(state, dispatch, view) => {
15+
const attrs: Record<string, any> = {};
16+
1517
const parentHeading = findParentNodeOfType(hType(state.schema))(state.selection);
16-
if (parentHeading && parentHeading.node.attrs[headingLevelAttr] === level) {
17-
return toParagraph(state, dispatch, view);
18+
if (parentHeading) {
19+
if (parentHeading.node.attrs[headingLevelAttr] === level) {
20+
return toParagraph(state, dispatch, view);
21+
}
22+
23+
Object.assign(attrs, parentHeading.node.attrs);
1824
}
1925

2026
// const text = state.selection.$head.parent.textContent;
21-
const attrs = {
22-
// [YfmHeadingAttr.Id]: slugify(text),
23-
[YfmHeadingAttr.Level]: level,
24-
};
27+
// attrs[YfmHeadingAttr.Id] = slugify(text);
28+
attrs[YfmHeadingAttr.Level] = level;
2529

2630
return setBlockType(hType(state.schema), attrs)(state, dispatch);
2731
};

0 commit comments

Comments
 (0)