@@ -28,88 +28,69 @@ use std::cmp::Reverse;
28/// Panics when missing head or anchor.
28/// Panics when missing head or anchor.
29/// Panics when head come after head or anchor come after anchor.
29/// Panics when head come after head or anchor come after anchor.
30pub fn print(s: &str) -> (String, Selection) {
30pub fn print(s: &str) -> (String, Selection) {
31− let mut primary = None;
31+ let mut primary_idx = None;
32 let mut ranges = SmallVec::new();
32 let mut ranges = SmallVec::new();
33 let mut iter = s.chars().peekable();
33 let mut iter = s.chars().peekable();
34 let mut left = String::with_capacity(s.len());
34 let mut left = String::with_capacity(s.len());
35 'outer: while let Some(c) = iter.next() {
36 'outer: while let Some(c) = iter.next() {
36 let start = left.len();
37 let start = left.len();
37− if c == '#' {
39+ if c != '#' {
38− if iter.next_if_eq(&'[').is_some() {
40+ left.push(c);
39− if primary.is_some() {
41+ continue;
44+ let (is_primary, close_pair) = match iter.next() {
45+ Some('[') => (true, ']'),
46+ Some('(') => (false, ')'),
54+ if is_primary && primary_idx.is_some() {
40− panic!("primary `#[` already appeared {left:?} {s:?}");
55+ panic!("primary `#[` already appeared {left:?} {s:?}");
42− if iter.next_if_eq(&'|').is_some() {
57+
43− while let Some(c) = iter.next() {
44− if c == ']' && iter.next_if_eq(&'#').is_some() {
58+ let head_at_beg = iter.next_if_eq(&'|').is_some();
45− primary = Some(ranges.len());
59+
46− ranges.push(Range::new(left.len(), start));
52− panic!("missing primary end `]#` {left:?} {s:?}");
54− while let Some(c) = iter.next() {
60+ while let Some(c) = iter.next() {
55− if c == '|' {
61+ if !(c == close_pair && iter.peek() == Some(&'#')) {
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()));
72− panic!("missing primary end `|]#` {left:?} {s:?}");
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));
84− panic!("missing end `)#` {left:?} {s:?}");
86− while let Some(c) = iter.next() {
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()));
103− panic!("missing end `|)#` {left:?} {s:?}");
106 left.push(c);
62 left.push(c);
66+ let prev = left.pop().unwrap();
73+ iter.next(); // skip "#"
76+ primary_idx = Some(ranges.len());
78+ let (anchor, head) = match head_at_beg {
79+ true => (left.len(), start),
80+ false => (start, left.len()),
82+ ranges.push(Range::new(anchor, head));
87+ panic!("missing end `{close_pair}#` {left:?} {s:?}");
109− left.push(c);
89+ panic!("missing end `|{close_pair}#` {left:?} {s:?}");
112− let primary = match primary {
93+ let primary = match primary_idx {
113 Some(i) => i,
94 Some(i) => i,
114 None => panic!("missing primary `#[|]#` {s:?}"),
95 None => panic!("missing primary `#[|]#` {s:?}"),