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
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//! ***(some of the following information may be subject to change)***
//! # Aldoc
//! 
//! *aldoc* is a Markdown variant with the goal of providing the beauty and control 
//! of LaTeX documents with Markdown's pretty syntax, in other words, letting you 
//! write your documents without ever needing to touch LaTeX code.
//! 
//! ## Status
//! 
//! This project is still in its infancy (pre-alpha), and major design decisions 
//! haven't been taken yet. The goals spoken of haven't been reached yet, and 
//! features are lacking, this shouldn't be used on its current state.
//! 
//! ## Syntax 
//! 
//! The syntax of aldoc is still *WIP*: what syntax will be the most beneficious 
//! has not yet been decided, but still, the one used for testing temporarily is 
//! the following:
//! 
//! - Paragraphs are spaced with a blank line between them. (this example 
//! cannot be shown on the Rustdoc)
//! - Unnumbered lists can be written with the `-` or the `+` character.
//! 	```
//! 	- Alement
//! 	- Belement
//! 	- Celement
//! 	```
//! - Enumerated lists can be written in many ways. Aldoc's design allow you to use
//! any combination of enumerator (`1`, `a`, `III`) and symbol (`.`, `)`, `-`).
//! 	- With numbers:
//! 		```
//! 		1. Alement
//! 		2. Belement
//! 		3. Celement
//! 		```
//! 	- With letters (uppercase or lowercase):
//! 		```
//! 		a) Alement
//! 		b) Belement
//! 		c) Celement
//! 		```
//! 	- With roman numbers (uppercase or lowercase):
//! 		```
//! 		I- Alement
//! 		II- Belement
//! 		III- Celement
//! 		```
//! ## Tool
//! 
//! As a tool, library and Cargo package, it provides an abstraction for the 
//! language and also a way to compile the documents to PDF. To do that the 
//! following processes takes place:
//! 
//! 1. The aldoc source is parsed into a Rust abstraction.
//! 2. The abstraction is compiled to LaTeX.
//! 3. The LaTeX code is compiled to PDF via Tectonic.
//! 
//! ### Usage
//! 
//! To actually compile the document, you only need to provide it with the input
//! file path (.ald) and the output pdf path, like this:
//! 
//! ```shell
//! $ aldoc doc.md compile out.pdf
//! ```
//! 
//! You may even omit the output file, in which case, aldoc will output a pdf
//! with the same name as the document.
//! 
//! ```shell
//! $ aldoc doc.md compile # outputs pdf as "doc.pdf"
//! ```

mod parse;
mod compiler;
mod pdf;

pub use crate::{
    pdf::{PdfError, save_as_pdf},
    compiler::{Compiler, IntoLatex, IntoPrintable},
    parse::{Document, parse}
};
use nom::Err as NomError;
use nom::error::ErrorKind;
use std::io::Error as IoError;

use thiserror::Error;

#[derive(Error, Debug)]
pub enum AldocError {
    #[error("Error reading file")]
    FileError(#[from] IoError),
    #[error("Document is empty")]
    EmptyDocument,
    #[error("Error parsing document")]
    ParseError(NomError<(String, ErrorKind)>),
    #[error("Error exporting to PDF: {0}")]
    PdfError(#[from] PdfError)
}
impl From<NomError<(&str, ErrorKind)>> for AldocError {
    fn from(e: NomError<(&str, ErrorKind)>) -> AldocError {
        AldocError::ParseError(e.to_owned())
    }
}

#[cfg(test)]
mod tests {
    use crate::AldocError;
    use crate::pdf::save_as_pdf;
    use crate::parse::parse;
    use std::path::PathBuf;

    fn quick_pdf<T>(p: T) -> Result<(), AldocError>
        where T: Into<PathBuf> 
    {
        let text = std::fs::read_to_string(p.into()).unwrap();
        let document = parse(&text)?;
        save_as_pdf(&document, "test/test.pdf", true)?; // some tests don't need to be saved to a pdf
        Ok(())
    }
    fn quick_parse<T>(p: T) -> Result<(), AldocError>
        where T: Into<PathBuf> 
    {
        let text = std::fs::read_to_string(p.into()).unwrap();
        parse(&text)?;
        Ok(())
    }
}