Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Line continuation: A method to divide up long lines.


  • Please log in to reply
25 replies to this topic
savage
  • Members
  • 207 posts
  • Last active: Jul 03 2008 03:12 AM
  • Joined: 02 Jul 2004
This would be easier if we had a sort of file-here syntax. Something like this...

FileAppend, CVBsAhkTest.vbs, ENDFILE
Set objFM = WScript.CreateObject ("FMPRO.Application")
objFM.Visible=True
Set objFMfiles = objFM.Documents.Open("%FileNamePath%"`,"")
objFMfiles.DoFMScript ("%ScriptName%")
objFM.Quit
ENDFILE

IE, it reads all the text between the fileappend and the specified ending string literally. I guess this would be good for assigning chunks of text to variables. Actually maybe that would be better, like this ...

TextHere, var, endstring
blah
jadlfjoa9040

yadda yadda
etc etc etc
endstring

FileAppend, %var%, file

That way the technique could be used without having to change additional functions.

And continuing my train of thought, an expanded application of this would be to run your script like so -

Run, %comspec% /k C:\VBsAHKTest.vbs > C:\output.txt

And then read the file in. It would be slow because of the disk access, but it would allow some rudimentary communication between the script and ahk.

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Although something like this has been asked for before, you gave some nice details with your idea. How about something more general like this example:

FileAppend,
  
Set objFM = WScript.CreateObject ("FMPRO.Application")
objFM.Visible=True
Set objFMfiles = objFM.Documents.Open("%FileNamePath%"`,"")
objFMfiles.DoFMScript ("%ScriptName%")
objFM.Quit
, CVBsAhkTest.vbs


One drawback with the above is that you would still need to escape literal commas in any parameter that needs them, such as the above. I'm not sure if there is any good remedy for that.

Also, can anyone think of a better tag than
?  "Preformatted" isn't really quite accurate, so it's main strength is being easy to remember for those who know HTML.

Also, there is some doubt about default vs. optional behavior for the following:
- Should leading tabs and spaces be omitted by default?
- Should linebreaks be omitted by default?

To make the above configurable, perhaps something like these examples:
: linebreaks become linefeeds
: linebreaks become CR+LF
: linebreaks become spaces
: Retain leading spaces or tabs in each line.
					
					

jonny
  • Members
  • 2951 posts
  • Last active: Feb 24 2008 04:22 AM
  • Joined: 13 Nov 2004
Carets don't seem to fit AHK very well. First and foremost, I think the tag should be configurable like #CommentFlag or #EscapeChar, but in my opinion the default should be parentheses or maybe a parenthese-enclosed tag, like so:

FileAppend,
(
Set objFM = WScript.CreateObject ("FMPRO.Application")
objFM.Visible=True
Set objFMfiles = objFM.Documents.Open("%FileNamePath%"`,"")
objFMfiles.DoFMScript ("%ScriptName%")
objFM.Quit
, CVBsAhkTest.vbs
)

or

FileAppend,
(param)
Set objFM = WScript.CreateObject ("FMPRO.Application")
objFM.Visible=True
Set objFMfiles = objFM.Documents.Open("%FileNamePath%"`,"")
objFMfiles.DoFMScript ("%ScriptName%")
objFM.Quit
, CVBsAhkTest.vbs
(/param)

As for the configuration, I think it's a great idea. But rather than include it in the tag itself, you could make another parameter for it.


And just to clarify, are you talking about including this as feature for all parameters, or just for this specific one? I personally would be more comfortable in some circumstances using this. I'm always worrying about escaping commas and the like.

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004

I think the tag should be configurable like #CommentFlag or #EscapeChar

Sounds good, but one fairly large problem with it is that it can lead to ambiguity: If the author of a script configures the PRE/paren operator to be something that could be construed as the start of a variable name, the loading routine would have a hard time figuring out whether it is a continuation of the line above or the start of a "var = value" line.

in my opinion the default should be parentheses or maybe a parenthese-enclosed tag, like so:

FileAppend,
(
...
)

Parens are certainly simpler, but it might cause ambiguity someday if infix expressions such as (var + 3) are ever allowed on the left side of an assignment. Since this is hard to imagine, it's only a minor concern.

(param)
...
(/param)

I wanted it to work also to break apart a single parameter, so that probably wouldn't be the best name. For example:
FileAppend, Some really long line of text`n
(
And sentence #2.
And sentence #3.
, MyFile.txt
)

As for the configuration, I think it's a great idea. But rather than include it in the tag itself, you could make another parameter for it.

Did you mean make it a global setting? I wanted to have the options available on a per-use basis because there are varying times when CR+LF, LF, or nothing at all would be wanted.

And just to clarify, are you talking about including this as feature for all parameters, or just for this specific one?

Good point. I wanted it to be for all commands. In fact, this is purely a line continuation mechanism. When the script is running, the command itself never "sees" the paren/PRE section because by that time, the pre-loader has already merged it all into one giant line.

By the way, a minor drawback of this approach is that the total cumulative line size will be limited to about 16383 characters.

I'm always worrying about escaping commas and the like.

Unfortunately, the idea as presented does nothing to help with that (perhaps that's a reason to disallow it from splitting a single parameter as shown above). However, it is alleviated a little by the fact that you don't have to escape commas in the following cases:
1) MsgBox
2) In the last parameter of a command, such as the Text parameter of "Gui, Add".
3) When assigning to a var temporarily, and then passing a reference to that var as a param:
var = commas in here, do not need to be escaped.
FileAppend, %var%`n, MyFile.txt

Tekl
  • Members
  • 814 posts
  • Last active: May 03 2009 03:28 PM
  • Joined: 24 Sep 2004
Hi,

I would prefer it like in PHP:

myVar = <<<END
Multiline
Text
END

and for FileAppend:
FileAppend, <<<END
Multiline
Text
END, c:\My Documents\Test.txt

maybe it could done this way:
FileAppend, <<<END, c:\My Documents\Test.txt
Multiline
Text
END

Regards, Tekl

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
It is a nice syntax, but the problem is ambiguity. I've made ambiguity mistakes in the past so I've become very wary of them.

In this case, having <<
Still, the additional slight chance of breaking existing scripts is enough to turn me off the same-line idea. Though something like this is still possible because it's not ambiguous:

myVar =
<< Multiline
Text
END

But if it would be done that way, it might as well be done with a simpler leading key-symbol such as the parentheses idea above.

Thanks for your suggestion. Even though not adopted, it enriches those of us who don't know much PHP.

Tekl
  • Members
  • 814 posts
  • Last active: May 03 2009 03:28 PM
  • Joined: 24 Sep 2004
Hi Chris,

the <<< could be escaped with `<<<. Do you have understand, that also << You're right, a non-PHP-coder could have problems. What about using the known %-symbol?

myVar = %%%END%%%
bla bla
blubb blubb
%%%END%%%

Tekl

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Very original ideas. I'll consider those, but might wind up using Jonny's paretheses idea since it's so simple and concise. This is how it would look:
myVar =
(`n
     Multiline 
     Text
)
The `n above tells it to substitute a `n for each literal line-break.

Tekl
  • Members
  • 814 posts
  • Last active: May 03 2009 03:28 PM
  • Joined: 24 Sep 2004
Hi Chris,

yes that looks easy, but what appens with this code?

myVar = 
(`n 
     Multiline 
     This maybe is a problem: )
     Does it continue here?
)

I don't understand what `n means.

Tekl

BoBo
  • Guests
  • Last active:
  • Joined: --
The `n above tells it to substitute a `n for each literal line-break.

Hinzuf├╝gen eines CR+LF an jedes Zeilenende im definierten Text (?)

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
The parentheses would only be recognized when they appear at the beginning of a line, so it seems okay. But there is the question of whether the last line should have a `n or not. By default, probably not.

`n is an escape sequence that stands for the linefeed/newline character (similar to the user having pressed Enter). If `n were absent in the example above, the lines would be concatenated without any intervening characters. For example:
Gui, Add, ListBox,, Item1|Item2|Item3
(
     |Item4|Item5|Item6
     |Item7|Item8|Item9
)
The text in between the parens would be merged into the top line without any spaces, tabs, or linefeeds in between.

  • Guests
  • Last active:
  • Joined: --
I have to say I like savage's option...

FileAppend, CVBsAhkTest.vbs, ENDFILE
Set objFM = WScript.CreateObject ("FMPRO.Application")
objFM.Visible=True
Set objFMfiles = objFM.Documents.Open("%FileNamePath%"`,"")
objFMfiles.DoFMScript ("%ScriptName%")
objFM.Quit
ENDFILE

...most (at 1st), but I'm not sure if it's a typo or if he's suggesting reversing the params, the help says Text is the 1st param & Filename is the 2nd, but above he reversed it, so it's either part of the suggestion or just a typo. Anyway, I think static, one-line options, like Filename, should be 1st & ambiguously long options should be at the end, like Text. Which would make his example work.

Actually maybe that would be better, like this ...

...instead of making it only work by adding it to a var, it should work on all params of everything, so you could do the above FileAppend way OR do...

var = ENDFILE
blah
blah
ENDFILE
Chris, I got lost on your post with the
 tags, 1st I thought it was forum cough, where you were trying to make that text be html 
'd, but then you mentioned it later as really being part of the syntax. What is 
 supposed to do?

I don't know where the parenthese idea is going...

[quote]in my opinion the default should be parentheses or maybe a parenthese-enclosed tag, like so:

FileAppend,
(
...
)[/quote]
...if you had a closing parenthese in the Text, you'd have to escape it too.

[quote name="Chris"]In fact, this is purely a line continuation mechanism. When the script is running, the command itself never "sees" the paren/PRE section because by that time, the pre-loader has already merged it all into one giant line.

By the way, a minor drawback of this approach is that the total cumulative line size will be limited to about 16383 characters.[/quote]
...no, it shouldn't smash the continued lines together, then run it, it should run through it & add each line that isn't the end, to an internal (the ahk program itself, not the script) variable (resizing to fit), then when it gets to the end, use that variable as the Text, use it as a parameter to the internal function that does whatever. Why is the line limited to 16383?

I like this option...

[quote name="Tekl"]I would prefer it like in PHP:

[code]myVar = << Multiline
Text
END[/code]
[/quote]
...but why 3 <'s? Does PHP really use 3? Perl uses 2...

[code]$var =<<'END_OF_VAR';[/code]
...so it could be...

[code]var = <<'END_OF_VAR'[/code]
...in ahk. You could keep or lose the single quotes, I don't know if perl requires them, they're just in the code where I know it's used, using them might help unambiguate things, I'd say lose them if not 100% necessary.

[quote name="Tekl"]and for FileAppend:
[code]FileAppend, << Multiline
Text
END, c:\My Documents\Test.txt[/code]
[/quote]
...my version...

[code]FileAppend, << END_OF_TEXT
Multiline
Text
END_OF_TEXT
c:\My Documents\Test.txt[/code]
...2 <'s, a longer end string to make sure it's unique, in perl the end string has to be on it's own line so I did that here, you don't need a comma, because the previous param was ended by the end string, anything left has to be the rest of the params, but leaving the comma before the last line isn't that big of a deal.

This is the best version...

[quote name="Tekl"]maybe it could done this way:
[code]FileAppend, << Multiline
Text
END[/code]
[/quote]
...my version...

[code]FileAppend, << END_OF_TEXT, c:\My Documents\Test.txt
Multiline
Text
END_OF_TEXT[/code]
...I don't see how this is ambiguous, because you just have to not allow a comma in the end string, that is not a big limitation or you could use the single quotes & the end string could contain anything or just escape the comma, escaping the end string to contain what you want is alot better than escaping anything in the actual text.

Expanding on this you could have multiple << parameters...

[code]FileAppend, << END_OF_TEXT, << END_OF_FILENAME
Multiline
Text
END_OF_TEXT
c:\My Documents\Test.txt
END_OF_FILENAME[/code]
...while this is a bad example, because a filename shouldn't contain line breaks, there might be some other function that accepts 2 Text params & this is how you could do that. This is why the in-line << is better. There should be some flag somewhere to indicate whether the text should be parsed for ahk variables...default it should probably not, to preserve whatever text is dumped in there. Like maybe...

[code]InputBox, filename, Title, Enter Filename
FileAppend, << END_OF_TEXT, <<% END_OF_FILENAME
Multiline
Text
END_OF_TEXT
%filename%
END_OF_FILENAME[/code]
...this time using <<% instead of << would mean "parse the text for variables", if there are different classes of things to parse for, use different flags, default no parsing, use exactly as is.

Since we're already in disagreement about 3 <'s or 2...you could have a...

[code]#EndStringChars <<
#EndStringChars <<<[/code]
...define & then anyone could use any prefix & it would treat it as an end string, they would have to pick a unique, non-conflicting prefix tho...or...

[code]#EndStringFormat <<%s>>
#EndStringFormat %%%%s%%%[/code]
...this version is to take into account the %%%END%%% example, some people might want more than a prefix, but a suffix too, so they could use this to define both, %s in the string is treated as the place where it matches the end string text, anything but %s is treated as a prefix & suffix to match in an end string. Not having %s in the format string could either be an error or it could treat it as a prefix only format string. Then either...

[code]#EndStringFormat <<
#EndStringFormat <<%s[/code]
...would work & mean the same as...

[code]#EndStringChars <<[/code]
[quote name="Chris"]It is a nice syntax, but the problem is ambiguity. I've made ambiguity mistakes in the past so I've become very wary of them.[/quote]
...I don't know where the ambiguity is, by default, disallow commas from being part of an end string, but allow them to escape a comma or use single quotes to define the end string...

[code]FileAppend, << MY_END_STRING_HAS_A_`,_COMMA_IN_IT, c:\My Documents\Test.txt
Multiline
Text
MY_END_STRING_HAS_A_,_COMMA_IN_IT[/code]
...I'm not sure if the comma in the 2nd occurrence should or shouldn't be escaped, it's not on the same line as a command, but it might make more sense to leave it escaped for consistency or allow either. With single quotes...

[code]FileAppend, << 'MY_END_STRING_HAS_A_,_COMMA_IN_IT', c:\My Documents\Test.txt
Multiline
Text
MY_END_STRING_HAS_A_,_COMMA_IN_IT[/code]

[quote name="Chris"]Though something like this is still possible because it's not ambiguous:

myVar =
<< Multiline
Text
END[/quote]
...maybe it's not ambiguous (but I don't see how the same line one is either, especially on this one, var = takes no other params), but it looks clunky to say var =, then <<
[quote name="Chris"]But if it would be done that way, it might as well be done with a simpler leading key-symbol such as the parentheses idea above.[/quote]
...I don't see how the parentheses would work, what if the Text has a closing parenthese? Should we escape all closing parentheses in the Text...um, no. An end string can be made unique on the spot, so you know it's not in the Text.

[quote name="Chris"]Thanks for your suggestion. Even though not adopted, it enriches those of us who don't know much PHP.[/quote]
...it should be adopted.

[quote name="Tekl"]the <<< could be escaped with `<<<.[/quote]
...escape it? why? ain't <<< or << unique enough? or do you mean be able to escape it within itself...

[code]var = << ...if that's what you mean, yes, I guess, people wanting to cause problems should be able to use the end string prefix inside itself. If you mean...

[code]var = `<< ...then no, escaping it here, just makes it look weird.

[quote name="Tekl"]Do you have understand, that also << ...yes, I don't think this has be stated clearly enough either...for the non-PHP & non-Perl among us, the <<
[code]<< << << ...<<
[quote name="Tekl"]You're right, a non-PHP-coder could have problems. What about using the known %-symbol?[/quote]
...% would almost definitely conflict with the current use of %. But also...

[quote name="Tekl"]myVar = %%%END%%%
bla bla
blubb blubb
%%%END%%%[/quote]
...the %'s or the <'s are just a prefix (& suffix on the % version) to indicate an end string, not to be used in the 2nd occurrence that is ending the string.

[quote name="Chris"]Very original ideas. I'll consider those, but might wind up using Jonny's paretheses idea since it's so simple and concise.[/quote]
...I still say using a closing parenthese is going to cause a conflict if the Text has one.

Going completely away from the end string idea...this was my 1st thought...

[code]FileAppend, begin, c:\My Documents\Test.txt
Multiline
Text
FileAppend, end[/code]
...all of that being literal code, use new keywords 'begin' & 'end' to begin & end the append. That only fixes this function, but you could use the same idea on any other function that accepts alot of text as input. Like MsgBox...

[code]MsgBox, begin
Multi-line
Message
Box
is easier than a bunch of `n's
MsgBox, end[/code]
...or...

[code]MsgBox, 3, Title, begin, 5
This
is
a
multi-line Message Box using the 2nd format.
MsgBox, end[/code]
...& before you say "that will break scripts that do use begin as the text to display" simply look for an end tag & if you don't find one, don't give an error, just revert to the old way & display the word begin...ditto for end, if you encounter an end tag without having seen a begin, display the word end, like it would now. Pretty much, any function that currently accepts a Text param, accept the words begin & end to designate a block to be that param. & if some functions accept multiple Text params, use begin1, end1, begin2, end2...

[code]MsgBox, 3, begin1, begin2, 5
Title
MsgBox, end1
This
is
a
multi-line Message Box using the 2nd format.
MsgBox, end2[/code]
...or really, accept this too...

[code]MsgBox, 3, begin, begin2, 5
Title
MsgBox, end
This
is
a
multi-line Message Box using the 2nd format.
MsgBox, end2[/code]
...or even...

[code]MsgBox, 3, begin2, begin, 5
This
is
a
multi-line Message Box using the 2nd format.
MsgBox, end
Title
MsgBox, end2[/code]
...match up the begins & ends, but don't require them in any order...begin without a number is ended by end, with a number the numbers must match.

I started writing this when Chris's "Very original ideas." post was the last post, I see other people have noticed the closing paren dilemma. Even if it has to be the beginning of the line, it's still not very unique...the Text could contain a closing paren on it's own line, say if you were using an ahk script to generate an ahk script. The end strings are unique (or can be made unique right when you're scripting) & so are the begin/end, begin2/end2, beginN/endN. Tho, I just thought, the begin/end combos need a place for flags...say %begin, means "parse for variables", the flag(s) would only be in the begin tag, so you would just use end or endN to end it. So then the syntax is FbeginN or could even be beginNF, where F is any flags & N is either not there or is a number. Perhaps the begin/end syntax could be overrideable as a define, then people could use anything...

#BeginFormat %fbegin%n
#EndFormat end%n

#BeginFormat begin%n%f
#EndFormat end%n


BoBo
  • Guests
  • Last active:
  • Joined: --
Interesting. Now I need a break/coffee. :lol:

jonny
  • Members
  • 2951 posts
  • Last active: Feb 24 2008 04:22 AM
  • Joined: 13 Nov 2004
Wow. Long post. Anywho, the closing paranthese isn't a problem. As they've said, only a ")" directly preceded by a real new line (not `n) would be taken as the close.

the Text could contain a closing paren on it's own line, say if you were using an ahk script to generate an ahk script.


You mean specifying a parenthese-enclosed multi-line inside a command, that, itself, generates a multi-line? This case would be far too rare to merit attention. Just use `n) In that case.

And, if you had to escape parentheses, you'd actually have to escape it twice, once for the multi-line syntax, and one for the parameter itself. That would get very confusing very fast. I like being able to set the prefix and suffix though, that's a good idea.

On another subject, throwing up too many ideas at once like that is not just confusing, but it's jumping ahead a little too far. State the ideas that seem best to you, or filter out the few that you think would be most applicable. As ideas develop to fruition, they can be extended or improved, but let's not try to do it all at once.

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
[quote]ambiguously long options should be at the end, like Text. Which would make his example work.[/quote]Yes I generally agree with that. FileAppend is an exception: its current parameter ordering is okay because there is a special 2-parameter mode inside file-read/write loops that benefits from the current ordering.

[quote]What is
 supposed to do?[/quote]To clarify, my counter-proposals are all based primarily on ease of implementation.  That is why the parenthesis and 
 tags appear beneath the line they belong to: it makes the parsing simple and fast.

[quote]...if you had a closing parenthese in the Text, you'd have to escape it too.
...I don't see how the parentheses would work, what if the Text has a closing parenthese? Should we escape all closing parentheses in the Text...um, no.
...I still say using a closing parenthese is going to cause a conflict if the Text has one.[/quote]Each parenthesis would be required to appear at the beginning of a line just like a brace. Thus, there would be no ambiguity (since variable names can't contain parentheses) and no need to escape anything.

[quote]Even if it has to be the beginning of the line, it's still not very unique...the Text could contain a closing paren on it's own line, say if you were using an ahk script to generate an ahk script.[/quote]If you still think so, I could use clarification.

[quote]...no, it shouldn't smash the continued lines together, then run it, it should run through it & add each line that isn't the end, to an internal (the ahk program itself, not the script) variable (resizing to fit), then when it gets to the end, use that variable as the Text, use it as a parameter to the internal function that does whatever.[/quote]That would be a lot more work (and code size) because scripts are not interpreted at runtime; that step is done during the loading as described [url=http://www.autohotkey.com/docs/misc/Performance.htm]here[/url].

[quote]Why is the line limited to 16383?[/quote]That limit was based on my original intent to make this a simple line-continuation mechanism, where lines get merged together immediately after being read from the disk. But I'll reconsider that in light of everything you've said.

[quote]...this time using <<% instead of << would mean "parse the text for variables", if there are different classes of things to parse for, use different flags, default no parsing, use exactly as is.[/quote]That's getting more complicated than I had in mind. I was hoping for a quick yet highly useful line continuation mechanism that would allow people to cut and paste literal text from anywhere and use it in a script without having to put in `n at the end of every line, etc.

[quote]An end string can be made unique on the spot, so you know it's not in the Text.[/quote]Yes that's a good point.

[quote]...% would almost definitely conflict with the current use of %. But also...[/quote]I'm starting to like the the % idea better, though it still has problems. The reason I like it is that %% in a script is never valid, so it's 100% certain that it marks something new. The << idea is not certain and requires logic to retreat and reconsider something to be literal whenever the ending marker is not found.

[quote]before you say "that will break scripts that do use begin as the text to display" simply look for an end tag & if you don't find one, don't give an error, just revert to the old way & display the word begin[/quote]That seems like a good system, but I wanted something easy to implement and small in code size. It would be easy if AHK were purely interpreted, and that's probably what you were assuming.

I really appeciate your input because I can now see some significant advantages to yours/Tekl's/Savage's ideas, namely: 1) No need for escaped commas because yours is on a per-parameter basis while mine was a raw line continuation mechanism that merges lines together the moment they are loaded; and 2) Yours is probably easier to use and more readable.

The main disadvantage: harder to implement and larger code size.