markdown_formatter/args/
split.rs1pub fn split_into_lines(input: String, limit: usize) -> Vec<String> {
2 let mut output: Vec<String> = vec![];
3 let mut cur_line: Vec<char> = vec![];
4 let mut cur_line_len: usize = 0;
5 input.trim()
6 .replace("\n", " &#LF#&!")
7 .split(" ")
8 .for_each(|space_separated| {
9 let mut space_separated: String = space_separated.to_string();
10 if cur_line_len == limit || cur_line_len + 1 == limit {
11 output.push(cur_line.clone().into_iter().collect());
13 cur_line.clear();
14 cur_line_len = 0;
15 }
16 if space_separated.starts_with("&#LF#&!") {
17 if cur_line_len > 0 {
18 output.push(cur_line.clone().into_iter().collect());
19 cur_line.clear();
20 cur_line_len = 0;
21 }else {
22 output.push("".to_string());
23 }
24 space_separated = space_separated.replace("&#LF#&!", "");
25 }
26 let len_of_space_separated = len_of_chars(&space_separated);
27 if len_of_space_separated == 0 {
28 return;
29 }
30 if len_of_space_separated + cur_line_len < limit {
31 if cur_line_len > 0 {
33 cur_line.push(' ');
35 cur_line_len += 1;
36 }
37 cur_line.extend(space_separated.chars());
38 cur_line_len += len_of_space_separated;
39 } else {
40 if cur_line_len < limit && cur_line_len > 0 {
42 output.push(cur_line.clone().into_iter().collect());
44 cur_line.clear();
45 cur_line_len = 0;
46 }
47
48 space_separated.chars().for_each(|ch| {
49 match ch {
50 '\u{4E00}'..='\u{9FCC}'
51 | '\u{3400}'..='\u{4DB5}'
52 | '\u{20000}'..='\u{2A6D6}'
53 | '\u{2A700}'..='\u{2B734}'
54 | '\u{2B740}'..='\u{2B81D}' => {
55 cur_line_len += 2;
57 }
58 _ => {
59 cur_line_len += 1;
60 }
61 }
62 cur_line.push(ch);
64 if cur_line_len == limit || cur_line_len == limit - 1 {
65 output.push(cur_line.clone().into_iter().collect());
67 cur_line.clear();
68 cur_line_len = 0;
69 }
70 });
71 }
72 });
73
74 if cur_line_len > 0 {
75 output.push(cur_line.into_iter().collect());
76 }
77
78 output
79}
80
81pub fn len_of_chars(input: &str) -> usize {
82 let mut size = 0;
83 input.chars().for_each(|ch| {
84 match ch {
85 '\u{4E00}'..='\u{9FCC}'
86 | '\u{3400}'..='\u{4DB5}'
87 | '\u{20000}'..='\u{2A6D6}'
88 | '\u{2A700}'..='\u{2B734}'
89 | '\u{2B740}'..='\u{2B81D}' => {
90 size += 2;
92 }
93 _ => {
94 size += 1;
95 }
96 }
97 });
98 size
99}
100
101#[cfg(test)]
102mod tests {
103 use super::*;
104
105 #[test]
106 fn test_split_into_lines() {
107 let input = String::from("This is a long line. ".repeat(10));
108 assert_eq!(split_into_lines(input, 80).len(), 3);
109
110 let input = String::from("这是一段很长的介绍\n".repeat(10));
111 println!("{:?}", split_into_lines(input, 71));
112 }
114}