A file-based task manager

FIX: small bugs with link parsing

+12 -10
+3 -1
.tsk/archive/tsk-14.tsk
··· 5 6 and finally some *italics!* 7 8 - here's [a link](https://ngp.computer).
··· 5 6 and finally some *italics!* 7 8 + here's [a link](https://ngp.computer). 9 + 10 + and an internal link: [[tsk-11]]
+9 -9
src/task.rs
··· 65 // there will always be an op code in the stack 66 Some((_, c)) => { 67 out.push(c); 68 - let end = out.len()-1; 69 - if c == '\n' || c == '\r' { 70 - state.clear(); 71 - } 72 match (last, c, state_last) { 73 ('=', ' ' | '\n' | '\r' | '.' | '!' | '?', Some(Highlight(hl))) => { 74 state.pop(); ··· 92 contents.purple(), 93 super_num(links.len() + 1).purple() 94 ); 95 - out.replace_range(il..out.len()-1, &linktext); 96 links.push(ParsedLink::Internal(id)); 97 } else { 98 panic!("Internal link is not a valid id: {contents}"); ··· 119 }; 120 let linktext = format!( 121 "{}{}", 122 - out.get(linktextpos + 1..linkpos-1)?.blue(), 123 super_num(links.len() + 1).purple() 124 ); 125 let link = out.get(linkpos + 1..out.len() - 2)?; ··· 170 } 171 _ => (), 172 } 173 last = c; 174 } 175 None => break, ··· 231 output.links.as_slice() 232 ); 233 assert_eq!( 234 - "hello \u{1b}[34mworld\u{1b}[0m\u{1b}[35m¹\u{1b}[0m)\n", 235 output.content 236 ); 237 } ··· 264 let output = parse(input).expect("parse to work"); 265 assert_eq!(&[ParsedLink::Internal(Id(123))], output.links.as_slice()); 266 assert_eq!( 267 - "hello [\u{1b}[35mtsk-123\u{1b}[0m\u{1b}[35m¹\u{1b}[0m]\n", 268 output.content 269 ); 270 } ··· 338 let input = "hello *italic* ~strikethrough~ !bold!\n"; 339 let output = parse(input).expect("parse to work"); 340 assert_eq!( 341 - "hello \u{1b}[3mworld\u{1b}[0m \u{1b}[9mworld\u{1b}[0m \u{1b}[1mworld\u{1b}[0m\n", 342 output.content 343 ); 344 }
··· 65 // there will always be an op code in the stack 66 Some((_, c)) => { 67 out.push(c); 68 + let end = out.len() - 1; 69 match (last, c, state_last) { 70 ('=', ' ' | '\n' | '\r' | '.' | '!' | '?', Some(Highlight(hl))) => { 71 state.pop(); ··· 89 contents.purple(), 90 super_num(links.len() + 1).purple() 91 ); 92 + out.replace_range(il-1..out.len(), &linktext); 93 links.push(ParsedLink::Internal(id)); 94 } else { 95 panic!("Internal link is not a valid id: {contents}"); ··· 116 }; 117 let linktext = format!( 118 "{}{}", 119 + out.get(linktextpos + 1..linkpos - 1)?.blue(), 120 super_num(links.len() + 1).purple() 121 ); 122 let link = out.get(linkpos + 1..out.len() - 2)?; ··· 167 } 168 _ => (), 169 } 170 + if c == '\n' || c == '\r' { 171 + state.clear(); 172 + } 173 last = c; 174 } 175 None => break, ··· 231 output.links.as_slice() 232 ); 233 assert_eq!( 234 + "hello \u{1b}[34mworld\u{1b}[0m\u{1b}[35m¹\u{1b}[0m\n", 235 output.content 236 ); 237 } ··· 264 let output = parse(input).expect("parse to work"); 265 assert_eq!(&[ParsedLink::Internal(Id(123))], output.links.as_slice()); 266 assert_eq!( 267 + "hello \u{1b}[35mtsk-123\u{1b}[0m\u{1b}[35m¹\u{1b}[0m\n", 268 output.content 269 ); 270 } ··· 338 let input = "hello *italic* ~strikethrough~ !bold!\n"; 339 let output = parse(input).expect("parse to work"); 340 assert_eq!( 341 + "hello \u{1b}[3mitalic\u{1b}[0m \u{1b}[9mstrikethrough\u{1b}[0m \u{1b}[1mbold\u{1b}[0m\n", 342 output.content 343 ); 344 }