mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
More ScriptRule usage
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@996 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -46,6 +46,7 @@ template <> inline ScriptRegexP from_script<ScriptRegexP>(const ScriptValueP& va
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Rules : regex replace
|
// ----------------------------------------------------------------------------- : Rules : regex replace
|
||||||
|
|
||||||
|
/*
|
||||||
class ScriptReplaceRule : public ScriptValue {
|
class ScriptReplaceRule : public ScriptValue {
|
||||||
public:
|
public:
|
||||||
virtual ScriptType type() const { return SCRIPT_FUNCTION; }
|
virtual ScriptType type() const { return SCRIPT_FUNCTION; }
|
||||||
@@ -138,6 +139,89 @@ SCRIPT_FUNCTION(replace_rule) {
|
|||||||
SCRIPT_FUNCTION(replace) {
|
SCRIPT_FUNCTION(replace) {
|
||||||
return replace_rule(ctx)->eval(ctx);
|
return replace_rule(ctx)->eval(ctx);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct RegexReplacer {
|
||||||
|
ScriptRegexP match; ///< Regex to match
|
||||||
|
ScriptRegexP context; ///< Match only in a given context, optional
|
||||||
|
String replacement_string; ///< Replacement
|
||||||
|
ScriptValueP replacement_function; ///< Replacement function instead of a simple string, optional
|
||||||
|
bool recursive; ///< Recurse into the replacement
|
||||||
|
|
||||||
|
String apply(Context& ctx, String& input, int level = 0) const {
|
||||||
|
// match first, then check context of match
|
||||||
|
String ret;
|
||||||
|
while (match->regex.Matches(input)) {
|
||||||
|
// for each match ...
|
||||||
|
size_t start, len;
|
||||||
|
bool ok = match->regex.GetMatch(&start, &len, 0);
|
||||||
|
assert(ok);
|
||||||
|
ret += input.substr(0, start); // everything before the match position stays
|
||||||
|
String inside = input.substr(start, len); // inside the match
|
||||||
|
String next_input = input.substr(start + len); // next loop the input is after this match
|
||||||
|
if (!context || context->regex.Matches(ret + _("<match>") + next_input)) {
|
||||||
|
// the context matches -> perform replacement
|
||||||
|
if (replacement_function) {
|
||||||
|
// set match results in context
|
||||||
|
for (UInt m = 0 ; m < match->regex.GetMatchCount() ; ++m) {
|
||||||
|
match->regex.GetMatch(&start, &len, m);
|
||||||
|
String name = m == 0 ? _("input") : String(_("_")) << m;
|
||||||
|
String value = input.substr(start, len);
|
||||||
|
ctx.setVariable(name, to_script(value));
|
||||||
|
}
|
||||||
|
// call
|
||||||
|
inside = replacement_function->eval(ctx)->toString();
|
||||||
|
} else {
|
||||||
|
match->regex.Replace(&inside, replacement_string, 1); // replace inside
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (recursive && level < 20) {
|
||||||
|
ret += apply(ctx, inside, level + 1);
|
||||||
|
} else {
|
||||||
|
ret += inside;
|
||||||
|
}
|
||||||
|
input = next_input;
|
||||||
|
}
|
||||||
|
ret += input;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SCRIPT_FUNCTION_WITH_SIMPLIFY(replace) {
|
||||||
|
// construct replacer
|
||||||
|
RegexReplacer replacer;
|
||||||
|
replacer.match = from_script<ScriptRegexP>(ctx.getVariable(SCRIPT_VAR_match), SCRIPT_VAR_match);
|
||||||
|
if (ctx.getVariableOpt(SCRIPT_VAR_in_context)) {
|
||||||
|
replacer.context = from_script<ScriptRegexP>(ctx.getVariableOpt(SCRIPT_VAR_in_context), SCRIPT_VAR_in_context);
|
||||||
|
}
|
||||||
|
if (ctx.getVariableOpt(SCRIPT_VAR_recursive)) {
|
||||||
|
replacer.recursive = from_script<bool>(ctx.getVariableOpt(SCRIPT_VAR_recursive), SCRIPT_VAR_recursive);
|
||||||
|
} else {
|
||||||
|
replacer.recursive = false;
|
||||||
|
}
|
||||||
|
replacer.replacement_function = ctx.getVariable(SCRIPT_VAR_replace);
|
||||||
|
if (replacer.replacement_function->type() != SCRIPT_FUNCTION) {
|
||||||
|
replacer.replacement_string = replacer.replacement_function->toString();
|
||||||
|
replacer.replacement_function = ScriptValueP();
|
||||||
|
}
|
||||||
|
// run
|
||||||
|
SCRIPT_PARAM_C(String, input);
|
||||||
|
if (replacer.context || replacer.replacement_function || replacer.recursive) {
|
||||||
|
SCRIPT_RETURN(replacer.apply(ctx, input));
|
||||||
|
} else {
|
||||||
|
// simple replacing
|
||||||
|
replacer.match->regex.Replace(&input, replacer.replacement_string);
|
||||||
|
SCRIPT_RETURN(input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SCRIPT_FUNCTION_SIMPLIFY_CLOSURE(replace) {
|
||||||
|
FOR_EACH(b, closure.bindings) {
|
||||||
|
if (b.first == SCRIPT_VAR_match || b.first == SCRIPT_VAR_in_context) {
|
||||||
|
b.second = regex_from_script(b.second); // pre-compile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ScriptValueP();
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Rules : regex filter
|
// ----------------------------------------------------------------------------- : Rules : regex filter
|
||||||
|
|
||||||
@@ -175,7 +259,7 @@ ScriptValueP filter_rule(Context& ctx) {
|
|||||||
SCRIPT_PARAM_DEFAULT_C(String, in_context, String());
|
SCRIPT_PARAM_DEFAULT_C(String, in_context, String());
|
||||||
|
|
||||||
// cache
|
// cache
|
||||||
/*
|
//*
|
||||||
const int CACHE_SIZE = 6;
|
const int CACHE_SIZE = 6;
|
||||||
struct CacheItem{
|
struct CacheItem{
|
||||||
String match, in_context;
|
String match, in_context;
|
||||||
@@ -367,7 +451,7 @@ void init_script_regex_functions(Context& ctx) {
|
|||||||
ctx.setVariable(_("filter text"), script_filter_text);
|
ctx.setVariable(_("filter text"), script_filter_text);
|
||||||
ctx.setVariable(_("break text"), script_break_text);
|
ctx.setVariable(_("break text"), script_break_text);
|
||||||
ctx.setVariable(_("match"), script_match);
|
ctx.setVariable(_("match"), script_match);
|
||||||
ctx.setVariable(_("replace rule"), script_replace_rule);
|
ctx.setVariable(_("replace rule"), new_intrusive1<ScriptRule>(script_replace));
|
||||||
ctx.setVariable(_("filter rule"), script_filter_rule);
|
ctx.setVariable(_("filter rule"), script_filter_rule);
|
||||||
ctx.setVariable(_("break rule"), new_intrusive1<ScriptRule>(script_break_text));
|
ctx.setVariable(_("break rule"), new_intrusive1<ScriptRule>(script_break_text));
|
||||||
ctx.setVariable(_("match rule"), new_intrusive1<ScriptRule>(script_match));
|
ctx.setVariable(_("match rule"), new_intrusive1<ScriptRule>(script_match));
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ void init_script_variables() {
|
|||||||
Var(match);
|
Var(match);
|
||||||
Var(replace);
|
Var(replace);
|
||||||
VarN(in_context,_("in context"));
|
VarN(in_context,_("in context"));
|
||||||
|
Var(recursive);
|
||||||
Var(order);
|
Var(order);
|
||||||
Var(filter);
|
Var(filter);
|
||||||
Var(choice);
|
Var(choice);
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ enum Variable
|
|||||||
, SCRIPT_VAR_match
|
, SCRIPT_VAR_match
|
||||||
, SCRIPT_VAR_replace
|
, SCRIPT_VAR_replace
|
||||||
, SCRIPT_VAR_in_context
|
, SCRIPT_VAR_in_context
|
||||||
|
, SCRIPT_VAR_recursive
|
||||||
, SCRIPT_VAR_order
|
, SCRIPT_VAR_order
|
||||||
, SCRIPT_VAR_filter
|
, SCRIPT_VAR_filter
|
||||||
, SCRIPT_VAR_choice
|
, SCRIPT_VAR_choice
|
||||||
|
|||||||
Reference in New Issue
Block a user