Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
magicseteditor
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
MyCard
magicseteditor
Commits
725b5273
Commit
725b5273
authored
Aug 07, 2008
by
twanvl
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Lower case keywords are now recognized, but only if all parameters are given.
parent
b0534242
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
100 additions
and
40 deletions
+100
-40
data/magic.mse-game/script
data/magic.mse-game/script
+7
-4
data/magic.mse-game/set_fields
data/magic.mse-game/set_fields
+1
-0
src/data/keyword.cpp
src/data/keyword.cpp
+78
-28
src/data/keyword.hpp
src/data/keyword.hpp
+2
-2
src/script/functions/basic.cpp
src/script/functions/basic.cpp
+12
-6
No files found.
data/magic.mse-game/script
View file @
725b5273
...
...
@@ -311,9 +311,7 @@ mana_context :=
| <param-cost><match>, # keyword argument that is declared as cost
";
# truncates the name of legends
legend_filter := replace@(match:", [A-Z,a-z,Æ,0-9,' ]*", replace: "" )+
replace@(match:" of [A-Z,a-z,Æ,0-9,' ]*", replace: "" )+
replace@(match:" the [A-Z,a-z,Æ,0-9,' ]*", replace: "" )
legend_filter := replace@(match:"(, | of | the ).*", replace: "" )
# the rule text filter
# - adds mana symbols
# - makes text in parentheses italic
...
...
@@ -323,7 +321,12 @@ text_filter :=
remove_tag@(tag: "<i-auto>") +
# step 2 : reminder text for keywords
expand_keywords@(
default_expand: { chosen(choice:mode, set.automatic_reminder_text) },
condition: {
correct_case or (mode != "pseudo" and not used_placeholders)
}
default_expand: {
chosen(choice:if correct_case then mode else "lower case", set.automatic_reminder_text)
},
combine: {
if mode == "pseudo" then "<i-auto>{keyword}</i-auto>"
else "{keyword}<atom-reminder-{mode}> ({process_english_hints(reminder)})</atom-reminder-{mode}>" }
...
...
data/magic.mse-game/set_fields
View file @
725b5273
...
...
@@ -50,6 +50,7 @@ set field:
choice: pseudo
choice: action
choice: custom
choice: lower case
initial: old, core, expert, pseudo, action, custom
# Convert from older mse versions
script:
...
...
src/data/keyword.cpp
View file @
725b5273
...
...
@@ -21,6 +21,8 @@ DECLARE_POINTER_TYPE(KeywordParamValue);
class
Value
;
DECLARE_DYNAMIC_ARG
(
Value
*
,
value_being_updated
);
#define USE_CASE_INSENSITIVE_KEYWORDS 1
// ----------------------------------------------------------------------------- : Reflection
KeywordParam
::
KeywordParam
()
...
...
@@ -215,7 +217,12 @@ void Keyword::prepare(const vector<KeywordParamP>& param_types, bool force) {
}
regex
+=
_
(
"("
)
+
regex_escape
(
text
)
+
_
(
")"
);
regex
=
_
(
"
\\
y"
)
+
regex
+
_
(
"(?=$|[^a-zA-Z0-9
\\
(])"
);
// only match whole words
if
(
match_re
.
Compile
(
regex
,
wxRE_ADVANCED
))
{
#if USE_CASE_INSENSITIVE_KEYWORDS
int
flags
=
wxRE_ADVANCED
|
wxRE_ICASE
;
// case insensitive matching
#else
int
flags
=
wxRE_ADVANCED
#endif
if
(
match_re
.
Compile
(
regex
,
flags
))
{
// not valid if it matches "", that would make MSE hang
valid
=
!
match_re
.
Matches
(
_
(
""
));
}
else
{
...
...
@@ -262,6 +269,9 @@ KeywordTrie::~KeywordTrie() {
}
KeywordTrie
*
KeywordTrie
::
insert
(
Char
c
)
{
#if USE_CASE_INSENSITIVE_KEYWORDS
c
=
toLower
(
c
);
// case insensitive matching
#endif
KeywordTrie
*&
child
=
children
[
c
];
if
(
!
child
)
child
=
new
KeywordTrie
;
return
child
;
...
...
@@ -391,9 +401,9 @@ void dump(int i, KeywordTrie* t) {
#endif
String
KeywordDatabase
::
expand
(
const
String
&
text
,
const
ScriptValueP
&
match_condition
,
const
ScriptValueP
&
expand_default
,
const
ScriptValueP
&
combine_script
,
bool
case_sensitive
,
Context
&
ctx
)
const
{
assert
(
combine_script
);
...
...
@@ -451,6 +461,9 @@ String KeywordDatabase::expand(const String& text,
}
continue
;
}
else
{
#if USE_CASE_INSENSITIVE_KEYWORDS
c
=
toLower
(
c
);
// case insensitive matching
#endif
++
i
;
}
// find 'next' trie node set matching c
...
...
@@ -478,12 +491,10 @@ String KeywordDatabase::expand(const String& text,
if
(
used
.
insert
(
kw
).
second
)
{
// we have found a possible match, for a keyword which we have not seen before
if
(
tryExpand
(
*
kw
,
i
,
tagged
,
untagged
,
result
,
expand_type
,
expand_default
,
combine_script
,
case_sensitive
,
ctx
,
match_condition
,
expand_default
,
combine_script
,
ctx
,
stat
,
stat_key
))
{
// it matches
used
.
clear
();
expand_type
=
_
(
'a'
);
goto
matched_keyword
;
}
}
...
...
@@ -506,9 +517,9 @@ bool KeywordDatabase::tryExpand(const Keyword& kw,
String
&
untagged
,
String
&
result
,
char
expand_type
,
const
ScriptValueP
&
match_condition
,
const
ScriptValueP
&
expand_default
,
const
ScriptValueP
&
combine_script
,
bool
case_sensitive
,
Context
&
ctx
,
KeywordUsageStatistics
*
stat
,
Value
*
stat_key
)
const
...
...
@@ -523,9 +534,6 @@ bool KeywordDatabase::tryExpand(const Keyword& kw,
end
=
untagged_to_index
(
tagged
,
start_u
+
len_u
,
true
);
if
(
start
==
end
)
return
false
;
// don't match empty keywords
// copy text before keyword
result
+=
remove_tag
(
tagged
.
substr
(
0
,
start
),
_
(
"<kw-"
));
// a part of tagged has not been searched for <kw- tags
// this can happen when the trie incorrectly matches too early
for
(
size_t
j
=
expand_type_known_upto
+
1
;
j
<
start
;)
{
...
...
@@ -542,35 +550,45 @@ bool KeywordDatabase::tryExpand(const Keyword& kw,
}
}
// To determine if the case matches exactly we compare plain text parts with the original match string
size_t
pos_in_match_string
=
0
;
bool
correct_case
=
true
;
// also check if there are missing parameters
bool
used_placeholders
=
false
;
// Split the keyword, set parameters in context
// The even captures are parameter values, the odd ones are the plain text in between
String
total
;
// the total keyword
size_t
match_count
=
kw
.
match_re
.
GetMatchCount
();
assert
(
match_count
-
1
==
1
+
2
*
kw
.
parameters
.
size
());
size_t
part_start
=
start
;
for
(
size_t
j
=
1
;
j
<
match_count
;
++
j
)
{
// we start counting at 1, so
// j = 1 mod 2 -> text
// j = 0 mod 2 -> parameter #((j-1)/2) == (j/2-1)
size_t
start_u
,
len_u
;
kw
.
match_re
.
GetMatch
(
&
start_u
,
&
len_u
,
j
);
// note: start_u can be (uint)-1 when len_u == 0
size_t
part_end
=
len_u
>
0
?
untagged_to_index
(
tagged
,
start_u
+
len_u
,
true
)
:
start
;
String
part
=
tagged
.
substr
(
start
,
part_end
-
start
);
size_t
part_start_u
,
part_
len_u
;
kw
.
match_re
.
GetMatch
(
&
part_start_u
,
&
part_
len_u
,
j
);
// note: start_u can be (uint)-1 when
part_
len_u == 0
size_t
part_end
=
part_len_u
>
0
?
untagged_to_index
(
tagged
,
part_start_u
+
part_len_u
,
true
)
:
part_
start
;
String
part
=
tagged
.
substr
(
part_start
,
part_end
-
part_
start
);
// strip left over </kw tags
part
=
remove_tag
(
part
,
_
(
"</kw-"
));
if
((
j
%
2
)
==
0
)
{
// parameter
KeywordParam
&
kwp
=
*
kw
.
parameters
[
j
/
2
-
1
];
String
param
=
untagged
.
substr
(
start_u
,
len_u
);
// untagged version
String
param
=
untagged
.
substr
(
part_start_u
,
part_
len_u
);
// untagged version
// strip separator_before
String
separator_before
,
separator_after
;
if
(
kwp
.
separator_before_re
.
IsValid
()
&&
kwp
.
separator_before_re
.
Matches
(
param
))
{
size_t
s
_start
,
s
_len
;
// start should be 0
kwp
.
separator_before_re
.
GetMatch
(
&
s
_start
,
&
s
_len
);
separator_before
=
param
.
substr
(
0
,
s
_start
+
s
_len
);
param
=
param
.
substr
(
s
_start
+
s
_len
);
size_t
s
ep_start
,
sep
_len
;
// start should be 0
kwp
.
separator_before_re
.
GetMatch
(
&
s
ep_start
,
&
sep
_len
);
separator_before
=
param
.
substr
(
0
,
s
ep_start
+
sep
_len
);
param
=
param
.
substr
(
s
ep_start
+
sep
_len
);
// strip from tagged version
size_t
end_t
=
untagged_to_index
(
part
,
s_start
+
s
_len
,
false
);
part
=
get_tags
(
part
,
0
,
end_t
,
true
,
true
)
+
part
.
substr
(
end_t
);
size_t
sep_end_t
=
untagged_to_index
(
part
,
sep_start
+
sep
_len
,
false
);
part
=
get_tags
(
part
,
0
,
sep_end_t
,
true
,
true
)
+
part
.
substr
(
sep_
end_t
);
// transform?
if
(
kwp
.
separator_script
)
{
ctx
.
setVariable
(
_
(
"input"
),
to_script
(
separator_before
));
...
...
@@ -579,13 +597,13 @@ bool KeywordDatabase::tryExpand(const Keyword& kw,
}
// strip separator_after
if
(
kwp
.
separator_after_re
.
IsValid
()
&&
kwp
.
separator_after_re
.
Matches
(
param
))
{
size_t
s
_start
,
s
_len
;
// start + len should be param.size()
kwp
.
separator_after_re
.
GetMatch
(
&
s
_start
,
&
s
_len
);
separator_after
=
param
.
substr
(
s_start
);
param
=
param
.
substr
(
0
,
s_start
);
size_t
s
ep_start
,
sep
_len
;
// start + len should be param.size()
kwp
.
separator_after_re
.
GetMatch
(
&
s
ep_start
,
&
sep
_len
);
separator_after
=
param
.
substr
(
s
ep
_start
);
param
=
param
.
substr
(
0
,
s
ep
_start
);
// strip from tagged version
size_t
s
tart_t
=
untagged_to_index
(
part
,
s
_start
,
false
);
part
=
part
.
substr
(
0
,
s
tart_t
)
+
get_tags
(
part
,
start_t
,
part
.
size
(),
true
,
true
);
size_t
s
ep_start_t
=
untagged_to_index
(
part
,
sep
_start
,
false
);
part
=
part
.
substr
(
0
,
s
ep_start_t
)
+
get_tags
(
part
,
sep_
start_t
,
part
.
size
(),
true
,
true
);
// transform?
if
(
kwp
.
separator_script
)
{
ctx
.
setVariable
(
_
(
"input"
),
to_script
(
separator_after
));
...
...
@@ -598,6 +616,7 @@ bool KeywordDatabase::tryExpand(const Keyword& kw,
// process param
if
(
param
.
empty
())
{
// placeholder
used_placeholders
=
true
;
script_param
->
value
=
_
(
"<atom-kwpph>"
)
+
(
kwp
.
placeholder
.
empty
()
?
kwp
.
name
:
kwp
.
placeholder
)
+
_
(
"</atom-kwpph>"
);
script_part
->
value
=
part
+
script_param
->
value
;
// keep tags
}
else
{
...
...
@@ -613,11 +632,39 @@ bool KeywordDatabase::tryExpand(const Keyword& kw,
}
part
=
separator_before
+
script_part
->
toString
()
+
separator_after
;
ctx
.
setVariable
(
String
(
_
(
"param"
))
<<
(
int
)(
j
/
2
),
script_param
);
}
else
if
(
correct_case
)
{
// Plain text, check if the case matches
for
(
size_t
i
=
part_start_u
;
i
<
part_start_u
+
part_len_u
;
++
i
,
++
pos_in_match_string
)
{
if
(
pos_in_match_string
>
kw
.
match
.
size
())
{
// outside match string, shouldn't happen, strings should be the same length
correct_case
=
false
;
break
;
}
Char
actual_char
=
untagged
.
GetChar
(
i
);
Char
match_char
=
kw
.
match
.
GetChar
(
pos_in_match_string
);
if
(
actual_char
!=
match_char
)
{
correct_case
=
false
;
break
;
}
}
// we should have arrived at a param tag, skip it
if
(
pos_in_match_string
<
kw
.
match
.
size
()
&&
is_substr
(
kw
.
match
,
pos_in_match_string
,
_
(
"<atom-param"
)))
{
pos_in_match_string
=
match_close_tag_end
(
kw
.
match
,
pos_in_match_string
);
}
}
total
+=
part
;
start
=
part_end
;
part_
start
=
part_end
;
}
ctx
.
setVariable
(
_
(
"mode"
),
to_script
(
kw
.
mode
));
ctx
.
setVariable
(
_
(
"correct case"
),
to_script
(
correct_case
));
ctx
.
setVariable
(
_
(
"used placeholders"
),
to_script
(
used_placeholders
));
// Final check whether the keyword matches
if
(
match_condition
&&
(
bool
)
*
match_condition
->
eval
(
ctx
)
==
false
)
{
return
false
;
}
// Show reminder text?
bool
expand
=
expand_type
==
_
(
'1'
);
...
...
@@ -627,6 +674,9 @@ bool KeywordDatabase::tryExpand(const Keyword& kw,
expand_type
=
expand
?
_
(
'A'
)
:
_
(
'a'
);
}
// Copy text before keyword
result
+=
remove_tag
(
tagged
.
substr
(
0
,
start
),
_
(
"<kw-"
));
// Combine keyword & reminder with result
if
(
expand
)
{
String
reminder
;
...
...
src/data/keyword.hpp
View file @
725b5273
...
...
@@ -155,7 +155,7 @@ class KeywordDatabase {
* @param case_sensitive case sensitive matching of keywords?
* @param ctx context for evaluation of scripts
*/
String
expand
(
const
String
&
text
,
const
ScriptValueP
&
expand_default
,
const
ScriptValueP
&
combine_script
,
bool
case_sensitive
,
Context
&
ctx
)
const
;
String
expand
(
const
String
&
text
,
const
ScriptValueP
&
match_condition
,
const
ScriptValueP
&
expand_default
,
const
ScriptValueP
&
combine_script
,
Context
&
ctx
)
const
;
private:
KeywordTrie
*
root
;
///< Data structure for finding keywords
...
...
@@ -167,7 +167,7 @@ class KeywordDatabase {
* - return true
*/
bool
tryExpand
(
const
Keyword
&
kw
,
size_t
pos
,
String
&
tagged
,
String
&
untagged
,
String
&
out
,
char
expand_type
,
const
ScriptValueP
&
expand_default
,
const
ScriptValueP
&
combine_script
,
bool
case_sensitive
,
Context
&
ctx
,
const
ScriptValueP
&
match_condition
,
const
ScriptValueP
&
expand_default
,
const
ScriptValueP
&
combine_script
,
Context
&
ctx
,
KeywordUsageStatistics
*
stat
,
Value
*
stat_key
)
const
;
};
...
...
src/script/functions/basic.cpp
View file @
725b5273
...
...
@@ -539,10 +539,12 @@ SCRIPT_FUNCTION(random_select) {
// ----------------------------------------------------------------------------- : Keywords
SCRIPT_RULE_2_N_DEP
(
expand_keywords
,
ScriptValueP
,
_
(
"default expand"
),
default_expand
,
ScriptValueP
,
_
(
"combine"
),
combine
)
{
SCRIPT_FUNCTION_WITH_DEP
(
expand_keywords
)
{
SCRIPT_PARAM_C
(
String
,
input
);
SCRIPT_PARAM_C
(
Set
*
,
set
);
SCRIPT_PARAM_N
(
ScriptValueP
,
_
(
"condition"
),
match_condition
);
SCRIPT_PARAM_N
(
ScriptValueP
,
_
(
"default expand"
),
default_expand
);
SCRIPT_PARAM_N
(
ScriptValueP
,
_
(
"combine"
),
combine
);
KeywordDatabase
&
db
=
set
->
keyword_db
;
if
(
db
.
empty
())
{
db
.
prepare_parameters
(
set
->
game
->
keyword_parameter_types
,
set
->
keywords
);
...
...
@@ -553,15 +555,19 @@ SCRIPT_RULE_2_N_DEP(expand_keywords, ScriptValueP, _("default expand"), default_
SCRIPT_OPTIONAL_PARAM_C_
(
CardP
,
card
);
WITH_DYNAMIC_ARG
(
keyword_usage_statistics
,
card
?
&
card
->
keyword_usage
:
nullptr
);
try
{
SCRIPT_RETURN
(
db
.
expand
(
input
,
default_expand
,
combine
,
tru
e
,
ctx
));
SCRIPT_RETURN
(
db
.
expand
(
input
,
match_condition
,
default_expand
,
combin
e
,
ctx
));
}
catch
(
const
Error
&
e
)
{
throw
ScriptError
(
_ERROR_2_
(
"in function"
,
e
.
what
(),
_
(
"expand_keywords"
)));
}
}
SCRIPT_RULE_2_DEPENDENCIES
(
expand_keywords
)
{
default_expand
->
dependencies
(
ctx
,
dep
);
combine
->
dependencies
(
ctx
,
dep
);
SCRIPT_FUNCTION_DEPENDENCIES
(
expand_keywords
)
{
SCRIPT_PARAM_C
(
Set
*
,
set
);
SCRIPT_PARAM_N
(
ScriptValueP
,
_
(
"condition"
),
match_condition
);
SCRIPT_PARAM_N
(
ScriptValueP
,
_
(
"default expand"
),
default_expand
);
SCRIPT_PARAM_N
(
ScriptValueP
,
_
(
"combine"
),
combine
);
match_condition
->
dependencies
(
ctx
,
dep
);
default_expand
->
dependencies
(
ctx
,
dep
);
combine
->
dependencies
(
ctx
,
dep
);
set
->
game
->
dependent_scripts_keywords
.
add
(
dep
);
// this depends on the set's keywords
return
ctx
.
getVariable
(
SCRIPT_VAR_input
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment