rustex 0.1.0

A library to make simple auto-generated LaTeX files in Rust.
Documentation
use super::def_syntax::*;
use crate::components::document::*;
use std::io::{Write, Error};
use regex::*;


const BOLD_REGEX: &str = r"\*{2}(?P<text>[^\*]+?)\*{2}";
const ITALIC_REGEX: &str = r"_(?P<text>[^_]+?)_";
const COLOR_REGEX: &str = r"#(?P<color>[^{} ]+)\{(?P<text>[^{}]+)\}";

pub fn into_braces(string: &String) -> String {
    let mut str_with_braces: String = String::from("{");
    str_with_braces = format!("{}{}", str_with_braces, string);
    format!("{}{}", str_with_braces, "}")
}

pub fn into_brackets(string: &String) -> String {
    let mut str_with_brackets: String = String::from("[");
    str_with_brackets = format!("{}{}", str_with_brackets, string);
    format!("{}{}", str_with_brackets, "]")
}

pub fn into_label(label_name: &String) -> String {
    format!("{}{}", DEF_LABEL, into_braces(label_name))
}

fn into_bold(string: &String) -> String {
    format!("{}{}", DEF_BOLD, into_braces(string))
}

fn into_italic(string: &String) -> String {
    format!("{}{}", DEF_ITALIC, into_braces(string) )
}

fn into_color(string: &String, color: &String) -> String {
    let formatted_string = format!("{}{}{}", DEF_COLOR, into_braces(color), into_braces(string));
    into_braces(&formatted_string)
}

pub fn indent_line(doc: &Document, num_tabs: &usize) -> Result<(), Error> {
    let tabs_str: String = "\t".repeat(*num_tabs);
    write!(doc.get_file(), "{}", tabs_str)
}

pub fn write_indented_line(doc: &Document, num_tabs: &usize, text: &str) -> Result<(), Error> {
    indent_line(&doc, num_tabs)?;
    writeln!(doc.get_file(), "{}", text)
}

enum FormatType {
    Bold,
    Italic,
    Color
}

impl FormatType {
    fn handle_formatting(&self, text: &String, color: Option<&String>) -> String {
        match self {
            FormatType::Bold => into_bold(text),
            FormatType::Italic => into_italic(text),
            FormatType::Color => into_color(text, color.unwrap())
        }
    }
}

pub fn format_text(text: String) -> String {
    handle_color(handle_italic(handle_bold(text)))
}

fn handle_bold(text: String) -> String {
    let bold_regex: Result<Regex, regex::Error> = Regex::new(BOLD_REGEX);

    match bold_regex {
        Ok(regex) => replace_matches(text, regex, FormatType::Bold),

        Err(error) => {
            println!("Bold regex error: {}", error);
            text
        }
    }
}

fn handle_italic(text: String) -> String {
    let italic_regex: Result<Regex, regex::Error> = Regex::new(ITALIC_REGEX);

    match italic_regex {
        Ok(regex) => replace_matches(text, regex, FormatType::Italic),

        Err(error) => {
            println!("Italic regex error: {}", error);
            text
        }
    }
}

fn handle_color(text: String) -> String {
    let color_regex: Result<Regex, regex::Error> = Regex::new(COLOR_REGEX);

    match color_regex {
        Ok(regex) => replace_matches(text, regex, FormatType::Color),

        Err(error) => {
            println!("Color regex error: {}", error);
            text
        }
    }
}

fn replace_matches(text: String, regex: Regex, format_type: FormatType) -> String {
    let captures = regex.captures_iter(&text);
    let mut new_text = text.clone();

    for capture in captures {
        match format_type {
            FormatType::Color => {
                new_text = regex
                    .replace(&new_text, format_type.handle_formatting(
                        &capture["text"].to_string(),
                        Some(&capture["color"].to_string())
                    ))
                    .into_owned();
            }

            _ => {
                new_text = regex
                    .replace(&new_text, format_type.handle_formatting(&capture["text"].to_string(), None))
                    .into_owned();
            }
        }
    }

    new_text
}