md_footer/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use std::io::Read;

pub fn convert<R: Read>(mut reader: R) -> String {
    let mut is_codeblock = false;
    let mut is_hiperlink = false;
    let mut collected_links: Vec<String> = vec![];
    let mut links_stack: Vec<String> = vec![];
    let mut last_byte = b'\0';
    let mut bytes = vec![];
    let mut byte = [0u8];

    while reader.read(&mut byte).expect("failed to read file") != 0 {
        let c = byte[0];
        if c == b'`' && is_codeblock {
            is_codeblock = false;
            bytes.push(c);
        } else if c == b'`' && !is_codeblock {
            is_codeblock = true;
            bytes.push(c);
        } else if c == b'[' && !is_codeblock {
            links_stack.push("".into());
            bytes.push(c);
        } else if c == b'(' && last_byte == b']' && !is_codeblock {
            is_hiperlink = true;
        } else if c == b')' && !is_codeblock && is_hiperlink {
            is_hiperlink = false;
            if let Some(link) = links_stack.pop() {
                let pointer =
                    if let Some(position) = collected_links.iter().position(|l| l == &link) {
                        position + 1
                    } else {
                        collected_links.push(link);
                        collected_links.len()
                    };

                bytes.push(b'[');
                for b in pointer.to_string().bytes() {
                    bytes.push(b.clone());
                }
                bytes.push(b']');
            } else {
                bytes.push(c);
            }
        } else if !is_codeblock && is_hiperlink {
            if let Some(link) = links_stack.last_mut() {
                link.push(c as char);
            } else {
                bytes.push(c);
            }
        } else {
            bytes.push(c);
        };
        last_byte = c;
    }

    if !collected_links.is_empty() {
        bytes.push(b'\n');
        bytes.push(b'\n');
        for (i, link) in collected_links.iter().enumerate() {
            for b in format!("[{}]:{}\n", i + 1, link).bytes() {
                bytes.push(b);
            }
        }
    }

    String::from_utf8(bytes).expect("failed to render")
}