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
|
both the front and the back text will be shown in the popup when one of them
|
||||||
matches.
|
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
|
## Installation
|
||||||
|
|
||||||
Binary builds of the map generator for Linux and Windows, as well as an archive
|
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 anyhow::{Context, Result};
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
use regex::RegexSet;
|
use regex::{Regex, RegexSet};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -130,6 +130,7 @@ pub enum TileKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Common configuration based on command line arguments
|
/// Common configuration based on command line arguments
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
/// Number of threads for parallel processing
|
/// Number of threads for parallel processing
|
||||||
pub num_threads: usize,
|
pub num_threads: usize,
|
||||||
|
@ -151,6 +152,8 @@ pub struct Config {
|
||||||
pub viewer_entities_path: PathBuf,
|
pub viewer_entities_path: PathBuf,
|
||||||
/// Sign text filter patterns
|
/// Sign text filter patterns
|
||||||
pub sign_patterns: RegexSet,
|
pub sign_patterns: RegexSet,
|
||||||
|
/// Sign text transformation pattern
|
||||||
|
pub sign_transforms: Vec<(Regex, String)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
|
@ -173,6 +176,8 @@ impl Config {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let sign_patterns = Self::sign_patterns(args).context("Failed to parse sign patterns")?;
|
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 {
|
Ok(Config {
|
||||||
num_threads,
|
num_threads,
|
||||||
|
@ -185,6 +190,7 @@ impl Config {
|
||||||
viewer_info_path,
|
viewer_info_path,
|
||||||
viewer_entities_path,
|
viewer_entities_path,
|
||||||
sign_patterns,
|
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
|
/// Constructs the path to an input region file
|
||||||
pub fn region_path(&self, coords: TileCoords) -> PathBuf {
|
pub fn region_path(&self, coords: TileCoords) -> PathBuf {
|
||||||
let filename = coord_filename(coords, "mca");
|
let filename = coord_filename(coords, "mca");
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! The [MetadataWriter] and related types
|
//! The [MetadataWriter] and related types
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
|
use regex::Regex;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -8,7 +9,7 @@ use crate::{
|
||||||
io::{fs, storage},
|
io::{fs, storage},
|
||||||
world::{
|
world::{
|
||||||
block_entity::{self, BlockEntity, BlockEntityData},
|
block_entity::{self, BlockEntity, BlockEntityData},
|
||||||
de,
|
de, sign,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -145,6 +146,28 @@ impl<'a> MetadataWriter<'a> {
|
||||||
false
|
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
|
/// Generates [Entities] data from collected entity lists
|
||||||
fn entities(&self) -> Result<Entities> {
|
fn entities(&self) -> Result<Entities> {
|
||||||
let data: ProcessedEntities =
|
let data: ProcessedEntities =
|
||||||
|
@ -158,6 +181,12 @@ impl<'a> MetadataWriter<'a> {
|
||||||
.filter(|entity| match &entity.data {
|
.filter(|entity| match &entity.data {
|
||||||
BlockEntityData::Sign(sign) => self.sign_filter(sign),
|
BlockEntityData::Sign(sign) => self.sign_filter(sign),
|
||||||
})
|
})
|
||||||
|
.map(|mut entity| {
|
||||||
|
match &mut entity.data {
|
||||||
|
BlockEntityData::Sign(sign) => self.sign_transform(sign),
|
||||||
|
};
|
||||||
|
entity
|
||||||
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,12 @@ pub struct Args {
|
||||||
/// To make all signs visible, pass an empty string to either option.
|
/// To make all signs visible, pass an empty string to either option.
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
pub sign_filter: Vec<String>,
|
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
|
/// Minecraft save directory
|
||||||
pub input_dir: PathBuf,
|
pub input_dir: PathBuf,
|
||||||
/// MinedMap data directory
|
/// MinedMap data directory
|
||||||
|
|
Loading…
Add table
Reference in a new issue