My function seems to have no effect
[1/14] from: richard:coffre:francetelecom at: 15-Apr-2002 11:46
Hi Rebol fellows,
Hereafter my code :
REBOL[]
get_func_name: make function! [ chaine ] [
use [ guillemet ] [
guillemet: make string! {"}
remove/part chaine 6
foo: copy/part chaine 1 1
if foo == guillemet [ remove/part chaine 1 ]
; Supprimer les 2 derniers caract=E8res
clear skip tail chaine -2
return (chaine)
]
]
test: copy "123456fonction rearzer r r12"
print test
print ["toto:" get_func_name [ test ]]
When I test it, I have :
>> do %get_func.r
Script: "Untitled" (none)
123456fonction rearzer r r12
toto:
and not something like this : "fonction rearzer r r"
Richard Coffre
France Telecom Orbiscom
T=E9l. : 01 47 61 46 28
[2/14] from: lmecir:mbox:vol:cz at: 15-Apr-2002 13:05
Hi Richard,
just use something like:
print ["toto:" get_func_name test]
----- Original Message -----
Subject: [REBOL] My function seems to have no effect
Hi Rebol fellows,
Hereafter my code :
REBOL[]
get_func_name: make function! [ chaine ] [
use [ guillemet ] [
guillemet: make string! {"}
remove/part chaine 6
foo: copy/part chaine 1 1
if foo == guillemet [ remove/part chaine 1 ]
; Supprimer les 2 derniers caractères
clear skip tail chaine -2
return (chaine)
]
]
test: copy "123456fonction rearzer r r12"
print test
print ["toto:" get_func_name [ test ]]
When I test it, I have :
>> do %get_func.r
Script: "Untitled" (none)
123456fonction rearzer r r12
toto:
and not something like this : "fonction rearzer r r"
Richard Coffre
France Telecom Orbiscom
Tél. : 01 47 61 46 28
[3/14] from: richard:coffre:francetelecom at: 15-Apr-2002 14:16
I'm stupid. I was so obvious that I didn't see it.
Thanks to clean my eyes.
:-)
-----Message d'origine-----
De : Ladislav Mecir [mailto:[lmecir--mbox--vol--cz]]
Envoy=E9 : lundi 15 avril 2002 13:05
=C0 : [rebol-list--rebol--com]
Objet : [REBOL] Re: My function seems to have no effect
Hi Richard,
just use something like:
print ["toto:" get_func_name test]
----- Original Message -----
Subject: [REBOL] My function seems to have no effect
Hi Rebol fellows,
Hereafter my code :
REBOL[]
get_func_name: make function! [ chaine ] [
use [ guillemet ] [
guillemet: make string! {"}
remove/part chaine 6
foo: copy/part chaine 1 1
if foo == guillemet [ remove/part chaine 1 ]
; Supprimer les 2 derniers caract=E8res
clear skip tail chaine -2
return (chaine)
]
]
test: copy "123456fonction rearzer r r12"
print test
print ["toto:" get_func_name [ test ]]
When I test it, I have :
>> do %get_func.r
Script: "Untitled" (none)
123456fonction rearzer r r12
toto:
and not something like this : "fonction rearzer r r"
Richard Coffre
France Telecom Orbiscom
T=E9l. : 01 47 61 46 28
[4/14] from: joel:neely:fedex at: 15-Apr-2002 8:48
Hi, Richard,
The definition of your GET_FUNC_NAME seens to want a string
argument, but you're handing it a block.
However, let's look a little deeper...
COFFRE Richard FTO wrote:
> Hi Rebol fellows,
> Hereafter my code :
<<quoted lines omitted: 10>>
> ]
> ]
1) You should establish types for function arguments whenever
possible. That will help you catch any mismatch errors
(whether typos or thinkos ;-).
get_func_name: func [chaine [string!]] [
;...
]
2) If you need a local value within a function, use the right
mechanism for that purpose. There are some potentially
confusing interactions between USE and FUNC which you can avoid
by saying
get_func_name: func [chaine [string!] /local guillemet] [
;...
]
to put GUILLEMET in the context of the GET_FUNC_NAME function.
3) That said, in this case you don't need GUILLEMET at all,
since you're only using it as a constant value in the
test to see whether to snip off the leading quote. You also
don't need FOO (which you use but allow to remain global!)
get_func_name: func [chaine [string!]] [
remove/part chaine 6
if chaine/1 = #"^"" [ remove/part chaine 1 ]
; Supprimer les 2 derniers caractères
clear skip tail chaine -2
chaine
]
because a string is just a series of characters, so you can
explicitly test (e.g.) the first character of a string vs.
a character value.
4) REMOVE defaults to removing one element, so the /PART
refinement isn't needed for a single element removal.
get_func_name: func [chaine [string!]] [
remove/part chaine 6
if chaine/1 = #"^"" [ remove chaine ]
; Supprimer les 2 derniers caractères
clear skip tail chaine -2
chaine
]
5) CLEAR returns the tail of its argument series, and you
apparently want the head of that series as your result,
so why not...
get_func_name: func [chaine [string!]] [
remove/part chaine 6
if chaine/1 = #"^"" [ remove chaine ]
head clear skip tail chaine -2
]
6) REMOVE returns the remainder of the series, so...
get_func_name: func [chaine [string!]] [
if #"^"" = first remove/part chaine 6 [
remove chaine
]
head clear skip tail chaine -2
]
After the above changes, we have this behavior
>> get_func_name "123456fonction rearzer r r12"
== "fonction rearzer r r"
Is that what you wanted as the result for this test case?
Finally, I don't know your application, but I'm a bit puzzled
by the issue of checking for (and removing if found) the
quotation mark. Do you really have data in your application
that looks like
123456"fonction rearzer r r12
with an embedded quotation mark? If there's a quotation mark
after the first six characters, is there a matching quotation
mark later on in the line? If so, should it be removed as well
(either before or after deleting the last two characters)?
HTH!
-jn-
--
; Joel Neely joeldotneelyatfedexdotcom
REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip
do function [s] [t] [ t: "" foreach [a b] s [repend t [b a]] t ] {
| e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]
[5/14] from: g:santilli:tiscalinet:it at: 15-Apr-2002 18:19
Hi COFFRE,
On Monday, April 15, 2002, 11:46:04 AM, you wrote:
CRF> get_func_name: make function! [ chaine ] [
CRF> use [ guillemet ] [
CRF> guillemet: make string! {"}
CRF> remove/part chaine 6
CRF> foo: copy/part chaine 1 1
CRF> if foo == guillemet [ remove/part chaine 1 ]
CRF> ; Supprimer les 2 derniers caractères
CRF> clear skip tail chaine -2
CRF> return (chaine)
CRF> ]
CRF> ]
I see others have answered your question, but I'd like to point
out another way to write your function; I hope it can be useful.
get_func_name: func [chaine /local chars-to-skip start end] [
chars-to-skip: either chaine/7 = #"^"" [7] [6]
start: skip chaine chars-to-skip
end: skip tail chaine -2
copy/part start end
]
which can be reduced to:
get_func_name: func [chaine] [
copy/part skip chaine either chaine/7 = #"^"" [7] [6] skip tail chaine -2
]
which will probably be much faster than your version.
Regards,
Gabriele.
--
Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer
Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r
[6/14] from: richard:coffre:francetelecom at: 16-Apr-2002 9:47
Thanks for your optimization
-----Message d'origine-----
De : Gabriele Santilli [mailto:[g--santilli--tiscalinet--it]]
Envoy=E9 : lundi 15 avril 2002 18:20
=C0 : COFFRE Richard FTO
Objet : [REBOL] Re: My function seems to have no effect
Hi COFFRE,
On Monday, April 15, 2002, 11:46:04 AM, you wrote:
CRF> get_func_name: make function! [ chaine ] [
CRF> use [ guillemet ] [
CRF> guillemet: make string! {"}
CRF> remove/part chaine 6
CRF> foo: copy/part chaine 1 1
CRF> if foo == guillemet [ remove/part chaine 1 ]
CRF> ; Supprimer les 2 derniers caract=E8res
CRF> clear skip tail chaine -2
CRF> return (chaine)
CRF> ]
CRF> ]
I see others have answered your question, but I'd like to point
out another way to write your function; I hope it can be useful.
get_func_name: func [chaine /local chars-to-skip start end] [
chars-to-skip: either chaine/7 = #"^"" [7] [6]
start: skip chaine chars-to-skip
end: skip tail chaine -2
copy/part start end
]
which can be reduced to:
get_func_name: func [chaine] [
copy/part skip chaine either chaine/7 = #"^"" [7] [6] skip tail
chaine -2
]
which will probably be much faster than your version.
Regards,
Gabriele.
--
Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer
Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r
[7/14] from: richard:coffre:francetelecom at: 16-Apr-2002 9:33
Hi Joel,
Your explanation is very very useful for a newbie like me and it helps to
understand the philosophy of Rebol.
Indeed, the lines I need to "clean" look like Call ("GetOCode:initData")
where I need to delete "Call ("" and the final ").
I'm sure now I can use parse with the option {"} to get only the tail but
I'm learning day after day.
I repeat I really appreciate your didactic explanation.
Thanks a lot
-----Message d'origine-----
De : Joel Neely [mailto:[joel--neely--fedex--com]]
Envoy=E9 : lundi 15 avril 2002 15:48
=C0 : [rebol-list--rebol--com]
Objet : [REBOL] Re: My function seems to have no effect
Hi, Richard,
The definition of your GET_FUNC_NAME seens to want a string
argument, but you're handing it a block.
However, let's look a little deeper...
COFFRE Richard FTO wrote:
> Hi Rebol fellows,
> Hereafter my code :
<<quoted lines omitted: 10>>
> ]
> ]
1) You should establish types for function arguments whenever
possible. That will help you catch any mismatch errors
(whether typos or thinkos ;-).
get_func_name: func [chaine [string!]] [
;...
]
2) If you need a local value within a function, use the right
mechanism for that purpose. There are some potentially
confusing interactions between USE and FUNC which you can avoid
by saying
get_func_name: func [chaine [string!] /local guillemet] [
;...
]
to put GUILLEMET in the context of the GET_FUNC_NAME function.
3) That said, in this case you don't need GUILLEMET at all,
since you're only using it as a constant value in the
test to see whether to snip off the leading quote. You also
don't need FOO (which you use but allow to remain global!)
get_func_name: func [chaine [string!]] [
remove/part chaine 6
if chaine/1 = #"^"" [ remove/part chaine 1 ]
; Supprimer les 2 derniers caract=E8res
clear skip tail chaine -2
chaine
]
because a string is just a series of characters, so you can
explicitly test (e.g.) the first character of a string vs.
a character value.
4) REMOVE defaults to removing one element, so the /PART
refinement isn't needed for a single element removal.
get_func_name: func [chaine [string!]] [
remove/part chaine 6
if chaine/1 = #"^"" [ remove chaine ]
; Supprimer les 2 derniers caract=E8res
clear skip tail chaine -2
chaine
]
5) CLEAR returns the tail of its argument series, and you
apparently want the head of that series as your result,
so why not...
get_func_name: func [chaine [string!]] [
remove/part chaine 6
if chaine/1 = #"^"" [ remove chaine ]
head clear skip tail chaine -2
]
6) REMOVE returns the remainder of the series, so...
get_func_name: func [chaine [string!]] [
if #"^"" = first remove/part chaine 6 [
remove chaine
]
head clear skip tail chaine -2
]
After the above changes, we have this behavior
>> get_func_name "123456fonction rearzer r r12"
== "fonction rearzer r r"
Is that what you wanted as the result for this test case?
Finally, I don't know your application, but I'm a bit puzzled
by the issue of checking for (and removing if found) the
quotation mark. Do you really have data in your application
that looks like
123456"fonction rearzer r r12
with an embedded quotation mark? If there's a quotation mark
after the first six characters, is there a matching quotation
mark later on in the line? If so, should it be removed as well
(either before or after deleting the last two characters)?
HTH!
-jn-
--
; Joel Neely joeldotneelyatfedexdotcom
REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip
do function [s] [t] [ t: "" foreach [a b] s [repend t [b a]] t ] {
| e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]
[8/14] from: joel:neely:fedex at: 16-Apr-2002 7:21
Hi, Richard,
In that case...
COFFRE Richard FTO wrote:
> Hi Joel,
>
> Indeed, the lines I need to "clean" look like
> Call ("GetOCode:initData")
> where I need to delete "Call ("" and the final ").
>
Some sample data:
bletch: {
Call ("Get0Code:initData")
call ("TestFunc:blahblah")
call("Quux:flarp") call("Quux:spoo")
call ( "Layout:spaceObsessively" ) CALL ( "The:end" )
}
Some generic boilerplate:
whitespace: charset { ^-^/} gap: [any whitespace]
The real work happens here:
parse/all bletch [
any [
{call} gap {(} gap {"} copy fn to {"} {"} gap {)} (
print fn
)
|
skip
]
]
This produces the following output:
Get0Code:initData
TestFunc:blahblah
Quux:flarp
Quux:spoo
Layout:spaceObsessively
The:end
You can, of course, do something inside the parens more interesting
than just print out to the console...
HTH!
-jn-
--
; Joel Neely joeldotneelyatfedexdotcom
REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip
do function [s] [t] [ t: "" foreach [a b] s [repend t [b a]] t ] {
| e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]
[9/14] from: richard:coffre:francetelecom at: 16-Apr-2002 14:45
It's really great but the double quotes are optional so what should be
update in your code ?
You're really fast for me and I don't have the time to understand everything
but with this easy example I can realize all the power of Rebol.
Let's go to the Rebolution ...
-----Message d'origine-----
De : Joel Neely [mailto:[joel--neely--fedex--com]]
Envoy=E9 : mardi 16 avril 2002 14:21
=C0 : [rebol-list--rebol--com]
Objet : [REBOL] Re: My function seems to have no effect
Hi, Richard,
In that case...
COFFRE Richard FTO wrote:
> Hi Joel,
>
> Indeed, the lines I need to "clean" look like
> Call ("GetOCode:initData")
> where I need to delete "Call ("" and the final ").
>
Some sample data:
bletch: {
Call ("Get0Code:initData")
call ("TestFunc:blahblah")
call("Quux:flarp") call("Quux:spoo")
call ( "Layout:spaceObsessively" ) CALL ( "The:end" )
}
Some generic boilerplate:
whitespace: charset { ^-^/} gap: [any whitespace]
The real work happens here:
parse/all bletch [
any [
{call} gap {(} gap {"} copy fn to {"} {"} gap {)} (
print fn
)
|
skip
]
]
This produces the following output:
Get0Code:initData
TestFunc:blahblah
Quux:flarp
Quux:spoo
Layout:spaceObsessively
The:end
You can, of course, do something inside the parens more interesting
than just print out to the console...
HTH!
-jn-
--
; Joel Neely joeldotneelyatfedexdotcom
REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip
do function [s] [t] [ t: "" foreach [a b] s [repend t [b a]] t ] {
| e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]
[10/14] from: richard::coffre::francetelecom::com at: 16-Apr-2002 14:55
Hi,
Can you give more explanation about the boilerplate.
I believe that gap is not a refinement of parse but I don't really
understand the link between the boilerplate and the parse command : how can
Rebol use the whitespace definition into parse ... ???
:-O
-----Message d'origine-----
De : Joel Neely [mailto:[joel--neely--fedex--com]]
Envoy=E9 : mardi 16 avril 2002 14:21
=C0 : [rebol-list--rebol--com]
Objet : [REBOL] Re: My function seems to have no effect
Hi, Richard,
In that case...
COFFRE Richard FTO wrote:
> Hi Joel,
>
> Indeed, the lines I need to "clean" look like
> Call ("GetOCode:initData")
> where I need to delete "Call ("" and the final ").
>
Some sample data:
bletch: {
Call ("Get0Code:initData")
call ("TestFunc:blahblah")
call("Quux:flarp") call("Quux:spoo")
call ( "Layout:spaceObsessively" ) CALL ( "The:end" )
}
Some generic boilerplate:
whitespace: charset { ^-^/} gap: [any whitespace]
The real work happens here:
parse/all bletch [
any [
{call} gap {(} gap {"} copy fn to {"} {"} gap {)} (
print fn
)
|
skip
]
]
This produces the following output:
Get0Code:initData
TestFunc:blahblah
Quux:flarp
Quux:spoo
Layout:spaceObsessively
The:end
You can, of course, do something inside the parens more interesting
than just print out to the console...
HTH!
-jn-
--
; Joel Neely joeldotneelyatfedexdotcom
REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip
do function [s] [t] [ t: "" foreach [a b] s [repend t [b a]] t ] {
| e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]
[11/14] from: joel:neely:fedex at: 16-Apr-2002 10:58
Hi, Richard,
I'll try to explain and fix...
COFFRE Richard FTO wrote:
> ... the double quotes are optional ...
>
> Can you give more explanation about the boilerplate.
> I believe that gap is not a refinement of parse but I don't
> really understand the link between the boilerplate and the
> parse command : how can Rebol use the whitespace definition
> into parse ... ???
>
Briefly, the parse rules specify a "grammar" which must be satisfied
by the series being parsed. (In the comments below, I'll stick to
parsing a string.)
A BITSET! value can be used by PARSE in the sense of "one of these
characters", so the definition
whitespace: charset { ^-^/}
means that the value of WHITESPACE will match anywhere that a space,
tab, or newline occurs. Within the parsing dialect, the keyword ANY
means zero or more occurrences of what follows, so the definition
gap: [any whitespace]
means that GAP will match anywhere that an optional run made up of
spaces, tabs, and newlines (in any order/combination) occurs.
If the quotation marks are optional, then the grammar gets a bit
more complicated, especially if we're going to worry about whether
the quotation marks must balance. Of course, we can cheat and
assume that whatever is creating the input data will deal with
that issue. In other words, I'll assume that presence/absence
of properly-balanced quotation marks isn't a significant issue for
the present purpose.
> Some sample data:
> bletch: {
<<quoted lines omitted: 3>>
> call ( "Layout:spaceObsessively" ) CALL ( "The:end" )
> }
bletch: {
Call ("Get0Code:initData")
call ("TestFunc:blahblah")
call("Quux:flarp") call("Quux:spoo")
CALL (MoreStuff:unQuoted)
call ( MoreStuff:quotesMustMatch )
call("Cheat:caseOne) call(Cheat:caseTwo")
call ( "Layout:spaceObsessively" ) CALL ( "The:end" )
}
whitespace: charset { ^-^/} gap: [any whitespace]
parse/all bletch [
any [
{call} gap {(} copy fn to {)} {)} (
print trim/with fn {" }
)
|
skip
]
]
This provides the following output:
Get0Code:initData
TestFunc:blahblah
Quux:flarp
Quux:spoo
MoreStuff:unQuoted
MoreStuff:quotesMustMatch
Cheat:caseOne
Cheat:caseTwo
Layout:spaceObsessively
The:end
and returns TRUE because it consumed the entire string.
The way that parse rule works is as follows:
- a string is assumed to be made up of zero or more parts
(that's the role of ANY )
- each part is either a function call or a single character
whose value we don't care about
(that's the role of | )
- a function call must contain the following parts:
- the literal word "call"
- an optional run of whitespace
- an open parenthesis
- any characters (no constraints on what may appear here)
up to but not including a close parenthesis --
all of which will be saved in the word FN
- a close parenthesis
- if we do match a function call with the above syntax, remove
all spaces and quotation marks from the string in FN and print
what's left
(that's the role of the parentheses enclosing the PRINT...
phrase)
Note that this version will allow unbalanced quotation marks around
the name of the function being called.
Hope this helps!
-jn-
[12/14] from: anton:lexicon at: 17-Apr-2002 2:22
Hi,
{ ^-^/}
Ceci une chaine contenant trois caractères:
This is a string containing three characters:
1) a space
2) a tab
3) a newline
The /all refinement of parse directs parse to
consider all characters, including whitespaces.
See the help for parse.
Anton.
[13/14] from: richard:coffre:francetelecom at: 17-Apr-2002 10:31
Thanks Joel
-----Message d'origine-----
De : Joel Neely [mailto:[joel--neely--fedex--com]]
Envoy=E9 : mardi 16 avril 2002 17:58
=C0 : [rebol-list--rebol--com]
Objet : [REBOL] Re: My function seems to have no effect
Hi, Richard,
I'll try to explain and fix...
COFFRE Richard FTO wrote:
> ... the double quotes are optional ...
>
> Can you give more explanation about the boilerplate.
> I believe that gap is not a refinement of parse but I don't
> really understand the link between the boilerplate and the
> parse command : how can Rebol use the whitespace definition
> into parse ... ???
>
Briefly, the parse rules specify a "grammar" which must be satisfied
by the series being parsed. (In the comments below, I'll stick to
parsing a string.)
A BITSET! value can be used by PARSE in the sense of "one of these
characters", so the definition
whitespace: charset { ^-^/}
means that the value of WHITESPACE will match anywhere that a space,
tab, or newline occurs. Within the parsing dialect, the keyword ANY
means zero or more occurrences of what follows, so the definition
gap: [any whitespace]
means that GAP will match anywhere that an optional run made up of
spaces, tabs, and newlines (in any order/combination) occurs.
If the quotation marks are optional, then the grammar gets a bit
more complicated, especially if we're going to worry about whether
the quotation marks must balance. Of course, we can cheat and
assume that whatever is creating the input data will deal with
that issue. In other words, I'll assume that presence/absence
of properly-balanced quotation marks isn't a significant issue for
the present purpose.
> Some sample data:
> bletch: {
<<quoted lines omitted: 3>>
> call ( "Layout:spaceObsessively" ) CALL ( "The:end" )
> }
bletch: {
Call ("Get0Code:initData")
call ("TestFunc:blahblah")
call("Quux:flarp") call("Quux:spoo")
CALL (MoreStuff:unQuoted)
call ( MoreStuff:quotesMustMatch )
call("Cheat:caseOne) call(Cheat:caseTwo")
call ( "Layout:spaceObsessively" ) CALL ( "The:end" )
}
whitespace: charset { ^-^/} gap: [any whitespace]
parse/all bletch [
any [
{call} gap {(} copy fn to {)} {)} (
print trim/with fn {" }
)
|
skip
]
]
This provides the following output:
Get0Code:initData
TestFunc:blahblah
Quux:flarp
Quux:spoo
MoreStuff:unQuoted
MoreStuff:quotesMustMatch
Cheat:caseOne
Cheat:caseTwo
Layout:spaceObsessively
The:end
and returns TRUE because it consumed the entire string.
The way that parse rule works is as follows:
- a string is assumed to be made up of zero or more parts
(that's the role of ANY )
- each part is either a function call or a single character
whose value we don't care about
(that's the role of | )
- a function call must contain the following parts:
- the literal word "call"
- an optional run of whitespace
- an open parenthesis
- any characters (no constraints on what may appear here)
up to but not including a close parenthesis --
all of which will be saved in the word FN
- a close parenthesis
- if we do match a function call with the above syntax, remove
all spaces and quotation marks from the string in FN and print
what's left
(that's the role of the parentheses enclosing the PRINT...
phrase)
Note that this version will allow unbalanced quotation marks around
the name of the function being called.
Hope this helps!
-jn-
[14/14] from: richard:coffre:francetelecom at: 17-Apr-2002 10:33
Thanks Anton
-----Message d'origine-----
De : Anton [mailto:[anton--lexicon--net]]
Envoy=E9 : mardi 16 avril 2002 18:23
=C0 : [rebol-list--rebol--com]
Objet : [REBOL] Re: My function seems to have no effect
Hi,
{ ^-^/}
Ceci une chaine contenant trois caract=E8res:
This is a string containing three characters:
1) a space
2) a tab
3) a newline
The /all refinement of parse directs parse to
consider all characters, including whitespaces.
See the help for parse.
Anton.
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted