1#![allow(dead_code, unused_variables)]
10mod rustla_options;
11pub mod parser;
12use parser::Parser;
13use parser::state_machine::State;
14pub mod doctree;
15use doctree::DocTree;
16pub mod common;
17mod utf8_to_latex;
18
19use std::io::BufRead;
20
21pub fn run() -> Result<(), MainError> {
24 copyright();
25
26 let args: Vec<String> = std::env::args().collect();
27 let args_len = args.len();
28
29 let rustla_options = crate::rustla_options::ruSTLaOptions::new(&args);
30
31 let mut src_lines = Vec::new();
32
33 let path: std::path::PathBuf = if let Some(arg) = args.last() {
36 if args_len == 1 {
37 let stdin = std::io::stdin();
39 for line in stdin.lock().lines() {
40 match line {
41 Ok(line) => src_lines.push(line),
42 Err(e) => {
43 return Err(MainError::InputError(format!(
44 "Error when reading stdin: {}",
45 e
46 )))
47 }
48 }
49 }
50
51 std::path::PathBuf::new()
52 } else if let Ok(pathbuf) = std::fs::canonicalize(arg) {
53 let line_iter = match crate::common::read_path_lines(&pathbuf) {
54 Ok(lines) => lines,
55 Err(e) => {
56 return Err(MainError::PathError(format!(
57 "Could not split file into lines: {}",
58 e
59 )))
60 }
61 };
62 for line in line_iter {
63 match line {
64 Ok(line) => src_lines.push(line),
65 Err(e) => {
66 return Err(MainError::InputError(String::from(
67 "Could not construct a line vector from input...",
68 )))
69 }
70 }
71 }
72
73 pathbuf
74 } else {
75 let stdin = std::io::stdin();
76 for line in stdin.lock().lines() {
77 match line {
78 Ok(line) => src_lines.push(line),
79 Err(e) => {
80 return Err(MainError::InputError(format!(
81 "Error when reading stdin: {}",
82 e
83 )))
84 }
85 }
86 }
87 std::path::PathBuf::new()
88 }
89 } else {
90 unreachable!("No arguments, not even the program itself? Computer says no...")
91 };
92
93 let mut doctree = DocTree::new(path);
96 let mut parser = Parser::new(src_lines, doctree, 0, 0, State::Body, 0);
97
98 use common::ParsingResult;
99
100 doctree = match parser.parse() {
101 ParsingResult::EOF { doctree, .. } | ParsingResult::EmptyStateStack { doctree, .. } => {
102 doctree
103 }
104 ParsingResult::Failure { message, doctree } => {
105 eprintln!("Parsing error: {}", message);
106 doctree
107 }
108 };
109
110 doctree = doctree.perform_restructuredtext_transforms();
111 doctree.write_to_larst(&rustla_options);
112
113 Ok(())
114}
115
116fn copyright() {
118 const VERSION: &'static str = env!("CARGO_PKG_VERSION");
120 const AUTHOR_NAME: &'static str = env!("AUTHOR_NAME");
122 const AUTHOR_YEAR: &'static str = env!("AUTHOR_YEAR");
126 eprintln!("\nThis is ruSTLa, version {}", VERSION);
127 eprintln!("Copyright © {} {}\n", AUTHOR_YEAR, AUTHOR_NAME);
128}
129
130fn usage() {
132 println!("Instructions");
133 println!("============");
134 println!("In order to transpile a document,");
135 println!("point ruSTLa to an rST file with");
136 println!("\n $ rustla path/to/file.rst\n");
137 println!("Capabilities to transpile an entire");
138 println!("toctree will be added later.");
139}
140
141#[derive(Debug)]
142pub enum MainError {
144 PathError(String),
146 InputError(String),
148 ParseError(String),
150 PrintError(String),
152 ArgumentError(String),
154}