markdown_utils/
codespan.rs

1/**
2 * Return the minimum possible of characters not found in a row.
3 * 
4 * For example, given the string ``"c cc cccc"`` and the
5 * character ``"c"``, returns the minimum number of characters in
6 * a row that are not found, so ``3`` in this case.
7 *
8 * This function is useful in to compute the number of backticks
9 * that must wrap markdown code spans. Given the code span
10 * ``"code that contains 3 \`\`\` and 2 \`\` backticks"`` and
11 * the character ``"`"``, this function returns  ``1``.
12 *
13 * Args:
14 *     character (str): Character to search.
15 *     text (str): Text inside which find the character repeated
16 *       in a row.
17 *
18 * Returns:
19 *     int: Minimum number possible of characters not found in a row.
20 **/
21pub fn n_backticks_to_wrap_codespan(
22    character: char,
23    text: &str,
24) -> usize {
25    let mut in_a_rows: Vec<usize> = vec![];
26    let mut current_in_a_row = 0;
27
28    for c in text.chars() {
29        if c == character {
30            current_in_a_row += 1;
31        } else if current_in_a_row > 0 {
32            if !in_a_rows.contains(&current_in_a_row) {
33                in_a_rows.push(current_in_a_row)
34            }
35            current_in_a_row = 0;
36        }
37    }
38    if current_in_a_row > 0 && !in_a_rows.contains(&current_in_a_row) {
39        in_a_rows.push(current_in_a_row)
40    }
41
42    let mut result = 0;
43    if in_a_rows.len() > 0 {
44        let max = in_a_rows.iter().max().unwrap() + 2;
45        for n in 1..max {
46            if !in_a_rows.contains(&n) {
47                result = n;
48                break;
49            }
50        }
51    }
52    result
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58    use rstest::rstest;
59
60    #[rstest]
61    #[case('c', &"c tt ccc cccc", 2)]
62    #[case('c', &"c cc ttt cccc", 3)]
63    #[case('c', &"t cc ttt cccc", 1)]
64    #[case('c', &"c cc ccc tttt", 4)]
65    fn n_backticks_to_wrap_codespan_test(
66        #[case] character: char,
67        #[case] text: &str,
68        #[case] expected: usize,
69    ) {
70        assert_eq!(
71            n_backticks_to_wrap_codespan(character, text),
72            expected,
73        );
74    }
75}