aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.rs23
1 files changed, 16 insertions, 7 deletions
diff --git a/src/main.rs b/src/main.rs
index 23789b6..ea4e4f7 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -17,7 +17,11 @@ type Blocks<'a> = HashMap<String,Cow<'a,str>>;
17#[derive(Parser, Debug)] 17#[derive(Parser, Debug)]
18#[clap(author, version, about, long_about = None)] 18#[clap(author, version, about, long_about = None)]
19struct Config { 19struct Config {
20 /// Base output directory (default: './code') 20 /// Maximum substitution depth
21 #[clap(short, long, default_value_t = 10)]
22 depth: u32,
23
24 /// Base output directory [default: './code']
21 #[clap(short, long)] 25 #[clap(short, long)]
22 output: Option<PathBuf>, 26 output: Option<PathBuf>,
23 27
@@ -91,23 +95,28 @@ fn indent<'a>(input: Cow<'a,str>, indent: usize) -> Cow<'a,str> {
91 * of the borrowed value `text`. Moreover `text` takes ownership of `new_text: String` using 95 * of the borrowed value `text`. Moreover `text` takes ownership of `new_text: String` using
92 * the `Cow::from()` function. No heap allocation is performed, and the string is not copied. 96 * the `Cow::from()` function. No heap allocation is performed, and the string is not copied.
93 */ 97 */
94fn build(base: &Option<PathBuf>, blocks: &Blocks) { 98fn build(base: &Option<PathBuf>, blocks: &Blocks, depth: u32) {
95 lazy_static! { 99 lazy_static! {
96 static ref PATH: Regex = Regex::new(r"^(?:[[:word:]\.-]+/)*[[:word:]\.-]+\.[[:alpha:]]+$").unwrap(); 100 static ref PATH: Regex = Regex::new(r"^(?:[[:word:]\.-]+/)*[[:word:]\.-]+\.[[:alpha:]]+$").unwrap();
97 static ref MACRO: Regex = Regex::new(r"(?m)^([[:blank:]]*)<<([^>\s]+)>>").unwrap(); 101 static ref MACRO: Regex = Regex::new(r"(?m)^([[:blank:]]*)<<([^>\s]+)>>").unwrap();
98 } 102 }
99 blocks.iter().for_each(|(k,v)| if PATH.is_match(k) { 103 blocks.iter().for_each(|(k,v)| if PATH.is_match(k) {
104 let mut d = 0;
100 let mut code = v.clone(); // No clone is happening because the value is a `Borrowed` 105 let mut code = v.clone(); // No clone is happening because the value is a `Borrowed`
101 // Here `replace_all` returns a `Owned` value only when a replacement takes place. 106 // Here `replace_all` returns a `Owned` value only when a replacement takes place.
102 // We can use it to recursively build blocks of code until no more substitutions are 107 // We can use it to recursively build blocks of code until no more substitutions are
103 // necessary (i.e., `replace_all` returns a `Borrowed`). 108 // necessary (i.e., `replace_all` returns a `Borrowed`).
104 while let Cow::Owned(step) = MACRO.replace_all(&code, |caps: &Captures| { 109 while let Cow::Owned(step) = MACRO.replace_all(&code, |caps: &Captures| {
105 indent( 110 let block = if d < depth {
106 blocks.get(&caps[2]).expect("Block not present").clone(), 111 blocks.get(&caps[2]).expect("Block not present").clone()
107 caps[1].len() 112 } else {
108 ) 113 eprintln!("Reached maximum depth, output might be truncated. Increase `--depth` accordingly.");
114 Cow::Owned(String::from(""))
115 };
116 indent(block, caps[1].len())
109 }) { 117 }) {
110 code = Cow::from(step); 118 code = Cow::from(step);
119 d += 1;
111 } 120 }
112 write_to_file(base, k, &code).expect("Unable to write to file"); 121 write_to_file(base, k, &code).expect("Unable to write to file");
113 }) 122 })
@@ -153,7 +162,7 @@ fn main() -> Result<()> {
153 } 162 }
154 } 163 }
155 ); 164 );
156 build(&config.output, &blocks); 165 build(&config.output, &blocks, config.depth);
157 pandoc 166 pandoc
158 })); 167 }));
159 pandoc.execute().unwrap(); 168 pandoc.execute().unwrap();