md_footer/
lib.rs

1use std::io::Read;
2
3pub fn convert<R: Read>(mut reader: R) -> String {
4    let mut is_codeblock = false;
5    let mut is_hiperlink = false;
6    let mut collected_links: Vec<String> = vec![];
7    let mut links_stack: Vec<String> = vec![];
8    let mut last_byte = b'\0';
9    let mut bytes = vec![];
10    let mut byte = [0u8];
11
12    while reader.read(&mut byte).expect("failed to read file") != 0 {
13        let c = byte[0];
14        if c == b'`' && is_codeblock {
15            is_codeblock = false;
16            bytes.push(c);
17        } else if c == b'`' && !is_codeblock {
18            is_codeblock = true;
19            bytes.push(c);
20        } else if c == b'[' && !is_codeblock {
21            links_stack.push("".into());
22            bytes.push(c);
23        } else if c == b'(' && last_byte == b']' && !is_codeblock {
24            is_hiperlink = true;
25        } else if c == b')' && !is_codeblock && is_hiperlink {
26            is_hiperlink = false;
27            if let Some(link) = links_stack.pop() {
28                let pointer =
29                    if let Some(position) = collected_links.iter().position(|l| l == &link) {
30                        position + 1
31                    } else {
32                        collected_links.push(link);
33                        collected_links.len()
34                    };
35
36                bytes.push(b'[');
37                for b in pointer.to_string().bytes() {
38                    bytes.push(b.clone());
39                }
40                bytes.push(b']');
41            } else {
42                bytes.push(c);
43            }
44        } else if !is_codeblock && is_hiperlink {
45            if let Some(link) = links_stack.last_mut() {
46                link.push(c as char);
47            } else {
48                bytes.push(c);
49            }
50        } else {
51            bytes.push(c);
52        };
53        last_byte = c;
54    }
55
56    if !collected_links.is_empty() {
57        bytes.push(b'\n');
58        bytes.push(b'\n');
59        for (i, link) in collected_links.iter().enumerate() {
60            for b in format!("[{}]:{}\n", i + 1, link).bytes() {
61                bytes.push(b);
62            }
63        }
64    }
65
66    String::from_utf8(bytes).expect("failed to render")
67}