I wish the Delphi language supported multi-line strings
Posted by jpluimers on 2018/06/21
Very often, I see people ask for how to embed multi-line strings in a Delphi source file.
The short answer is: you can’t.
The long answer is: you can’t and if you want you have to hack your way around.
The answer should be: just like any of these languages that do support multiline strings:
- Python
- embed them with triple single quotes or triple double quotes: [WayBack] 3. An Informal Introduction to Python — Python 3.6.1 documentation – strings
- JavasScript
- as of ECMAScript 6, you can use backticks: [WayBack] Template literals – JavaScript | MDN
- Ruby
- Via the Here Documents syntax: [Archive.is] File: literals.rdoc [Ruby 2.2.0] – Here Documents
- C#
- By prepending the opening double quote of a string with @: [Archive.is] Code: Generating Multiline String Literals (Visual C#)
Many languages support this through a feature called HEREDOC.
Now in Delphi and other languages like Java are building ugly workarounds like for instance this one: [WayBack] RAD Studio Tip: Using resource scripts to organize project dependencies. – Chapman World.
–jeroen
Steven said
None of the solutions I have come across really does a great job, other than embedding resources. Unfortunately that is also a pain to work with. Just spitballing here, but maybe what we need is a better method of controlling and editing these resources? I liked the approach that Chapman was making with this TFormResource component, but it stores the data internally into the form as binary, which really stinks when it comes to looking at a diff between versions. Maybe what is needed is a component that manages the resources/rc file for you? The component wouldn’t have much runtime code, just enough to load the resource and return it to the application. Resources would be separate files, so versioning would be simpler.
jpluimers said
Over the last decade or so, I have started moving more and more things from DFM to Pascal source. It makes more stable code. But I like your train of thought, so I will likely do some research into the direction of build tooling.
Michał Rajewicz said
You may check my OLTypes Library.
It’s distributed under the MIT License (so basically free to use).
https://bitbucket.org/mihoor/oltypes/wiki/Home
Here’s an example of line manipulation in a string (interchangeable) variable:
var
s: OLString;
begin
s.LineAdd(‘First line’);
s.LineAdd(‘Third line’); //Oops!
s.LineInsertAt(1, ‘Second line’); //Corrected!
s.Lines[4] := ‘Fifth line’;
ShowMessage(s);
end;
jpluimers said
This does not solve the problem at hand.
Russell Weetch (@RussellWeetch) said
This has been a request since back in the Delphi 1 days IIRC. It would be a vey useful addition.
jpluimers said
Even before that (;
Ralf St said
Also you can put multilie text at designtime in a component which stores tstrings like a memo. Thet text will be stored in dfm. I use this to store firebird sql for buliding / modifiing stored procedures and triggers. A very simple copy and past action. I use for that an tibcsript component, it has something like 10000 lines sql inside. Everytime my program detects that its version number is higer then the number stored in the database this whole script will be executed.
jpluimers said
Which means refactoring, search and diff tools handle it badly because of the DFM format.
Eli M. said
For lots of text I just use a TMemo. You can also use a TFDMemTable w/ 1 field.
jpluimers said
The problem with those is that hardly any of the Delphi tooling (including 3rd party) supports refactoring DFM files or stuff inside databases.
This apart from DFM files splitting strings their own way, so it is not easy to get them line by line on the DFM level (for instance when comparing versions). This is worse when you store stuff in a database (even an in-memory table).
rvelthuis said
How often do you need that really? And multiline strings can easily be done using pseudo-concatenation, i.e.
'one' + 'two'
. If you do that on separate lines, all is well. The newer IDEs even help you with that, by adding the quotes and plus sign for you once you start a new line, when typing a string. I don’t quite see the need for something like in Python or C#.rvelthuis said
And no need to “hack”. OK, you are not “embedding” per se, unless you use resourcestrings the same way. The same syntax applies. Actually, multiline strings have their problems too, especially WRT leading spaces. The pseudo-concatenation syntax is much clearer in that respect, since lines are still surrounded by quotes.
edwinyzh said
‘one’ + ‘two’ is two ugly for multi-line SQL, XML or JSON strings.
rvelthuis said
@Edwinyzh: Why is it ugly? If formatted properly, it puts every line on its own line. And with “formatted properly”, I don’t mean lines that go well beyond the right edge of the editor. That is not ugly, it is very readable. Much more readable than a multiline string with its non-fitting indentation.
jpluimers said
Lately I need it more often, as I have been moving truckloads of resources and DFM properties to plain Delphi code because it is way easier to refactor.
ruurd said
Mwah. The whole HEREDOC thing is some sort of a lexer kludge to begin with. Did you ever use them in a piece of software where you really could not get it done otherwise? Me neither…
jpluimers said
Good point. Thanks for pointing out the grass is not always greener (: