~rbdr/page

6a8515fe6ed81369badb51496699a2ff25dbfa9f — Ruben Beltran del Rio 8 months ago 0a7a1f2 1.2.0
Wrap headings, fix empty lines
3 files changed, 56 insertions(+), 15 deletions(-)

M Cargo.lock
M Cargo.toml
M src/gemini_parser.rs
M Cargo.lock => Cargo.lock +1 -1
@@ 4,4 4,4 @@ version = 3

[[package]]
name = "page"
version = "1.1.0"
version = "1.2.0"

M Cargo.toml => Cargo.toml +1 -1
@@ 1,6 1,6 @@
[package]
name = "page"
version = "1.1.0"
version = "1.2.0"
edition = "2021"

[dependencies]

M src/gemini_parser.rs => src/gemini_parser.rs +54 -13
@@ 6,8 6,9 @@ pub fn parse(source: &str) -> String {
    let mut html:String = "".to_owned();
    let mut current_line_type: Option<LineType> = None;

    let mut heading_stack: Vec<u8> = Vec::new();
    for line in lines {
        let mut line_type = LineType::Text;
        let mut line_type = LineType::Blank;
        if line.char_indices().count() > 2 {
            let mut end = line.len();
            if line.char_indices().count() > 3 {


@@ 38,8 39,8 @@ pub fn parse(source: &str) -> String {
                    let line_content = get_partial_line_content(&line_type, line);
                    html.push_str(&line_content);
                } else {
                    let line_content = get_full_line_content(&line_type, line);
                    html.push_str(&line_content);
                    html.push_str(&get_heading_wrapper(&mut heading_stack, &line_type));
                    html.push_str(&get_full_line_content(&line_type, line));
                }
                current_line_type = Some(line_type);
            },


@@ 50,30 51,31 @@ pub fn parse(source: &str) -> String {
            html.push_str(get_line_closer(line));
        }
    }
    html.push_str(&close_heading_wrapper(&mut heading_stack));
    html
}

fn is_block(line_type: &LineType) -> bool {
    return match line_type {
        LineType::PreformattedText => true,
        LineType::ListItem => true,
        LineType::Quote => true,
        LineType::PreformattedText | LineType::ListItem | LineType::Quote => true,
        _ => false,
    }
}

fn get_partial_line_content(line_type: &LineType, line: &str) -> String {
    let encoded_line = line.replace("<", "&lt;").replace(">", "&gt;");
    return match line_type {
        LineType::ListItem => format!("<li>{}</li>", line[2..].trim()),
        LineType::Quote => line[1..].trim().to_string(),
        LineType::PreformattedText => format!("{}\n", line),
        LineType::ListItem => format!("<li>{}</li>", encoded_line[2..].trim()),
        LineType::Quote => encoded_line[1..].trim().to_string(),
        LineType::PreformattedText => format!("{}\n", encoded_line),
        _ => "".to_string(),
    }
}

fn get_full_line_content(line_type: &LineType, line: &str) -> String {
    let encoded_line = line.replace("<", "&lt;").replace(">", "&gt;");
     match line_type {
        LineType::Text => format!("<p>{}</p>\n", line.trim()),
        LineType::Text => format!("<p>{}</p>\n", encoded_line.trim()),
        LineType::Blank => "<br/>\n".to_string(),
        LineType::Link => {
            let url = get_link_address(line);


@@ 83,13 85,52 @@ fn get_full_line_content(line_type: &LineType, line: &str) -> String {
                format!("<div><a href=\"{}\">{}</a></div>\n", url.replace(".gmi", ".html"), get_link_content(line))
            }
        },
        LineType::Heading1 => format!("<h1>{}</h1>\n", line[1..].trim()),
        LineType::Heading2 => format!("<h2>{}</h2>\n", line[2..].trim()),
        LineType::Heading3 => format!("<h3>{}</h3>\n", line[3..].trim()),
        LineType::Heading1 => format!("<h1>{}</h1>\n", encoded_line[1..].trim()),
        LineType::Heading2 => format!("<h2>{}</h2>\n", encoded_line[2..].trim()),
        LineType::Heading3 => format!("<h3>{}</h3>\n", encoded_line[3..].trim()),
        _ => "".to_string(),
    }
}

fn get_heading_wrapper(heading_stack: &mut Vec<u8>, line_type: &LineType) -> String {
    let mut string = String::new();
    let current_heading: u8 = match line_type {
        LineType::Heading1 => 1,
        LineType::Heading2 => 2,
        LineType::Heading3 => 3,
        _ => 255
    };

    if current_heading < 255 {
        while let Some(open_heading) = heading_stack.pop() {
            // You just encountered a more important heading.
            // Put it back. Desist.
            if open_heading < current_heading {
                heading_stack.push(open_heading);
                break;
            }

            string.push_str("</div>");

            if open_heading == current_heading {
                break;
            }
        }
        heading_stack.push(current_heading);
        string.push_str(&format!("<div class=\"h{}\">", current_heading));
    }

    return string;
}

fn close_heading_wrapper(heading_stack: &mut Vec<u8>) -> String {
    let mut string = String::new();
    while let Some(_open_heading) = heading_stack.pop() {
        string.push_str("</div>");
    }
    return string;
}

fn get_line_opener(line_type: &LineType) -> &'static str {
    match line_type {
        LineType::ListItem => "<ul>",