tex2csv 0.2.0

Utility to convert a LaTeX Table to a csv file.
Documentation
use std::fs::File;
use std::io::{BufRead, BufReader, Write};

/// This function shall parse a LaTex Table into a csv file.
/// This simplest case of such a table might look like this:
/// ```latex
/// \begin{tabular}{|c|c|c|}
///   \hline
///   Name & Age & City \\
///   \hline
///   John & 25 & New York \\
///   Jane & 30 & San Francisco \\
///   \hline
/// \end{tabular}
/// ```
/// The `tabular` environment can be something else, e.g. `longtable`.
///
/// Arguments
/// =========
///     * `file_handle` - A handle to a `BufReader`, i.e. the .tex file.
///     * `environment` - A string slice specifing the name of the environment wrapping the table
pub fn parse_file(
    tex_file_handle: BufReader<File>,
    mut csv_file: File,
    environment: &str,
) -> Result<(), Box<dyn std::error::Error>> {
    let open_env: String = String::from(r"\begin{") + environment;
    let close_env: String = String::from(r"\end{") + environment;
    // Parse exclusion file
    let exclude_lines = match File::open("exclude_lines.txt") {
        Ok(f) => f,
        Err(e) => {
            println!(
                r"You need to supply a file 'exclude_lines.txt' containing keyword identifying lines to be skipped.
        For example: 
            \midrule
            \toprule
            \endheader
            \begin
            \end
            {}
            ", e
            );
            panic!("No 'exclude_lines.txt' given.")
        }
    };
    let exclude_handle = BufReader::new(exclude_lines);
    let exclude_iterator = parse_exclude_list(exclude_handle).unwrap();
    // Iterate over each line in the LaTeX file
    for line in tex_file_handle.lines() {
        // Unwrap Result returned in the lines iterator.
        let line = line?;
        // Check if we have a separator, open/closing of environment or empty line
        if exclude_iterator.contains(&line.trim().to_owned())
            || line.trim().is_empty()
            || line.trim().contains(&open_env)
            || line.trim().contains(&close_env)
        {
            continue;
        } else {
            // Split the line into columns using "&" as a delimiter and remove "\\"
            let columns: Vec<&str> = line.split('&').map(|s| s.trim()).collect();
            let columns: Vec<String> = columns.iter().map(|&s| s.replace(r"\\", "")).collect();
            // Write the CSV header to the CSV file
            writeln!(csv_file, "{}", columns.join(","))?;
        }
    }
    Ok(())
}

/// This function makes it possible to parse a file with keywords to be skipped on parsing the tex
/// file
pub fn parse_exclude_list(
    exclude_file: BufReader<File>,
) -> Result<Vec<String>, Box<dyn std::error::Error>> {
    let exclude_list: Vec<String> = exclude_file.lines().map(|l| l.unwrap()).collect();
    println!("Parsed exclusion list:");
    for i in exclude_list.iter() {
        println!("{}",i)
    }
    Ok(exclude_list)
}