mirror of
https://github.com/neocturne/MinedMap.git
synced 2025-03-04 17:23:33 +01:00
core: add support for sign text transformations
Add support for regexp replacement patterns, which can be useful when the text matched by --sign-filter or --sign-prefix should not be displayed.
This commit is contained in:
parent
a99a734df8
commit
8a1a26c13c
4 changed files with 71 additions and 2 deletions
|
@ -75,6 +75,12 @@ All prefixes and filters are applied to the front and back text separately, but
|
|||
both the front and the back text will be shown in the popup when one of them
|
||||
matches.
|
||||
|
||||
Finally, `--sign-transform` allows to specify sed-style replacement patterns to
|
||||
modify the text displayed on the map. This can be used if the text matched by
|
||||
`--sign-prefix` or `--sign-filter` should not be displayed:
|
||||
`--sign-filter 's/\[Map\]//'` would replace each occurence of "\[Map\]" with
|
||||
the empty string.
|
||||
|
||||
## Installation
|
||||
|
||||
Binary builds of the map generator for Linux and Windows, as well as an archive
|
||||
|
|
|
@ -8,7 +8,7 @@ use std::{
|
|||
|
||||
use anyhow::{Context, Result};
|
||||
use indexmap::IndexSet;
|
||||
use regex::RegexSet;
|
||||
use regex::{Regex, RegexSet};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
|
@ -130,6 +130,7 @@ pub enum TileKind {
|
|||
}
|
||||
|
||||
/// Common configuration based on command line arguments
|
||||
#[derive(Debug)]
|
||||
pub struct Config {
|
||||
/// Number of threads for parallel processing
|
||||
pub num_threads: usize,
|
||||
|
@ -151,6 +152,8 @@ pub struct Config {
|
|||
pub viewer_entities_path: PathBuf,
|
||||
/// Sign text filter patterns
|
||||
pub sign_patterns: RegexSet,
|
||||
/// Sign text transformation pattern
|
||||
pub sign_transforms: Vec<(Regex, String)>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
|
@ -173,6 +176,8 @@ impl Config {
|
|||
.collect();
|
||||
|
||||
let sign_patterns = Self::sign_patterns(args).context("Failed to parse sign patterns")?;
|
||||
let sign_transforms =
|
||||
Self::sign_transforms(args).context("Failed to parse sign transforms")?;
|
||||
|
||||
Ok(Config {
|
||||
num_threads,
|
||||
|
@ -185,6 +190,7 @@ impl Config {
|
|||
viewer_info_path,
|
||||
viewer_entities_path,
|
||||
sign_patterns,
|
||||
sign_transforms,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -200,6 +206,28 @@ impl Config {
|
|||
)?)
|
||||
}
|
||||
|
||||
/// Parses the sign transform argument into a vector of [Regex] and
|
||||
/// corresponding replacement strings
|
||||
fn sign_transforms(args: &super::Args) -> Result<Vec<(Regex, String)>> {
|
||||
let splitter = Regex::new(r"^s/((?:[^\\/]|\\.)*)/((?:[^\\/]|\\.)*)/$").unwrap();
|
||||
|
||||
args.sign_transform
|
||||
.iter()
|
||||
.map(|t| Self::sign_transform(&splitter, t))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Parses the sign transform argument into a [Regex] and its corresponding
|
||||
/// replacement string
|
||||
fn sign_transform(splitter: &Regex, transform: &str) -> Result<(Regex, String)> {
|
||||
let captures = splitter
|
||||
.captures(transform)
|
||||
.with_context(|| format!("Invalid transform pattern '{}'", transform))?;
|
||||
let regexp = Regex::new(&captures[1])?;
|
||||
let replacement = captures[2].to_string();
|
||||
Ok((regexp, replacement))
|
||||
}
|
||||
|
||||
/// Constructs the path to an input region file
|
||||
pub fn region_path(&self, coords: TileCoords) -> PathBuf {
|
||||
let filename = coord_filename(coords, "mca");
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
//! The [MetadataWriter] and related types
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use regex::Regex;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{
|
||||
|
@ -8,7 +9,7 @@ use crate::{
|
|||
io::{fs, storage},
|
||||
world::{
|
||||
block_entity::{self, BlockEntity, BlockEntityData},
|
||||
de,
|
||||
de, sign,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -145,6 +146,28 @@ impl<'a> MetadataWriter<'a> {
|
|||
false
|
||||
}
|
||||
|
||||
/// Applies a single transform to a [sign::SignText]
|
||||
///
|
||||
/// The regular expression is applied for each line of the sign text
|
||||
/// separately (actually for each element when JSON text is used)
|
||||
fn sign_text_transform(sign_text: &mut sign::SignText, transform: &(Regex, String)) {
|
||||
let (regexp, replacement) = transform;
|
||||
|
||||
for line in &mut sign_text.0 {
|
||||
for text in &mut line.0 {
|
||||
text.text = regexp.replace_all(&text.text, replacement).into_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Applies the configured transforms to the text of a sign
|
||||
fn sign_transform(&self, sign: &mut block_entity::Sign) {
|
||||
for transform in &self.config.sign_transforms {
|
||||
Self::sign_text_transform(&mut sign.front_text, transform);
|
||||
Self::sign_text_transform(&mut sign.back_text, transform);
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates [Entities] data from collected entity lists
|
||||
fn entities(&self) -> Result<Entities> {
|
||||
let data: ProcessedEntities =
|
||||
|
@ -158,6 +181,12 @@ impl<'a> MetadataWriter<'a> {
|
|||
.filter(|entity| match &entity.data {
|
||||
BlockEntityData::Sign(sign) => self.sign_filter(sign),
|
||||
})
|
||||
.map(|mut entity| {
|
||||
match &mut entity.data {
|
||||
BlockEntityData::Sign(sign) => self.sign_transform(sign),
|
||||
};
|
||||
entity
|
||||
})
|
||||
.collect(),
|
||||
};
|
||||
|
||||
|
|
|
@ -59,6 +59,12 @@ pub struct Args {
|
|||
/// To make all signs visible, pass an empty string to either option.
|
||||
#[arg(long)]
|
||||
pub sign_filter: Vec<String>,
|
||||
/// Regular expression replacement pattern for sign texts
|
||||
///
|
||||
/// Accepts patterns of the form 's/regexp/replacement/'. Transforms
|
||||
/// are applied to each line of sign texts separately.
|
||||
#[arg(long)]
|
||||
pub sign_transform: Vec<String>,
|
||||
/// Minecraft save directory
|
||||
pub input_dir: PathBuf,
|
||||
/// MinedMap data directory
|
||||
|
|
Loading…
Add table
Reference in a new issue