aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico Igne <git@federicoigne.com>2022-04-25 19:06:31 +0100
committerFederico Igne <git@federicoigne.com>2022-05-27 00:45:21 +0100
commit28b7a0fe190049b50c0033fafbcc618775e1fc79 (patch)
tree43e314fcea768539659f11d2c24d6ef0b1ea653b
parent33546fe83f06970acad2b505afd8733eb0a91b0d (diff)
downloadpangler-28b7a0fe190049b50c0033fafbcc618775e1fc79.tar.gz
pangler-28b7a0fe190049b50c0033fafbcc618775e1fc79.zip
feat: perform recursive macro substitution
-rw-r--r--src/main.rs40
1 files changed, 28 insertions, 12 deletions
diff --git a/src/main.rs b/src/main.rs
index eef5537..27b6510 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,4 +1,5 @@
1use std::io::Result; 1use std::io::Result;
2use std::borrow::Cow;
2use std::path::PathBuf; 3use std::path::PathBuf;
3use std::collections::HashMap; 4use std::collections::HashMap;
4use lazy_static::lazy_static; 5use lazy_static::lazy_static;
@@ -6,23 +7,33 @@ use regex::{Captures,Regex};
6use pandoc::{InputFormat,InputKind,OutputFormat,OutputKind,Pandoc}; 7use pandoc::{InputFormat,InputKind,OutputFormat,OutputKind,Pandoc};
7use pandoc_ast::Block; 8use pandoc_ast::Block;
8 9
9type Blocks<'a> = HashMap<&'a str,&'a str>; 10type Blocks<'a> = HashMap<String,Cow<'a,str>>;
10 11
11fn build(blocks: &Blocks, entry: &str) -> String { 12fn build_block(blocks: &Blocks, code: &Cow<str>) -> String {
12 lazy_static! { 13 lazy_static! {
13 static ref RE: Regex = Regex::new(r"(?m)^([[:blank:]]*)<<([^>\s]+)>>").unwrap(); 14 static ref MACRO: Regex = Regex::new(r"(?m)^([[:blank:]]*)<<([^>\s]+)>>").unwrap();
14 } 15 }
15 if let Some(entry) = blocks.get(entry).clone() { 16 if MACRO.is_match(&code) {
16 RE.replace_all(entry, |caps: &Captures| 17 let code = MACRO.replace_all(&code, |caps: &Captures| {
18 let indent = caps[1].len();
17 blocks.get(&caps[2]) 19 blocks.get(&caps[2])
18 .expect("Block not present") 20 .expect("Block not present")
19 .lines() 21 .lines()
20 .map(|l| format!("{}{}", &caps[1], l) ) 22 .map(|l| format!("{:indent$}{}", "", l) )
21 .collect::<Vec<_>>() 23 .collect::<Vec<_>>()
22 .join("\n") 24 .join("\n")
23 ).to_string() 25 }
26 );
27 build_block(blocks, &code)
24 } else { 28 } else {
25 String::from("") 29 code.to_string()
30 }
31}
32
33fn build(blocks: &Blocks, entry: &str) {
34 if let Some(code) = blocks.get(entry) {
35 let string = build_block(blocks, code);
36 println!("{}", string);
26 } 37 }
27} 38}
28 39
@@ -39,17 +50,22 @@ fn main() -> Result<()> {
39 let mut blocks: Blocks = HashMap::new(); 50 let mut blocks: Blocks = HashMap::new();
40 pandoc.blocks.iter().for_each(|block| 51 pandoc.blocks.iter().for_each(|block|
41 if let Block::CodeBlock(attr, code) = block { 52 if let Block::CodeBlock(attr, code) = block {
42 dbg!(block); 53 // let _classes = &attr.1;
54 // dbg!(block);
43 if attr.0.len() > 0 { 55 if attr.0.len() > 0 {
44 blocks.insert(&attr.0, &code); 56 let mut key = attr.2.iter()
57 .find_map(|(k,v)| if k == "path" { Some(v.clone()) } else { None })
58 .unwrap_or(String::from(""));
59 key.push_str(&attr.0);
60 /* Insert (or replace) block of code */
61 blocks.insert(key, Cow::from(code));
45 } else { 62 } else {
46 // println!("The following code has no ID:"); 63 // println!("The following code has no ID:");
47 // code.lines().for_each(|l| println!(" {}", l)); 64 // code.lines().for_each(|l| println!(" {}", l));
48 } 65 }
49 } 66 }
50 ); 67 );
51 let program = build(dbg!(&blocks), "main.rs"); 68 build(dbg!(&blocks), "src/main.rs");
52 //println!("{}", program);
53 pandoc 69 pandoc
54 })); 70 }));
55 pandoc.execute().unwrap(); 71 pandoc.execute().unwrap();