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
129
130
131
132
133
134
135
136
137
138
139
140
141
//! ***(some of the following information may be subject to change)***
//! # Aldoc
//! 
//! *aldoc* is a markup language, which takes heavy inspiration from Markdown. Its
//! main goal is to provide the beauty and control of LaTeX documents with 
//! Markdown's pretty syntax.
//! 
//! Another one of its goals is to remove the quirks that Markdown brings with its 
//! original design, such as:
//! 
//! - Different versions and editions of Markdown which mildly in syntax, thus 
//! making it unreliable for posting on multiple platforms (GitHub Markdown, 
//! original HTML Markdown, Pandoc Markdown, etc.)
//! - Markdown was not intended for use outside of small documents, such as
//! small notes or READMEs (this one), which led to decisions that impacted the
//! ergonomics in the syntax (pandoc filters) and ended up in the creation of the 
//! different variants.
//! 
//! ## 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
//! 		```
//! - Bold text is written with asterisks around it.
//! 	```
//! 	Normal text is written *until the asterisks come around*.
//! 	```
//! ## 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 LatexMk (this step is planned to 
//! change)
//! 
//! 
//! ### 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.ald 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.ald 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 parse::*;
use thiserror::Error;

#[derive(Error, Debug)]
pub enum AldocError {
    #[error("Error parsing document")]
    ParseError(String),
    #[error("Error compiling document")]
    CompilationError, // unimplemented
    #[error("Error exporting to PDF: {0}")]
    PdfError(PdfError)
}
impl<'s> From<ParseError<'s>> for AldocError {
    fn from(e: ParseError) -> AldocError {
        AldocError::ParseError(e.to_string())
    }
}
impl From<PdfError> for AldocError {
    fn from(e: PdfError) -> AldocError {
        AldocError::PdfError(e)
    }
}

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

    // This function is for tests
    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")?; // 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(())
    }
}