Skip to main content

markdown_editor/
input_rule.rs

1//! Markdown input rules (D13). A rule fires on a trigger typed into a text
2//! leaf and rewrites what was typed; each firing is its own undo step, so
3//! one undo restores the literal text. The set is configurable with
4//! [`BlockEditorState::with_input_rules`](super::BlockEditorState::with_input_rules).
5
6/// One input rule. Construct the built-in rules with the associated
7/// functions, or take them all with [`InputRule::markdown_defaults`].
8#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
9pub struct InputRule(pub(crate) RuleKind);
10
11#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
12pub(crate) enum RuleKind {
13    Heading,
14    BulletList,
15    OrderedList,
16    TaskItem,
17    Blockquote,
18    CodeFence,
19    HorizontalRule,
20    InlineMarks,
21    Link,
22    Table,
23}
24
25impl InputRule {
26    /// `# ` … `###### ` at the start of a paragraph: a heading.
27    pub const fn heading() -> Self {
28        Self(RuleKind::Heading)
29    }
30    /// `- `, `* `, `+ ` at the start of a paragraph: a bullet list.
31    pub const fn bullet_list() -> Self {
32        Self(RuleKind::BulletList)
33    }
34    /// `1. ` (any number) at the start of a paragraph: an ordered list.
35    pub const fn ordered_list() -> Self {
36        Self(RuleKind::OrderedList)
37    }
38    /// `[ ] ` / `[x] ` at the start of a paragraph or list item (so also
39    /// `- [ ] `): a task item, unchecked / checked.
40    pub const fn task_item() -> Self {
41        Self(RuleKind::TaskItem)
42    }
43    /// `> ` at the start of a paragraph: a blockquote.
44    pub const fn blockquote() -> Self {
45        Self(RuleKind::Blockquote)
46    }
47    /// ```` ``` ```` / ```` ```lang ```` then Enter or space: a code block.
48    pub const fn code_fence() -> Self {
49        Self(RuleKind::CodeFence)
50    }
51    /// `---` then Enter in an otherwise empty paragraph: a horizontal rule.
52    pub const fn horizontal_rule() -> Self {
53        Self(RuleKind::HorizontalRule)
54    }
55    /// `` `x` ``, `**x**`, `*x*`, `~~x~~` on the closing delimiter.
56    pub const fn inline_marks() -> Self {
57        Self(RuleKind::InlineMarks)
58    }
59    /// `[text](url)` on the closing `)`: `text` with a link mark.
60    pub const fn link() -> Self {
61        Self(RuleKind::Link)
62    }
63
64    /// `| a | b |` then Enter at the end of a paragraph: a table whose
65    /// header row holds those cells, plus one empty body row.
66    pub const fn table() -> Self {
67        Self(RuleKind::Table)
68    }
69
70    /// Every built-in rule.
71    pub fn markdown_defaults() -> Vec<Self> {
72        vec![
73            Self::heading(),
74            Self::bullet_list(),
75            Self::ordered_list(),
76            Self::task_item(),
77            Self::blockquote(),
78            Self::code_fence(),
79            Self::horizontal_rule(),
80            Self::inline_marks(),
81            Self::link(),
82            Self::table(),
83        ]
84    }
85}