@@ -28,88 +28,69 @@ use std::cmp::Reverse;
2828/// Panics when missing head or anchor.
2929/// Panics when head come after head or anchor come after anchor.
3030pub fn print(s: &str) -> (String, Selection) {
31− let mut primary = None;
31+ let mut primary_idx = None;
3232 let mut ranges = SmallVec::new();
3333 let mut iter = s.chars().peekable();
3434 let mut left = String::with_capacity(s.len());
35+
3536 'outer: while let Some(c) = iter.next() {
3637 let start = left.len();
37− if c == '#' {
38− if iter.next_if_eq(&'[').is_some() {
39− if primary.is_some() {
40− panic!("primary `#[` already appeared {left:?} {s:?}");
41− }
42− if iter.next_if_eq(&'|').is_some() {
43− while let Some(c) = iter.next() {
44− if c == ']' && iter.next_if_eq(&'#').is_some() {
45− primary = Some(ranges.len());
46− ranges.push(Range::new(left.len(), start));
47− continue 'outer;
48− } else {
49− left.push(c);
50− }
51− }
52− panic!("missing primary end `]#` {left:?} {s:?}");
53− } else {
54− while let Some(c) = iter.next() {
55− if c == '|' {
56− if let Some(cc) = iter.next_if_eq(&']') {
57− if iter.next_if_eq(&'#').is_some() {
58− primary = Some(ranges.len());
59− ranges.push(Range::new(start, left.len()));
60− continue 'outer;
61− } else {
62− left.push(c);
63− left.push(cc);
64− }
65− } else {
66− left.push(c);
67− }
68− } else {
69− left.push(c);
70− }
71− }
72− panic!("missing primary end `|]#` {left:?} {s:?}");
73− }
74− } else if iter.next_if_eq(&'(').is_some() {
75− if iter.next_if_eq(&'|').is_some() {
76− while let Some(c) = iter.next() {
77− if c == ')' && iter.next_if_eq(&'#').is_some() {
78− ranges.push(Range::new(left.len(), start));
79− continue 'outer;
80− } else {
81− left.push(c);
82− }
83− }
84− panic!("missing end `)#` {left:?} {s:?}");
85− } else {
86− while let Some(c) = iter.next() {
87− if c == '|' {
88− if let Some(cc) = iter.next_if_eq(&')') {
89− if iter.next_if_eq(&'#').is_some() {
90− ranges.push(Range::new(start, left.len()));
91− continue 'outer;
92− } else {
93− left.push(c);
94− left.push(cc);
95− }
96− } else {
97− left.push(c);
98− }
99− } else {
100− left.push(c);
101− }
102− }
103− panic!("missing end `|)#` {left:?} {s:?}");
104− }
105− } else {
38+
39+ if c != '#' {
40+ left.push(c);
41+ continue;
42+ }
43+
44+ let (is_primary, close_pair) = match iter.next() {
45+ Some('[') => (true, ']'),
46+ Some('(') => (false, ')'),
47+ Some(ch) => {
48+ left.push(ch);
49+ continue;
50+ }
51+ None => break,
52+ };
53+
54+ if is_primary && primary_idx.is_some() {
55+ panic!("primary `#[` already appeared {left:?} {s:?}");
56+ }
57+
58+ let head_at_beg = iter.next_if_eq(&'|').is_some();
59+
60+ while let Some(c) = iter.next() {
61+ if !(c == close_pair && iter.peek() == Some(&'#')) {
10662 left.push(c);
63+ continue;
64+ }
65+ if !head_at_beg {
66+ let prev = left.pop().unwrap();
67+ if prev != '|' {
68+ left.push(prev);
69+ left.push(c);
70+ continue;
71+ }
72+ }
73+ iter.next(); // skip "#"
74+
75+ if is_primary {
76+ primary_idx = Some(ranges.len());
10777 }
78+ let (anchor, head) = match head_at_beg {
79+ true => (left.len(), start),
80+ false => (start, left.len()),
81+ };
82+ ranges.push(Range::new(anchor, head));
83+ continue 'outer;
84+ }
85+
86+ if head_at_beg {
87+ panic!("missing end `{close_pair}#` {left:?} {s:?}");
10888 } else {
109− left.push(c);
89+ panic!("missing end `|{close_pair}#` {left:?} {s:?}");
11090 }
11191 }
112− let primary = match primary {
92+
93+ let primary = match primary_idx {
11394 Some(i) => i,
11495 None => panic!("missing primary `#[|]#` {s:?}"),
11596 };