aboutsummaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md78
1 files changed, 63 insertions, 15 deletions
diff --git a/README.md b/README.md
index 69ca732..5bd146e 100644
--- a/README.md
+++ b/README.md
@@ -48,7 +48,32 @@ the language of the code snippet can be provided and is useful to enable correct
48``` 48```
49~~~ 49~~~
50 50
51An identifier can also be a file name matching the following regex 51### Identifiers
52
53An identifier can either be a string, representing a macro to be used inside other code blocks, or a filename.
54In the latter, the code block will be considered a valid entry point for code generation.
55
56```{#types .rust}
57#[derive(Eq, Hash, PartialEq)]
58enum Key {
59 Macro(String),
60 Entry(PathBuf)
61}
62
63impl Key {
64 fn get_path(&self) -> Option<&PathBuf> {
65 match self {
66 Self::Entry(s) => Some(&s),
67 Self::Macro(_) => None
68 }
69 }
70}
71
72```
73
74There are currently 3 (possibly overlapping) scenarios in which an identifier is considered a valid filename.
75
76First, the filename matches the following regex
52 77
53```{#regex_path .rust} 78```{#regex_path .rust}
54static ref PATH: Regex = 79static ref PATH: Regex =
@@ -57,8 +82,7 @@ static ref PATH: Regex =
57 ).unwrap(); 82 ).unwrap();
58``` 83```
59 84
60In that case the code block is considered a valid **entry point** for the generation of a file with that name. 85For example
61The code block defines the content of the new file.
62 86
63~~~ 87~~~
64```{#file.py .python} 88```{#file.py .python}
@@ -66,8 +90,10 @@ The code block defines the content of the new file.
66``` 90```
67~~~ 91~~~
68 92
69File names can be generated in subfolders using the `path` attribute. 93Second, the code block contains a `path` attribute.
70The following code block determines the content of file `path/to/file.py`. 94With this feature, we can generated a file into a more complex folder structure.
95
96For example, the following code block determines the content of file `path/to/file.py`.
71 97
72~~~ 98~~~
73```{#file.py .python path="path/to/"} 99```{#file.py .python path="path/to/"}
@@ -77,16 +103,30 @@ The following code block determines the content of file `path/to/file.py`.
77 103
78This path is relative to the current working directory, unless [the `-o`/`--output` flag is used](#command-line-interface). 104This path is relative to the current working directory, unless [the `-o`/`--output` flag is used](#command-line-interface).
79 105
106Third, the code contains the `entry` class.
107This is useful when declaring an entry point that doesn't match any of the previous cases.
108
109~~~
110```{#Dockerfile .dockerfile .entry}
111[Docker directives]
112```
113~~~
114
115Any ID that doesn't match any of the previous cases is considered an internal macro.
80Code blocks without an ID are ignored. 116Code blocks without an ID are ignored.
81 117
82```{#code_block_gathering .rust} 118```{#code_block_gathering .rust}
83if !id.is_empty() { 119if !id.is_empty() {
84 let key = { 120 let key = {
85 let path = attrs.iter().find(|(k,_)| k == "path"); 121 <<regex_path_lazy>>
86 if let Some(path) = path { 122 let entry = clss.contains(&String::from("entry"));
87 format!("{}{}", path.1, id) 123 let path = attrs
124 .into_iter()
125 .find_map(|(k,p)| if k == "path" { Some(p.clone()) } else { None });
126 if entry || path.is_some() || PATH.is_match(id) {
127 Key::Entry(PathBuf::from(path.unwrap_or_default()).join(id))
88 } else { 128 } else {
89 id.to_string() 129 Key::Macro(id.to_string())
90 } 130 }
91 }; 131 };
92 <<code_block>> 132 <<code_block>>
@@ -96,6 +136,8 @@ if !id.is_empty() {
96} 136}
97``` 137```
98 138
139### Redefining code blocks
140
99Code blocks are processed in order. 141Code blocks are processed in order.
100By default, if an identifier is already defined, the code block is appended to the current corresponding value. 142By default, if an identifier is already defined, the code block is appended to the current corresponding value.
101 143
@@ -314,7 +356,7 @@ use std::collections::HashMap;
314``` 356```
315 357
316```{#types .rust} 358```{#types .rust}
317type Blocks<'a> = HashMap<String,Cow<'a,str>>; 359type Blocks<'a> = HashMap<Key,Cow<'a,str>>;
318``` 360```
319 361
320Code blocks are wrapped into a [`Cow`](https://doc.rust-lang.org/stable/std/borrow/enum.Cow.html), i.e., a "copy-on-write" smart pointer, to avoid string duplication, unless strictly necessary. 362Code blocks are wrapped into a [`Cow`](https://doc.rust-lang.org/stable/std/borrow/enum.Cow.html), i.e., a "copy-on-write" smart pointer, to avoid string duplication, unless strictly necessary.
@@ -366,7 +408,7 @@ In case we reach the maximum allowed depth we truncate code block substitution a
366|caps: &Captures| { 408|caps: &Captures| {
367 if current_depth < max_depth { 409 if current_depth < max_depth {
368 let block = blocks 410 let block = blocks
369 .get(&caps[2]) 411 .get(&Key::Macro(caps[2].to_string()))
370 .expect("Block not present") 412 .expect("Block not present")
371 .clone(); 413 .clone();
372 indent(block, caps[1].len()) 414 indent(block, caps[1].len())
@@ -387,10 +429,11 @@ fn build(
387 blocks: &Blocks, 429 blocks: &Blocks,
388 max_depth: u32 430 max_depth: u32
389) { 431) {
390 <<regex_definition>> 432 <<regex_macro_lazy>>
391 blocks 433 blocks
392 .iter() 434 .iter()
393 .for_each(|(path,code)| if PATH.is_match(path) { 435 .filter_map(|(key,code)| { key.get_path().map(|k| (k,code)) })
436 .for_each(|(path,code)| {
394 <<code_generation>> 437 <<code_generation>>
395 }) 438 })
396} 439}
@@ -506,11 +549,16 @@ use lazy_static::lazy_static;
506use regex::{Captures,Regex}; 549use regex::{Captures,Regex};
507``` 550```
508 551
509We wrap the regex definition in a `lazy_static` macro 552We wrap the regex definitions in a `lazy_static` macro
510 553
511```{#regex_definition .rust} 554```{#regex_path_lazy .rust}
512lazy_static! { 555lazy_static! {
513 <<regex_path>> 556 <<regex_path>>
557}
558```
559
560```{#regex_macro_lazy .rust}
561lazy_static! {
514 <<regex_macro>> 562 <<regex_macro>>
515} 563}
516``` 564```