WIP: added brackets for clarity in mapping expressions.

This commit is contained in:
Matthias Koefferlein 2020-12-19 16:37:58 +01:00
parent a1eb8c121b
commit 02f96f022a
4 changed files with 95 additions and 11 deletions

View File

@ -155,32 +155,44 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd)
"layer is specified, all source layers addressed with the source specification are "
"combined into this target layer.\n"
"\n"
"For clarity, source and target specifications can be enclosed in round or square brackets. "
"With square brackets, the default target is '*/*' which results in the expansion of a source "
"layer range.\n"
"\n"
"To clone layers, add a mapping statement beginning with a '+' character. While other mapping statements "
"redefine mappings established before, mapping statement starting with '+' will clone the layer (1:m mapping).\n"
"\n"
"It's also possible to cancel mappings established before by using an 'unmap' statement. Such a statement "
"You can cancel mappings established before by using an 'unmap' statement. Such a statement "
"begins with a '-' and lists the layers whose mapping is to be removed. This is useful for creating "
"'mapping holes' in sequences.\n"
"\n"
"If brackets are used, '+' (multi-mapping) and '-' (unmapping) needs to go before the brackets.\n"
"\n"
"Examples:\n"
"\n"
"* 1/0 2/0 3/0-255:17/0\n"
" Selects 1/0, 2/0 and maps layer 3, datatype 0 to 255 to layer 17, datatype 0\n"
" Selects 1/0, 2/0 and maps layer 3, datatype 0 to 255 to layer 17, datatype 0.\n"
" If clarity, the mapping can also be written with brackets like this: '(1/0) (2/0) (3/0-255:17/0)'.\n"
"\n"
"* A:1/0 B:2/0\n"
" Maps named layer A to 1/0 and named layer B to 2/0"
" Maps named layer A to 1/0 and named layer B to 2/0.\n"
" If clarity, the mapping can also be written with brackets like this: '(A:1/0) (B:2/0)'.\n"
"\n"
"* */*:*/* +10/*:1000/*"
" Includes all layers, but in addition copy all layers 10 to 1000 while keeping the datatype\n"
"* [*/*] +(10/*:1000)/*\n"
" Includes all layers, but in addition copies all datatypes of layer 10 to 1000 while keeping the datatype.\n"
" Note the square bracket which implies range expansion and how the brackets give a visual aid for the "
" grouping of the mapping parts.\n"
"\n"
"* */*:*/* -10/*"
" Includes all layers, but drops layer 10, all datatypes."
"* [*/*] -(10/*)\n"
" Includes all layers, but drops all datatypes from layer 10 through 'unmapping'.\n"
" Please note, that this specification requires -" + m_prefix + "s (skip unknown layers) because otherwise the "
" unmapped layers are still created through the unknown layer fallback path.\n"
)
<< tl::arg (group +
"--" + m_long_prefix + "layer-map-file=map", this, &GenericReaderOptions::set_layer_map_file, "Specifies the layer mapping for the input as a file",
"This option specifies the layer selection or mapping like + -" + m_prefix + ", but takes the mapping for the given file. "
"Each line in this file is read as one layer mapping expression. Empty lines or lines starting with a hash (#) character are "
"ignored."
"This option specifies the layer selection or mapping like -" + m_prefix + "m, but takes the mapping from the given file. "
"Each line in this file is read as one layer mapping expression. "
"Empty lines or lines starting with a hash (#) character or with double slashes (//) are ignored."
)
;
}

View File

@ -635,6 +635,13 @@ LayerMap::mmap_expr (tl::Extractor &ex, unsigned int l)
{
try {
bool round_bracket = false, square_bracket = false;
if (ex.test ("(")) {
round_bracket = true;
} else if (ex.test ("[")) {
square_bracket = true;
}
do {
tl::Extractor ex_saved = ex;
@ -678,7 +685,15 @@ LayerMap::mmap_expr (tl::Extractor &ex, unsigned int l)
LayerProperties lp;
lp.read (ex, true);
m_target_layers[l] = lp;
}
} else if (square_bracket) {
m_target_layers[l] = LayerProperties (db::any_ld (), db::any_ld ());
}
if (round_bracket) {
ex.expect (")");
} else if (square_bracket) {
ex.expect ("]");
}
} catch (...) {
throw LayerSpecFormatException (ex.skip ());
@ -790,6 +805,13 @@ LayerMap::unmap_expr (tl::Extractor &ex)
{
try {
bool round_bracket = false, square_bracket = false;
if (ex.test ("(")) {
round_bracket = true;
} else if (ex.test ("[")) {
square_bracket = true;
}
do {
tl::Extractor ex_saved = ex;
@ -829,6 +851,12 @@ LayerMap::unmap_expr (tl::Extractor &ex)
lp.read (ex, true);
}
if (round_bracket) {
ex.expect (")");
} else if (square_bracket) {
ex.expect ("]");
}
} catch (...) {
throw LayerSpecFormatException (ex.skip ());
}

View File

@ -74,6 +74,25 @@ TEST(1)
EXPECT_EQ (lm.first_logical (db::LDPair(10, 7)).first, false);
lm.map_expr ("'XP';10/7-8 : XN", 13);
EXPECT_EQ (lm.mapping_str (13), "10/7-8;XP : XN");
// brackets, "add_expr"
lm.clear ();
lm.add_expr ("[1-10/*]", 1);
EXPECT_EQ (lm.mapping_str (1), "1-10/* : */*");
lm.add_expr ("-(5/*)", 0);
EXPECT_EQ (lm.mapping_str (1), "1-4/*;6-10/* : */*");
lm.clear ();
lm.add_expr ("[1/15]", 1);
lm.add_expr ("+(1/5:1001/5)", 1);
// NOTE: the target is taken from the second expression (the last one wins)
EXPECT_EQ (lm.mapping_str (1), "1/5,15 : 1001/5");
lm.clear ();
lm.add_expr ("+(1/5:1001/5)", 1);
lm.add_expr ("[1/15]", 1);
// NOTE: the target is taken from the second expression (the last one wins)
EXPECT_EQ (lm.mapping_str (1), "1/5,15 : */*");
}
TEST(2)

View File

@ -201,5 +201,30 @@
when using unmapping and multi-mapping.
</p>
<h2>Brackets</h2>
<p>
Square brackets can be used to imply mapping to the original layer. When putting square brackets
around a mapping expression, the default target is "*/*", which means expansion to the original layer.
Hence the following statements are identical:
</p>
<pre>[1-10/*]
1-10/* : */*
</pre>
<p>
When combining this with "+" for multi-mapping, put "+" in front of the bracket.
</p>
<p>
You can put round brackets around mapping expressions for visual clarity, specifically when
combining them with "-" (unmapping) or "+" (multi-mapping):
</p>
<pre>-(1-10/*)
+(17/0 : 1017/0)
</pre>
</doc>