Compare commits
	
		
			2 commits
		
	
	
		
			3018db7dd1
			...
			ef9b4f3769
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| ef9b4f3769 | |||
| 0c3d77b90b | 
					 2 changed files with 55 additions and 16 deletions
				
			
		| 
						 | 
					@ -64,9 +64,7 @@ fn wave_numbers(input: &str) -> IResult<&str, (usize, u8)> {
 | 
				
			||||||
                })
 | 
					                })
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
        space1,
 | 
					        space1,
 | 
				
			||||||
        map_res(hexordecimal, |(radix, s)| {
 | 
					        map_res(hexordecimal, |(radix, s)| u8::from_str_radix(s, radix)),
 | 
				
			||||||
            u8::from_str_radix(s, radix)
 | 
					 | 
				
			||||||
        }),
 | 
					 | 
				
			||||||
    )(input)
 | 
					    )(input)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										67
									
								
								src/mfvi.rs
									
										
									
									
									
								
							
							
						
						
									
										67
									
								
								src/mfvi.rs
									
										
									
									
									
								
							| 
						 | 
					@ -14,22 +14,22 @@ struct Translation<'a> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Clone)]
 | 
					#[derive(Clone)]
 | 
				
			||||||
/// Holds the set of delimiters that should be removed from the MML to select a variant.
 | 
					/// Holds the set of delimiters that should be removed from the MML to select a variant.
 | 
				
			||||||
pub struct Variant<'v> {
 | 
					pub struct Variant {
 | 
				
			||||||
    keep_delim: &'v str,
 | 
					    keep_delim: char,
 | 
				
			||||||
    remove_delims: HashSet<&'v str>,
 | 
					    remove_delims: HashSet<char>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'v> Variant<'v> {
 | 
					impl Variant {
 | 
				
			||||||
    /// Get the set of character delimiters to remove from MML for this variant.
 | 
					    /// Get the set of character delimiters to remove from MML for this variant.
 | 
				
			||||||
    pub fn ignores(&self) -> &HashSet<&str> {
 | 
					    pub fn ignores(&self) -> &HashSet<char> {
 | 
				
			||||||
        &self.remove_delims
 | 
					        &self.remove_delims
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// The list of all variants defined in an MML file.
 | 
					/// The list of all variants defined in an MML file.
 | 
				
			||||||
pub struct VariantList<'v> {
 | 
					pub struct VariantList<'v> {
 | 
				
			||||||
    all_delims: HashSet<&'v str>,
 | 
					    all_delims: HashSet<char>,
 | 
				
			||||||
    variants: BTreeMap<&'v str, Variant<'v>>,
 | 
					    variants: BTreeMap<&'v str, Variant>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'v> VariantList<'v> {
 | 
					impl<'v> VariantList<'v> {
 | 
				
			||||||
| 
						 | 
					@ -43,14 +43,16 @@ impl<'v> VariantList<'v> {
 | 
				
			||||||
    fn finish(mut self) -> Self {
 | 
					    fn finish(mut self) -> Self {
 | 
				
			||||||
        for (_, v) in self.variants.iter_mut() {
 | 
					        for (_, v) in self.variants.iter_mut() {
 | 
				
			||||||
            v.remove_delims = self.all_delims.clone();
 | 
					            v.remove_delims = self.all_delims.clone();
 | 
				
			||||||
            v.remove_delims.remove(v.keep_delim);
 | 
					            v.remove_delims.remove(&v.keep_delim);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.variants.is_empty() {
 | 
					        if self.variants.is_empty() {
 | 
				
			||||||
            self.variants.insert(
 | 
					            self.variants.insert(
 | 
				
			||||||
                "_default_",
 | 
					                "_default_",
 | 
				
			||||||
                Variant {
 | 
					                Variant {
 | 
				
			||||||
                    keep_delim: "",
 | 
					                    // Not that we expect to find NUL bytes, but effectively we will remove all
 | 
				
			||||||
 | 
					                    // delimiters with this variant.
 | 
				
			||||||
 | 
					                    keep_delim: '\0',
 | 
				
			||||||
                    remove_delims: self.all_delims.clone(),
 | 
					                    remove_delims: self.all_delims.clone(),
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
| 
						 | 
					@ -115,17 +117,17 @@ pub fn get_variants<'a>(input: &'a str, sfx_mode: SfxMode) -> VariantList<'a> {
 | 
				
			||||||
                if let Some((first, second)) = l.trim().rsplit_once(char::is_whitespace) {
 | 
					                if let Some((first, second)) = l.trim().rsplit_once(char::is_whitespace) {
 | 
				
			||||||
                    use SfxMode::*;
 | 
					                    use SfxMode::*;
 | 
				
			||||||
                    match sfx_mode {
 | 
					                    match sfx_mode {
 | 
				
			||||||
                        Off => state.all_delims.insert(first),
 | 
					                        Off => state.all_delims.insert(first_char(first)),
 | 
				
			||||||
                        On => state.all_delims.insert(second),
 | 
					                        On => state.all_delims.insert(first_char(second)),
 | 
				
			||||||
                    };
 | 
					                    };
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } else if let Some(l) = line.strip_prefix("#VARIANT") {
 | 
					            } else if let Some(l) = line.strip_prefix("#VARIANT") {
 | 
				
			||||||
                let (first, second) = {
 | 
					                let (first, second) = {
 | 
				
			||||||
                    let rest = l.trim();
 | 
					                    let rest = l.trim();
 | 
				
			||||||
                    if let Some((f, s)) = rest.rsplit_once(' ') {
 | 
					                    if let Some((f, s)) = rest.rsplit_once(' ') {
 | 
				
			||||||
                        (f, s)
 | 
					                        (first_char(f), s)
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        (rest, "_default_")
 | 
					                        (first_char(rest), "_default_")
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -153,3 +155,42 @@ pub fn get_variants<'a>(input: &'a str, sfx_mode: SfxMode) -> VariantList<'a> {
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        .finish()
 | 
					        .finish()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn first_char(s: &str) -> char {
 | 
				
			||||||
 | 
					    s.chars().next().unwrap_or('\0')
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn select_variant<'i>(input: &'i str, var: &'i Variant) -> String {
 | 
				
			||||||
 | 
					    let mut output = input.to_string();
 | 
				
			||||||
 | 
					    // Workspace for converting char to &str in the loop.
 | 
				
			||||||
 | 
					    let mut buf = [0; 4];
 | 
				
			||||||
 | 
					    // Set of chars to find in `input`.
 | 
				
			||||||
 | 
					    let charlist: Vec<char> = var
 | 
				
			||||||
 | 
					        .remove_delims
 | 
				
			||||||
 | 
					        .iter()
 | 
				
			||||||
 | 
					        .copied()
 | 
				
			||||||
 | 
					        .chain([var.keep_delim])
 | 
				
			||||||
 | 
					        .collect();
 | 
				
			||||||
 | 
					    let mut needles = input.rmatch_indices(&charlist[..]).peekable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while let Some((idx, c)) = needles.next() {
 | 
				
			||||||
 | 
					        match c {
 | 
				
			||||||
 | 
					            // Remove the char if it is the `keep_delim`.
 | 
				
			||||||
 | 
					            d if var.keep_delim.encode_utf8(&mut buf) == d => {
 | 
				
			||||||
 | 
					                // `replace_range` doesn't make a full copy of the string the way `remove` does.
 | 
				
			||||||
 | 
					                output.replace_range(idx..=idx, "");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            // Anything else will be in `remove_delim`, so find a matching pair and remove
 | 
				
			||||||
 | 
					            // them and everything between them.
 | 
				
			||||||
 | 
					            d => match needles.peek() {
 | 
				
			||||||
 | 
					                Some(&(idx_1, d2)) if d == d2 => {
 | 
				
			||||||
 | 
					                    needles.next();
 | 
				
			||||||
 | 
					                    output.replace_range(idx_1..=idx, "");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                _ => {}
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    output
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue