Commit 0c3250cf authored by twanvl's avatar twanvl

Now all regex functions use ScriptRule.

The *_rule functions can now be considered deprecated
Documented this by removing mentions of the rule functions, except for a mention of backwards compatibility.
parent 7346a364
...@@ -2,20 +2,21 @@ Function: break_text ...@@ -2,20 +2,21 @@ Function: break_text
--Usage-- --Usage--
> break_text(some_string, match: regular expression, in_context: regular expression) > break_text(some_string, match: regular expression, in_context: regular expression)
> break_rule(match: ..., in_context: ...)(some_string)
Break text by only keeping the parts of the input that match the regular expression. Break text by only keeping the parts of the input that match the regular expression.
The function returns a [[type:list]] of parts. The function returns a [[type:list]] of parts.
If @in_context@ is given, the context must also match the string where the match is represented as <tt>&lt;match></tt>. If @in_context@ is given, the context must also match the string where the match is represented as <tt>&lt;match></tt>.
This function is available in [[script:rule form]]. When the @break_text@ is used many times with the same @match@ or @in_context@ values it is more efficient to declare these as default arguments:
When the @break_text@ is used many times the rule form is more efficient, because the regular expression is only compiled once. > my_break := break_text@(match: "something")
> my_break("input") # called many times
This way the regular expression is only compiled once.
--Filter vs. break-- --Filter vs. break--
The function @filter_text@ is very similar to @break_text@, instead of returning a list it concatenates the items. The function @filter_text@ is very similar to @break_text@, instead of returning a list it concatenates the items.
So for example where @break_text@ would return @["a","b","c"]@, @filter_text@ would return @"abc"@. So for example where @break_text@ returns @["a","b","c"]@, @filter_text@ would return @"abc"@.
In fact, @filter_text@ could be implemented as In fact, @filter_text@ could be implemented as
> filter_text := { for part in break_text() do part } > filter_text := { for part in break_text() do part }
...@@ -32,10 +33,9 @@ In fact, @filter_text@ could be implemented as ...@@ -32,10 +33,9 @@ In fact, @filter_text@ could be implemented as
> break_text(match: "/", "a/b/c") == ["/","/"] > break_text(match: "/", "a/b/c") == ["/","/"]
> break_text(match: "[^/]+", "a/b/c") == ["a","b","c"] > break_text(match: "[^/]+", "a/b/c") == ["a","b","c"]
> >
> f := break_rule(match: "xx+") > f := break_text@(match: "xx+")
> f("xyzxxxxyyzz") == ["xxxx"] > f("xyzxxxxyyzz") == ["xxxx"]
--See also-- --See also--
| [[fun:filter_text|filter_text / filter_rule]] | [[fun:filter_text]] Keep only the text matching a regular expression.
Keep only the text matching a regular expression.
...@@ -15,5 +15,5 @@ Does one string contain another at any position? ...@@ -15,5 +15,5 @@ Does one string contain another at any position?
> contains("abcdefg", match:"abd") == false > contains("abcdefg", match:"abd") == false
--See also-- --See also--
| [[fun:match|match / match_rule]] Does a string match a regular expression? | [[fun:match]] Does a string match a regular expression?
| [[fun:chosen]] Is the given choice selected in a multiple choice value? | [[fun:chosen]] Is the given choice selected in a multiple choice value?
...@@ -2,7 +2,6 @@ Function: expand_keywords ...@@ -2,7 +2,6 @@ Function: expand_keywords
--Usage-- --Usage--
> expand_keywords(some_tagged_string, default_expand: {...}, combine: {...}) > expand_keywords(some_tagged_string, default_expand: {...}, combine: {...})
> expand_keywords_rule(default_expand: {...}, combine: {...})(some_tagged_string)
Find [[type:keyword]]s and generate their reminder text. Find [[type:keyword]]s and generate their reminder text.
...@@ -28,8 +27,6 @@ For example, in the case of magic: ...@@ -28,8 +27,6 @@ For example, in the case of magic:
> ) > )
is used. This shows reminder text by default based on a [[type:set]] option, and it combined the keyword as @"keyword (reminder)"@. is used. This shows reminder text by default based on a [[type:set]] option, and it combined the keyword as @"keyword (reminder)"@.
This function is available in [[script:rule form]].
--Parameters-- --Parameters--
! Parameter Type Description ! Parameter Type Description
| @input@ [[type:tagged string]] String to expand keywords in. | @input@ [[type:tagged string]] String to expand keywords in.
...@@ -41,5 +38,5 @@ Assuming a keyword @"mse"@ exists with reminder text @"Magic Set Editor"@ exists ...@@ -41,5 +38,5 @@ Assuming a keyword @"mse"@ exists with reminder text @"Magic Set Editor"@ exists
> expand_keywords(default_expand: {true}, combine: { keyword + " = " + reminder }, "mse is cool") > expand_keywords(default_expand: {true}, combine: { keyword + " = " + reminder }, "mse is cool")
> == "<kw-A>mse = Magic Set Editor is cool</kw-A>" > == "<kw-A>mse = Magic Set Editor is cool</kw-A>"
> >
> f := expand_keywords_rule(default_expand: {true}, combine: { keyword+"="+reminder }) > f := expand_keywords@(default_expand: {true}, combine: { keyword+"="+reminder })
> f("mse is cool") == "<kw-A>mse = Magic Set Editor is cool</kw-A>" > f("mse is cool") == "<kw-A>mse = Magic Set Editor is cool</kw-A>"
...@@ -2,14 +2,15 @@ Function: filter_text ...@@ -2,14 +2,15 @@ Function: filter_text
--Usage-- --Usage--
> filter_text(some_string, match: regular expression, in_context: regular expression) > filter_text(some_string, match: regular expression, in_context: regular expression)
> filter_rule(match: ..., in_context: ...)(some_string)
Filter text by only keeping the parts of the input that match the regular expression. Filter text by only keeping the parts of the input that match the regular expression.
If @in_context@ is given, the context must also match the string where the match is represented as <tt>&lt;match></tt>. If @in_context@ is given, the context must also match the string where the match is represented as <tt>&lt;match></tt>.
This function is available in [[script:rule form]]. When the @filter_text@ is used many times with the same @match@ or @in_context@ values it is more efficient to declare these as default arguments:
When the @filter_text@ is used many times the rule form is more efficient, because the regular expression is only compiled once. > my_filter := filter_text@(match: "something")
> my_filter("input") # called many times
This way the regular expression is only compiled once.
--Parameters-- --Parameters--
! Parameter Type Description ! Parameter Type Description
...@@ -22,11 +23,9 @@ When the @filter_text@ is used many times the rule form is more efficient, becau ...@@ -22,11 +23,9 @@ When the @filter_text@ is used many times the rule form is more efficient, becau
> filter_text(match: ".", in_context:"a<match>", "banana") == "nn" > filter_text(match: ".", in_context:"a<match>", "banana") == "nn"
> filter_text(match: "[xy]", "xyz") == "xy" > filter_text(match: "[xy]", "xyz") == "xy"
> >
> f := filter_rule(match: "xx+") > f := filter_text@(match: "xx+")
> f("xyzxxyyzz") == "xx" > f("xyzxxyyzz") == "xx"
--See also-- --See also--
| [[fun:break_text|break_text / break_rule]] | [[fun:break_text]] Break text into parts each matching a regular expression.
Break text into parts each matching a regular expression. | [[fun:replace]] Replace text matching a regular expression.
| [[fun:replace|replace / replace_rule]]
Replace text matching a regular expression.
...@@ -2,12 +2,9 @@ Function: format ...@@ -2,12 +2,9 @@ Function: format
--Usage-- --Usage--
> format(some_number, format: format_specification) > format(some_number, format: format_specification)
> format_rule(format: format_specification)(some_number)
Format a number or other string as a string, [[http://www.cplusplus.com/reference/clibrary/cstdio/printf.html|printf]] style. Format a number or other string as a string, [[http://www.cplusplus.com/reference/clibrary/cstdio/printf.html|printf]] style.
This function is available in [[script:rule form]].
--Parameters-- --Parameters--
! Parameter Type Description ! Parameter Type Description
| @input@ [[type:int]] or [[type:double]] or [[type:string]] | @input@ [[type:int]] or [[type:double]] or [[type:string]]
...@@ -19,5 +16,5 @@ This function is available in [[script:rule form]]. ...@@ -19,5 +16,5 @@ This function is available in [[script:rule form]].
> format(format: "%03d", 13) == "013" > format(format: "%03d", 13) == "013"
> format(format: "%3s", "xy") == " xy" > format(format: "%3s", "xy") == " xy"
> >
> f := format_rule(format: "%03d") > f := format@(format: "%03d")
> f(1) == "001" > f(1) == "001"
...@@ -9,27 +9,19 @@ These functions are built into the program, other [[type:function]]s can be defi ...@@ -9,27 +9,19 @@ These functions are built into the program, other [[type:function]]s can be defi
| [[fun:reverse]] Reverse a string, @"aBc" -> "cBa"@. | [[fun:reverse]] Reverse a string, @"aBc" -> "cBa"@.
| [[fun:trim]] Remove leading and trailing whitespace from a string, @" abc " -> "abc"@. | [[fun:trim]] Remove leading and trailing whitespace from a string, @" abc " -> "abc"@.
| [[fun:substring]] Extract a part of a string. | [[fun:substring]] Extract a part of a string.
| [[fun:format|format / format_rule]] | [[fun:format]] Format a number as a string (printf).
Format a number as a string (printf).
| [[fun:curly_quotes]] Make quotes curly. | [[fun:curly_quotes]] Make quotes curly.
| [[fun:replace|replace / replace_rule]] | [[fun:replace]] Replace text matching a regular expression.
Replace text matching a regular expression. | [[fun:filter_text]] Keep only the text matching a regular expression.
| [[fun:filter_text|filter_text / filter_rule]] | [[fun:break_text]] Break text into parts each matching a regular expression.
Keep only the text matching a regular expression. | [[fun:sort_text]] Sort the letters in a string using a custom order.
| [[fun:break_text|break_text / break_rule]]
Break text into parts each matching a regular expression.
| [[fun:sort_text|sort_text / sort_rule]]
Sort the letters in a string using a custom order.
| [[fun:contains]] Does a string contain another one? | [[fun:contains]] Does a string contain another one?
| [[fun:match|match / match_rule]] | [[fun:match]] Does a string match a regular expression?
Does a string match a regular expression?
| [[fun:regex_escape]] Escape a string for use in a regular expression. | [[fun:regex_escape]] Escape a string for use in a regular expression.
! [[type:tagged_string|Tags]] <<< ! [[type:tagged_string|Tags]] <<<
| [[fun:tag_contents|tag_contents / tag_contents_rule]] | [[fun:tag_contents]] Change the contents of a specific tag.
Change the contents of a specific tag. | [[fun:remove_tag]] Remove a tag, keep the contents.
| [[fun:remove_tag|remove_tag / tag_remove_rule]]
Remove a tag, keep the contents.
| [[fun:remove_tags]] Remove all tags from tagged text. | [[fun:remove_tags]] Remove all tags from tagged text.
! [[type:list|Lists]] <<< ! [[type:list|Lists]] <<<
...@@ -40,8 +32,7 @@ These functions are built into the program, other [[type:function]]s can be defi ...@@ -40,8 +32,7 @@ These functions are built into the program, other [[type:function]]s can be defi
| [[fun:filter_list]] Filter a list, keeping only elements that match a predicate. | [[fun:filter_list]] Filter a list, keeping only elements that match a predicate.
! Keywords <<< ! Keywords <<<
| [[fun:expand_keywords|expand_keywords / expand_keywords_rule]] | [[fun:expand_keywords]] Expand the keywords in a piece of text.
Expand the keywords in a piece of text.
| [[fun:keyword_usage]] What keywords are used on a card, and how often are they used? | [[fun:keyword_usage]] What keywords are used on a card, and how often are they used?
! English language <<< ! English language <<<
......
...@@ -2,12 +2,13 @@ Function: match ...@@ -2,12 +2,13 @@ Function: match
--Usage-- --Usage--
> match(some_string, match: regular expression) > match(some_string, match: regular expression)
> match_rule(match:regular expression)(some_string)
Does a string match the given [[type:regex|regular expression]]? Does a string match the given [[type:regex|regular expression]]?
This function is available in [[script:rule form]]. When the match is performed many times with the same regular expression it is more efficient to declare that as a default argument:
When the match is performed many times the rule form is more efficient, because the regular expression is only compiled once. > my_match := match@(match: "something")
> my_match("input") # called many times
This way the regular expression is only compiled once.
--Parameters-- --Parameters--
! Parameter Type Description ! Parameter Type Description
...@@ -20,7 +21,7 @@ When the match is performed many times the rule form is more efficient, because ...@@ -20,7 +21,7 @@ When the match is performed many times the rule form is more efficient, because
> match("abc", match:"b+") == true > match("abc", match:"b+") == true
> match("abc", match:"$b+^") == false > match("abc", match:"$b+^") == false
> >
> f := match_rule(match: "a+|b+") > f := match@(match: "a+|b+")
> f("xyz") == false > f("xyz") == false
> f("aabb") == true > f("aabb") == true
......
...@@ -2,14 +2,11 @@ Function: remove_tag ...@@ -2,14 +2,11 @@ Function: remove_tag
--Usage-- --Usage--
> remove_tag(tag: some_tag, some_string) > remove_tag(tag: some_tag, some_string)
> tag_remove_rule(tag: some_tag)(some_string)
Remove a tag and its matching close tag from a [[type:tagged string]], but keep the contents. Remove a tag and its matching close tag from a [[type:tagged string]], but keep the contents.
The tag can be a whole tag, @"<tag>"@, or a prefix @"<i"@. In the latter case all tags starting with @"<i"@ are removed. The tag can be a whole tag, @"<tag>"@, or a prefix @"<i"@. In the latter case all tags starting with @"<i"@ are removed.
This function is available in [[script:rule form]].
--Parameters-- --Parameters--
! Parameter Type Description ! Parameter Type Description
| @tag@ [[type:string]] Tag to remove | @tag@ [[type:string]] Tag to remove
...@@ -19,10 +16,10 @@ This function is available in [[script:rule form]]. ...@@ -19,10 +16,10 @@ This function is available in [[script:rule form]].
> remove_tag(tag: "<b>", "<b>bold <i>text</i></b>") == "bold <i>text</i>" > remove_tag(tag: "<b>", "<b>bold <i>text</i></b>") == "bold <i>text</i>"
> remove_tag(tag: "<b", "<b-auto>bold</b-auto> text") == "bold text" > remove_tag(tag: "<b", "<b-auto>bold</b-auto> text") == "bold text"
> >
> f := tag_remove_rule(tag: "<i-auto>") > f := remove_tag@(tag: "<i-auto>")
> f("text, <i-auto>reminder</i-auto> <i>italic</i>") == "text, reminder <i>italic</i>" > f("text, <i-auto>reminder</i-auto> <i>italic</i>") == "text, reminder <i>italic</i>"
--See also-- --See also--
| [[fun:tag_contents|tag_contents / tag_contents_rule]] | [[fun:tag_contents]] Change the contents of a specific tag.
Change the contents of a specific tag. | [[fun:remove_tags]] Remove all tags from tagged text.
| [[fun:to_text]] Remove all tags from tagged text. | [[fun:to_text]] Remove all tags from tagged text, and convert it to a [[type:string]].
...@@ -17,5 +17,4 @@ This function differs from [[fun:to_text]], that function also un-escapes &lt; c ...@@ -17,5 +17,4 @@ This function differs from [[fun:to_text]], that function also un-escapes &lt; c
--See also-- --See also--
| [[fun:to_text]] Remove all tags from tagged text, and convert it to a [[type:string]]. | [[fun:to_text]] Remove all tags from tagged text, and convert it to a [[type:string]].
| [[fun:remove_tag|remove_tag / tag_remove_rule]] | [[fun:remove_tag]] Remove a single tag type.
Remove a single tag type.
...@@ -2,7 +2,6 @@ Function: replace ...@@ -2,7 +2,6 @@ Function: replace
--Usage-- --Usage--
> replace(some_string, match: regular expression, replace: replacement, in_context: regular expression) > replace(some_string, match: regular expression, replace: replacement, in_context: regular expression)
> replace_rule(match: ..., replace: ..., in_context: ...)(some_string)
Replace all matches of a regular expression with a replacement value. Replace all matches of a regular expression with a replacement value.
The replacement can either be a string or a function. The replacement can either be a string or a function.
...@@ -11,8 +10,10 @@ The replacement can either be a string or a function. ...@@ -11,8 +10,10 @@ The replacement can either be a string or a function.
Optionally a context can be given. The replacement is only performed if the string where the match is represented as <tt>&lt;match></tt> also matches the context. Optionally a context can be given. The replacement is only performed if the string where the match is represented as <tt>&lt;match></tt> also matches the context.
This function is available in [[script:rule form]]. When the @replace@ is used many times with the same @match@ or @in_context@ values it is more efficient to declare these as default arguments:
When the replacement is performed many times the rule form is more efficient, because the regular expression is only compiled once. > my_replace := replace@(match: "something", replace: "something else")
> my_replace("input") # called many times
This way the regular expression is compiled only once.
--Parameters-- --Parameters--
! Parameter Type Description ! Parameter Type Description
...@@ -26,11 +27,11 @@ When the replacement is performed many times the rule form is more efficient, be ...@@ -26,11 +27,11 @@ When the replacement is performed many times the rule form is more efficient, be
> replace(match: "a", replace: "e", "banana") == "benene" > replace(match: "a", replace: "e", "banana") == "benene"
> replace(match: "a", replace: "e", in_context: "<match>n", "banana") == "benena" > replace(match: "a", replace: "e", in_context: "<match>n", "banana") == "benena"
> replace(match: "(a|b)x", replace: "[\\0,\\1]", "axabxc") == "[ax,a]a[bx,b]c" > replace(match: "(a|b)x", replace: "[\\0,\\1]", "axabxc") == "[ax,a]a[bx,b]c"
> replace(match: "[ab]", replace: { to_upper(input) }, "banana") == "BAnAnA" > replace(match: "[ab]", replace: to_upper, "banana") == "BAnAnA"
> replace(match: "([0-9])[*]([0-9])", replace: { _1 * _2 }, "2*2+3*3") == "4+9"
> >
> f := replace_rule(match: "xx+", replace: "A") > f := replace@(match: "xx+", replace: "A")
> f("xyzxxyyzz") == "xyzAAyyzz" > f("xyzxxyyzz") == "xyzAAyyzz"
--See also-- --See also--
| [[fun:filter_text|filter_text / filter_rule]] | [[fun:filter_text]] Keep only the text matching a regular expression.
Keep only the text matching a regular expression.
...@@ -2,7 +2,6 @@ Function: sort_text ...@@ -2,7 +2,6 @@ Function: sort_text
--Usage-- --Usage--
> sort_text(order: order specification, some_text) > sort_text(order: order specification, some_text)
> sort_rule(order: order specification)(some_text)
Sort a string or filter it by keeping specific characters. Sort a string or filter it by keeping specific characters.
...@@ -45,8 +44,6 @@ behaves the same as ...@@ -45,8 +44,6 @@ behaves the same as
> sort_text(order: "x") > sort_text(order: "x")
because the first @"x"@ already selects all xs from the input. because the first @"x"@ already selects all xs from the input.
This function is available in [[script:rule form]].
--Parameters-- --Parameters--
! Parameter Type Description ! Parameter Type Description
| @input@ [[type:string]] Text to sort | @input@ [[type:string]] Text to sort
...@@ -67,5 +64,5 @@ This function is available in [[script:rule form]]. ...@@ -67,5 +64,5 @@ This function is available in [[script:rule form]].
> sort_text(order: "pattern(./. cycle(wubrg))", "wgw/g") == "g/w" > sort_text(order: "pattern(./. cycle(wubrg))", "wgw/g") == "g/w"
> sort_text(order: "[1234567890]cycle(wubrg)", "21wg") == "21gw" > sort_text(order: "[1234567890]cycle(wubrg)", "21wg") == "21gw"
> >
> f := sort_rule(order: "[1234567890]cycle(wubrg)") > f := sort_text@(order: "[1234567890]cycle(wubrg)")
> f("21wg") == "21gw" > f("21wg") == "21gw"
...@@ -2,15 +2,12 @@ Function: tag_contents ...@@ -2,15 +2,12 @@ Function: tag_contents
--Usage-- --Usage--
> tag_contents(tag: some_tag, contents: some_function, some_string) > tag_contents(tag: some_tag, contents: some_function, some_string)
> tag_contents_rule(tag: some_tag, contents: some_function)(some_string)
Apply a function to the contents of a particular tag. Apply a function to the contents of a particular tag.
The function is called with @input@ set to the old value inside the tag. The function is called with @input@ set to the old value inside the tag.
The tag can be a whole tag, @"<tag>"@, or a prefix @"<i"@. In the latter case all tags starting with @"<i"@ are removed. The tag can be a whole tag, @"<tag>"@, or a prefix @"<i"@. In the latter case all tags starting with @"<i"@ are removed.
This function is available in [[script:rule form]].
--Parameters-- --Parameters--
! Parameter Type Description ! Parameter Type Description
| @tag@ [[type:string]] Tag to match | @tag@ [[type:string]] Tag to match
...@@ -23,9 +20,8 @@ This function is available in [[script:rule form]]. ...@@ -23,9 +20,8 @@ This function is available in [[script:rule form]].
> tag_contents(tag: "<atom-name", contents: { card.name }, "<atom-name-auto></atom-name-auto> loses 1 life") > tag_contents(tag: "<atom-name", contents: { card.name }, "<atom-name-auto></atom-name-auto> loses 1 life")
> == "<atom-name-auto>Pink Elephant</atom-name-auto> loses 1 life" > == "<atom-name-auto>Pink Elephant</atom-name-auto> loses 1 life"
> >
> f := tag_contents_rule(tag: "<i>", contents: {""}) > f := tag_contents@(tag: "<i>", contents: {""})
> f("text, <i-auto>reminder</i-auto> <i>italic</i>") == "text, <i-auto>reminder</i-auto> <i></i>" > f("text, <i-auto>reminder</i-auto> <i>italic</i>") == "text, <i-auto>reminder</i-auto> <i></i>"
--See also-- --See also--
| [[fun:remove_tag|remove_tag / tag_remove_rule]] | [[fun:remove_tag]] Remove a tag, keep the contents.
Remove a tag, keep the contents.
...@@ -23,12 +23,15 @@ Instead define a function in the init script. ...@@ -23,12 +23,15 @@ Instead define a function in the init script.
>field: >field:
> script: flubble_script() > script: flubble_script()
--Use rule form-- --Use default arguments--
If a function is available in [[script:rule form]] use it where possible.
Many rules can be chained together using the @+@ operator. Many functions can be chained together using the @+@ operator.
For these functions [[script:default arguments]] can be given.
Have a look at @text_filter@ in the magic game file for an example. Have a look at @text_filter@ in the magic game file for an example.
Using default arguments is especially important for functions that work on [[type:regex|regular expressions]],
since it allows MSE to compile the regular expressions just once instead of for every call.
--Don't be afraid to nest-- --Don't be afraid to nest--
Don't be afraid to nest complex things like @if@ expressions inside other expressions. Don't be afraid to nest complex things like @if@ expressions inside other expressions.
For example the blend scripts for magic use: For example the blend scripts for magic use:
......
...@@ -11,21 +11,24 @@ For determining whether the argument is set only explicit arguments count, not e ...@@ -11,21 +11,24 @@ For determining whether the argument is set only explicit arguments count, not e
> arg := "something else" > arg := "something else"
> function() == "argument was: default" > function() == "argument was: default"
//Defaults are evaluated at the time the @@@@ operator is evaluated, so they can be used to simulate static scoping. Defaults are evaluated at the time the @@@@ operator is evaluated, they will not be overriden later
> default := "old default"
> function := { "argument was: " + arg }@(arg: default)
> default := "new default"
> function() == "argument was: old default"
--Rule functions-- --Rule functions--
Some functions are available in ''rule form''. In earlier versions of MSE some functions were available in a special ''rule form''.
A call to for example @replace_rule(match:"abc",replace:"xyz")@ is equivalent to @replace@@(match:"abc",replace:"xyz")@ .
These rule form functions are functions that create a new [[type:function]] with some defaults filled in. For backwards compatability these functions are still available, but they should not be used for new templates.
That new function, the rule, applies some transformation to the input and returns the result.
Programming in a ''rule style'' is still very useful.
A rule is like a normal function with all parameters given, except for the @input@. A rule is like a normal function with all parameters given, except for the @input@.
These rules can then be combined using the @+@ operator, for example:
Rules are often combined using the + operator, for example:
> # First all "a"s are replaced, then all "b"s. > # First all "a"s are replaced, then all "b"s.
> remove_as_and_bs := replace_rule(match: "a", replace: "") + > remove_as_and_bs := replace@(match: "a", replace: "") +
> replace_rule(match: "b", replace: "") > replace@(match: "b", replace: "")
> >
> text_with_as_and_bs := "bla bla bla" > text_with_as_and_bs := "bla bla bla"
> text_without_as_and_bs := remove_as_and_bs(text_with_as_and_bs) > text_without_as_and_bs := remove_as_and_bs(text_with_as_and_bs)
......
...@@ -5,9 +5,9 @@ MSE uses a custom scripting language to add complicated behaviour to [[type:fiel ...@@ -5,9 +5,9 @@ MSE uses a custom scripting language to add complicated behaviour to [[type:fiel
--Topics-- --Topics--
* [[script:introduction|Introduction to scripting]] * [[script:introduction|Introduction to scripting]]
* [[script:Operators]] * [[script:Operators]]
* [[script:variables|Variables]] * [[script:Variables]]
* [[script:functions|Functions]] * [[script:Functions]]
* [[script:default_arguments|Default arguments]] * [[script:Default arguments]]
* [[script:Control structures]] * [[script:Control structures]]
* [[script:Predefined variables]] * [[script:Predefined variables]]
* [[script:Best practices]] * [[script:Best practices]]
......
Rule form
Some functions are available in ''rule form''.
These rule form functions are functions that create a new [[type:function]].
That new function, the rule, applies some transformation to the input and returns the result.
A rule is like a normal function with all parameters given, except for the @input@.
Rules are often combined using the + operator, for example:
> # First all "a"s are replaced, then all "b"s.
> remove_as_and_bs := replace_rule(match: "a", replace: "") +
> replace_rule(match: "b", replace: "")
>
> text_with_as_and_bs := "bla bla bla"
> text_without_as_and_bs := remove_as_and_bs(text_with_as_and_bs)
...@@ -13,7 +13,7 @@ Functions can be composed using the @+@ operator, evaluating @a + b@ first evalu ...@@ -13,7 +13,7 @@ Functions can be composed using the @+@ operator, evaluating @a + b@ first evalu
> example := to_upper + { "result == {input}" } > example := to_upper + { "result == {input}" }
> example("xyz") == "result == XYZ" > example("xyz") == "result == XYZ"
Multiple functions can be changed together like this, especially using [[script:rule form]]. Multiple functions can be changed together like this, this is especially convenient in combination with [[script:default arguments]].
--Example-- --Example--
> example := { a + b } > example := { a + b }
......
...@@ -48,7 +48,7 @@ This is written as the character with code 1 in files. ...@@ -48,7 +48,7 @@ This is written as the character with code 1 in files.
--Related functions-- --Related functions--
The following script functions deal with tags: The following script functions deal with tags:
| [[fun:tag_contents|tag_contents / tag_contents_rule]] | [[fun:tag_contents]] Change the contents of a specific tag.
Change the contents of a specific tag. | [[fun:remove_tag]] Remove a tag, keep the contents.
| [[fun:remove_tag|remove_tag / tag_remove_rule]] | [[fun:remove_tags]] Remove all tags from tagged text.
Remove a tag, keep the contents. | [[fun:to_text]] Remove all tags from tagged text, and convert it to a [[type:string]].
...@@ -30,6 +30,7 @@ ScriptRegexP regex_from_script(const ScriptValueP& value) { ...@@ -30,6 +30,7 @@ ScriptRegexP regex_from_script(const ScriptValueP& value) {
// is it a regex already? // is it a regex already?
ScriptRegexP regex = dynamic_pointer_cast<ScriptRegex>(value); ScriptRegexP regex = dynamic_pointer_cast<ScriptRegex>(value);
if (!regex) { if (!regex) {
// TODO: introduce some kind of caching?
// compile string // compile string
regex = new_intrusive<ScriptRegex>(); regex = new_intrusive<ScriptRegex>();
if (!regex->regex.Compile(*value, wxRE_ADVANCED)) { if (!regex->regex.Compile(*value, wxRE_ADVANCED)) {
...@@ -225,6 +226,7 @@ SCRIPT_FUNCTION_SIMPLIFY_CLOSURE(replace) { ...@@ -225,6 +226,7 @@ SCRIPT_FUNCTION_SIMPLIFY_CLOSURE(replace) {
// ----------------------------------------------------------------------------- : Rules : regex filter // ----------------------------------------------------------------------------- : Rules : regex filter
/*
class ScriptFilterRule : public ScriptValue { class ScriptFilterRule : public ScriptValue {
public: public:
virtual ScriptType type() const { return SCRIPT_FUNCTION; } virtual ScriptType type() const { return SCRIPT_FUNCTION; }
...@@ -259,7 +261,7 @@ ScriptValueP filter_rule(Context& ctx) { ...@@ -259,7 +261,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;
...@@ -279,9 +281,9 @@ ScriptValueP filter_rule(Context& ctx) { ...@@ -279,9 +281,9 @@ ScriptValueP filter_rule(Context& ctx) {
cache[cache_pos].rule = intrusive_ptr<ScriptFilterRule>(new ScriptFilterRule); cache[cache_pos].rule = intrusive_ptr<ScriptFilterRule>(new ScriptFilterRule);
intrusive_ptr<ScriptFilterRule>& ret = cache[cache_pos].rule; intrusive_ptr<ScriptFilterRule>& ret = cache[cache_pos].rule;
cache_pos = (cache_pos+1) % CACHE_SIZE; cache_pos = (cache_pos+1) % CACHE_SIZE;
/*/ / * /
intrusive_ptr<ScriptFilterRule> ret(new ScriptFilterRule); intrusive_ptr<ScriptFilterRule> ret(new ScriptFilterRule);
//*/ //* /
// match // match
if (!ret->regex.Compile(match, wxRE_ADVANCED)) { if (!ret->regex.Compile(match, wxRE_ADVANCED)) {
...@@ -301,6 +303,36 @@ SCRIPT_FUNCTION(filter_rule) { ...@@ -301,6 +303,36 @@ SCRIPT_FUNCTION(filter_rule) {
} }
SCRIPT_FUNCTION(filter_text) { SCRIPT_FUNCTION(filter_text) {
return filter_rule(ctx)->eval(ctx); return filter_rule(ctx)->eval(ctx);
}*/
SCRIPT_FUNCTION_WITH_SIMPLIFY(filter_text) {
SCRIPT_PARAM_C(String, input);
SCRIPT_PARAM_C(ScriptRegexP, match);
SCRIPT_OPTIONAL_PARAM_C_(ScriptRegexP, in_context);
String ret;
// find all matches
while (match->regex.Matches(input)) {
// match, append to result
size_t start, len;
bool ok = match->regex.GetMatch(&start, &len, 0);
assert(ok);
String inside = input.substr(start, len); // the match
String next_input = input.substr(start + len); // everything after the match
if (!in_context || in_context->regex.Matches(input.substr(0,start) + _("<match>") + next_input)) {
// no context or context match
ret += inside;
}
input = next_input;
}
SCRIPT_RETURN(ret);
}
SCRIPT_FUNCTION_SIMPLIFY_CLOSURE(filter_text) {
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 break // ----------------------------------------------------------------------------- : Rules : regex break
...@@ -452,7 +484,7 @@ void init_script_regex_functions(Context& ctx) { ...@@ -452,7 +484,7 @@ void init_script_regex_functions(Context& ctx) {
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"), new_intrusive1<ScriptRule>(script_replace)); ctx.setVariable(_("replace rule"), new_intrusive1<ScriptRule>(script_replace));
ctx.setVariable(_("filter rule"), script_filter_rule); ctx.setVariable(_("filter rule"), new_intrusive1<ScriptRule>(script_filter_text));
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));
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment