#![allow(dead_code)]
use markdown::{Cursor, Doc, Mark, Part, Selection, Text};
pub struct Rng(pub u64);
impl Rng {
pub fn next(&mut self) -> usize {
self.0 = self
.0
.wrapping_mul(6364136223846793005)
.wrapping_add(1442695040888963407);
(self.0 >> 33) as usize
}
}
pub const LINES: &[&str] = &[
"# h",
"###### deep",
"text",
"- a",
"- b",
"1. a",
"2. b",
"9) paren",
"> q",
"```",
"```rust",
" indented",
"| a | b |",
"| --- | ---: |",
"| 1 | 2 |",
"---",
"***",
"",
" - nested",
" deep cont",
"- [ ] t",
"- [x] d",
"**bold** tail",
"_it_ tail",
"`code` tail",
"[l](u) tail",
"",
"",
"[l](<a b>)",
"",
"[l](a(b)c)",
"a*b",
"a_b_c",
"#123",
"1 < 2 & 3",
"AT&T",
"\\# escaped",
"~~s~~",
" ",
"> - x",
"- > x",
"> - y",
"> 1. one",
"> ```",
"> # h",
" > q",
">",
"<div>",
"a <span> b",
"trailing \\",
"**unclosed",
"| ragged |",
"setext",
"======",
"> [!TIP]",
"> [!NOTE]",
"> [!BOGUS]",
"> \\[!TIP\\]",
];
pub const BLOCKS: &[&str] = &[
"plain text",
"# heading",
"Setext\n------",
"* star bullet",
"- [ ] a task",
"- [x] a done task",
"1. ordered",
"9) ordered too",
"> quoted",
"> [!TIP]\n> an alert",
"```rs\nfn main() {}\n```",
"| a | b |\n| --- | --- |\n| 1 | 2 |",
"---",
"",
"<https://bezel.gallery>",
"- ",
"",
" indented code",
"nested\n\n - under it",
];
const WORDS: &[&str] = &["x", " ", "\n", "a b", "**", "#", "- ", "`", "|", "~~"];
const MARKS: &[Mark] = &[Mark::Bold, Mark::Italic, Mark::Strike, Mark::Code];
pub fn edit_randomly(doc: &mut Doc, rng: &mut Rng) {
if doc.blocks.is_empty() {
return;
}
let ix = rng.next() % doc.blocks.len();
let len = doc.blocks[ix]
.text_at(Part::Body)
.map_or(0, |text| text.text.len());
let a = if len == 0 { 0 } else { rng.next() % (len + 1) };
let b = if len == 0 { 0 } else { rng.next() % (len + 1) };
let at = Cursor::new(ix, Part::Body, 0);
match rng.next() % 8 {
0 => {
let word = WORDS[rng.next() % WORDS.len()];
doc.edit_at(at, |text| text.insert(a, word));
}
1 => {
doc.edit_at(at, |text| text.remove(a.min(b)..a.max(b)));
}
2 => {
let mark = MARKS[rng.next() % MARKS.len()].clone();
doc.edit_at(at, |text| text.toggle(a.min(b)..a.max(b), mark));
}
3 => {
doc.split(ix, a);
}
4 => {
doc.merge_back(at);
}
5 => {
let jx = rng.next() % doc.blocks.len();
let jlen = doc.blocks[jx]
.text_at(Part::Body)
.map_or(0, |text| text.text.len());
let c = if jlen == 0 {
0
} else {
rng.next() % (jlen + 1)
};
let word = WORDS[rng.next() % WORDS.len()];
doc.replace(
Selection::new(
Cursor::new(ix, Part::Body, a),
Cursor::new(jx, Part::Body, c),
),
Text::plain(word),
);
}
6 => {
doc.indent(ix);
}
_ => {
doc.outdent(ix);
}
}
}