Skip to content

Commit

Permalink
feat: Adds the ability to support horizontal rule in article editor
Browse files Browse the repository at this point in the history
  • Loading branch information
iamsivin committed May 22, 2024
1 parent 2912248 commit d7fd2a2
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Placeholder from "./Placeholder";
import {
listInputRules,
linksInputRules,
hrInputRules,
blocksInputRule,
baseKeyMaps,
textFormattingInputRules,
Expand Down Expand Up @@ -39,6 +40,7 @@ export const buildEditor = ({
blocksInputRule(schema),
textFormattingInputRules(schema),
linksInputRules(schema),
hrInputRules(schema),
listInputRules(schema),
dropCursor(),
gapCursor(),
Expand Down
40 changes: 40 additions & 0 deletions src/rules/hr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { inputRules } from 'prosemirror-inputrules';
import { safeInsert } from 'prosemirror-utils';
import { createInputRule } from '../utils';

function createHorizontalRuleInputRule(type) {
return createInputRule(
/^(?:---|___|\*\*\*)\s$/, // Ensures rule is triggered with space after "---", "___", or "***"
(state, match, start, end) => {
if (!match[0]) {
return null; // If no match found, return null
}

// Deletes the matched sequence including the space
let tr = state.tr.delete(start, end);
const hrPos = start; // Position where the horizontal rule should be inserted

// Insert the horizontal rule at the position
tr = safeInsert(type.create(), hrPos)(tr);

// Insert a paragraph node after the horizontal rule
tr = safeInsert(state.schema.nodes.paragraph.create(), tr.mapping.map(hrPos + 1))(tr);

return tr;
}
);
}

export function hrInputRules(schema) {
if (!schema.nodes.horizontal_rule) {
return null; // Ensures that horizontal_rule is part of the schema
}

const hrRule = createHorizontalRuleInputRule(schema.nodes.horizontal_rule);

return inputRules({
rules: [hrRule],
});
}

export default hrInputRules;
1 change: 1 addition & 0 deletions src/rules/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export { listInputRules } from './lists';
export { linksInputRules } from './links';
export { blocksInputRule } from './blocks';
export { hrInputRules } from './hr';
export { baseKeyMaps } from '../keymap';

export { textFormattingInputRules } from './marks';
5 changes: 3 additions & 2 deletions src/schema/markdown/articleParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const articleSchemaToMdMapping = {
export const articleMdToPmMapping = {
...baseNodesMdToPmMapping,
...baseMarksMdToPmMapping,
hr: { node: 'rule' },
hr: { node: 'horizontal_rule' },
heading: {
block: 'heading',
attrs: tok => ({ level: +tok.tag.slice(1) }),
Expand All @@ -46,6 +46,7 @@ md.enable([
'entity',
// Process escaped chars and hardbreaks
'escape',
'hr',
]);

export class ArticleMarkdownTransformer {
Expand All @@ -58,7 +59,7 @@ export class ArticleMarkdownTransformer {
}
}
});

this.markdownParser = new MarkdownParser(
schema,
tokenizer,
Expand Down

0 comments on commit d7fd2a2

Please sign in to comment.