Recent

Author Topic: Multiline string constants  (Read 18140 times)

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Multiline string constants
« on: April 25, 2013, 10:35:16 pm »
Would it be possible to do thing like this STRINGIFY() in pascal?
Code: [Select]
#define STRINGIFY(A) #A

const GLchar* source = STRINGIFY(

                                     uniform sampler2D tex0;
                                     uniform sampler2D tex1;

                                     void main() {
                                         vec4 s1 = texture2D(tex0, gl_TexCoord[0].st);
                                         vec4 s2 = texture2D(tex1, gl_TexCoord[0].st + vec2(0.0625, 0.0625));
                                         gl_FragColor = mix(vec4(1, s1.g, s1.b, 0.5), vec4(s2.r, s2.g, 1, 0.5), 0.5);
                                     }

                                     );

There was some Delphi related discussion there:
http://stackoverflow.com/questions/1872503/how-to-assign-a-multiline-string-value-without-quoting-each-line
But it didn't seem like there's answer.

Basically it would simplify text/code insertion within code, and should do like:
Code: [Select]
s := DoSomeStringMagics(
  line1
  line2
);
convert into:
Code: [Select]
s := '  line1#13#10  line2';with spaces and line changes included.

edit: yay, 1000th post  :D
« Last Edit: April 25, 2013, 10:40:55 pm by User137 »

eny

  • Hero Member
  • *****
  • Posts: 1634
Re: Multiline string constants
« Reply #1 on: April 26, 2013, 12:07:07 am »
When it's a one off I always use something like notepad++ to quote the lines by use of regular expressions.
And if I need multi line texts that change frequently I either use an external file that is read at runtime, or add it as a resource at compilation time.
You could also use a data module and put TMemo's on it I guess.

edit: yay, 1000th post  :D
996 :)
All posts based on: Win10 (Win64); Lazarus 2.0.10 'stable' (x64) unless specified otherwise...

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9792
  • Debugger - SynEdit - and more
    • wiki
Re: Multiline string constants
« Reply #2 on: April 26, 2013, 12:17:55 am »
When it's a one off I always use something like notepad++ to quote the lines by use of regular expressions.

The Lazarus source editor has reg-ex too. So you can do that in Lazarus.

Even better, if you use 1.1/trunk: You can write (and store) pascal script macros, to quote and unquote the text.

And in 1.1, you can configure that pressing return inside a string, adds closing ' on the line (optional "+LineEnding", and opening ' on the next.

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: Multiline string constants
« Reply #3 on: April 26, 2013, 01:08:13 am »
I was hoping there was compiler directives that would allow this, but i guess not. I also remembered that my code should be compilable with Delphi aswell, so new FPC features wouldn't do. This is coming for game engine, so i do not want to demand these texts be required with executable. Currently they look like this:
https://code.google.com/p/nxpascal/source/browse/trunk/src/nxShaders.pas
Thankgod GLSL doesn't need line changes after ; because that would add another +#13 after each line. It's just not easy to move the shader code to separate file and back, when needed. When you want to for example show the shader to somebody else, and stripping all quotes and + marks away... Especially with 3D shaders (which in my case are still very simplistic), it can get very complicated.
« Last Edit: April 26, 2013, 01:12:20 am by User137 »

irfanbagus

  • Jr. Member
  • **
  • Posts: 73
Re: Multiline string constants
« Reply #4 on: April 26, 2013, 01:38:41 am »
for same problem i make my own tool to convert my glsl file to *.inc file with string constants. make me easy to edit glsl and make my pascal source cleaner. only need to call from batch file/shell script.

Code: [Select]
program txt2const;

{$mode objfpc}{$H+}

uses
  Classes, sysutils;

var
  Src,Dst: TStringList;
  I: Integer;
begin
  if Paramcount<3 then
  begin
    WriteLn;
    WriteLn(ExtractFileName(ParamStr(0))+' <source> <dest> <const name>');
    Exit;
  end;
  try
    Src:= TStringList.Create;
    Dst:= TStringList.Create;
    Src.LoadFromFile(ParamStr(1));
    Dst.Add(ParamStr(3)+': String = ');
    for I:=0 to Src.Count-2 do
      Dst.Add('  ' + QuotedStr(Src[I]) + '#13#10+');
    if Src.Count>1 then
      Dst.Add('  ' + QuotedStr(Src[Src.Count-1]) + ';');
    Dst.SaveToFile(ParamStr(2));
  finally
    Src.Free;
    Dst.Free;
  end;
end.
« Last Edit: April 26, 2013, 01:40:43 am by irfanbagus »

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: Multiline string constants
« Reply #5 on: October 20, 2013, 11:11:14 am »
And yet another tool that converts multiline text to a multiline string...

It's GUI, standalone...

Still would like to see this functionality [1] as an Edit/Paste special option inside the IDE (i.e. text on clipboard gets pasted as quoted string - multiline with line endings etc if needed)...
Perhaps using an .lpk but I guess I can always try and write a Pascalscript macro ;)

[1] Relevant code:
Code: [Select]
function PascalizeString(SourceString: string): string;
var
  i: integer;
  Target: TStringList;
begin
  Target:=TStringList.Create;
  try
    Target.Text:=SourceString;
    for i:=0 to Target.Count-1 do
    begin
      if i<Target.Count-1 then
        Target[i]:=QuotedStr(Target[i])+' + LineEnding +'
      else
        Target[i]:=QuotedStr(Target[i])+';';
    end;
    result:=Target.Text;
  finally
    Target.Free;
  end;
end;
« Last Edit: October 20, 2013, 12:09:11 pm by BigChimp »
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

Leledumbo

  • Hero Member
  • *****
  • Posts: 8746
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Multiline string constants
« Reply #6 on: October 20, 2013, 12:13:43 pm »
Quote
Still would like to see this functionality [1] as an Edit/Paste special option inside the IDE (i.e. text on clipboard gets pasted as quoted string - multiline with line endings etc if needed)...
Perhaps using an .lpk but I guess I can always try and write a Pascalscript macro ;)
Well, since you know the IDE quite well (I guess), why don't you add that functionality to the... refactoring menu perhaps?

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9792
  • Debugger - SynEdit - and more
    • wiki
Re: Multiline string constants
« Reply #7 on: October 20, 2013, 12:19:19 pm »
You can extend the IDE to do this, by adding a macro. (trunk/upcoming 1.2)
http://wiki.lazarus.freepascal.org/Editor_Macros_PascalScript

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: Multiline string constants
« Reply #8 on: October 20, 2013, 12:41:17 pm »
Quote
Still would like to see this functionality [1] as an Edit/Paste special option inside the IDE (i.e. text on clipboard gets pasted as quoted string - multiline with line endings etc if needed)...
Perhaps using an .lpk but I guess I can always try and write a Pascalscript macro ;)
Well, since you know the IDE quite well (I guess), why don't you add that functionality to the... refactoring menu perhaps?
Hi Leledumbo.... nah, I don't know the IDE that well at all TBH... I've just dabbled a bit with getting help files improved, really.

Refactoring menu would be possible, but a rightclick, paste special (a la MS Word, LibreOffice) would make more sense IMO.
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: Multiline string constants
« Reply #9 on: October 20, 2013, 12:42:01 pm »
You can extend the IDE to do this, by adding a macro. (trunk/upcoming 1.2)
http://wiki.lazarus.freepascal.org/Editor_Macros_PascalScript
Hi Martin,

Yes, I noticed your post about that, thanks.
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

BeniBela

  • Hero Member
  • *****
  • Posts: 905
    • homepage
Re: Multiline string constants
« Reply #10 on: October 20, 2013, 12:45:36 pm »
Or use the correct line breaks and fpc handles multi line string fine...
« Last Edit: October 20, 2013, 12:49:33 pm by BeniBela »

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: Multiline string constants
« Reply #11 on: October 21, 2013, 12:43:05 pm »
but I guess I can always try and write a Pascalscript macro ;)

Ok, trying to convert to a macro:
Code: [Select]
procedure PascalizeString(Source: string; var Target: TStringList);
var
  i: integer;
begin
  Target.Text:=Source;
  for i:=0 to Target.Count-1 do
  begin
    if i<Target.Count-1 then
      Target[i]:=QuotedStr(Target[i])+' + LineEnding +'
    else
      Target[i]:=QuotedStr(Target[i])+';';
  end;
end;

var
  i: integer;
  First,Last: TPoint;
  SelectionText: string;
  ResultList: TStringList;
begin
  // Make sure text is selected:
  if not Caller.SelAvail then exit;

  First := Caller.BlockBegin;
  Last := Caller.BlockEnd;
  // Switch around if backward selection:
  if (First.y > Last.y) or ((First.y = Last.y) and (First.x > Last.x)) then begin
    First := Caller.BlockEnd;
    Last := Caller.BlockBegin;
  end;
  // Copy over selected text
  ResultList:=TStringList.Create;
  try
    for i:=First to Last do
    begin
      if i=First then
        SelectionText:=Caller.Lines[i]
      else
        SelectionText:=SelectionText+LineEnding+Caller.Lines[i];
    end;
    PascalizeString(SelectionText,ResultList);
    Caller.CutToClipBoard; //Cut out original text
    ClipBoard.AsText:=ResultList.Text; //Assign our own variable
    Caller.PasteFromClipBoard;
  finally
    ResultList.Free;
  end;
end.
PascalScript doesn't seem to support tstringlist or I need to "register" support for it or something? How would I do that?

Of course, other suggestions for improvement of that copy/paste job above would be welcome ;)
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9792
  • Debugger - SynEdit - and more
    • wiki
Re: Multiline string constants
« Reply #12 on: October 21, 2013, 01:13:00 pm »
The pascalscript in the IDE is very limited, so yes currently no stringlist (cam be added, but a question of time, testing, platforms ...)

The wiki page lists all the available procedures.

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
Re: Multiline string constants
« Reply #13 on: September 19, 2021, 08:17:13 am »
hello,
old post but i have just found that you can use TStringList in pascalscript of Macro Editor in Lazarus.
But you must do few changes in the unit EMScriptClasses of macroscript component.
1 - in the uses add uPSR_classes, uPSC_classes units.
2 -In the function CompilerOnUses replace : 
Code: Pascal  [Select][+][-]
  1.     SIRegisterTObject(Sender);
  2.     //SIRegister_Std(Sender);    
 
with this :
Code: Pascal  [Select][+][-]
  1.     SIRegisterTObject(Sender);
  2.     SIRegister_Std(Sender);
  3.     SIRegister_Classes(Sender, true);  
     
   
3 - In the constructor TEMSTPSExec.Create replace :
Code: Pascal  [Select][+][-]
  1.   RIRegisterTObject(FCLassImp);
  2.   // ## RIRegister_Std(CL);  
with this
Code: Pascal  [Select][+][-]
  1.   RIRegisterTObject(FCLassImp);
  2.   RIRegister_Std(FCLassImp);
  3.   RIRegister_Classes(FCLassImp,true);    


and now you should be able to use tstringlist in your pascalscript scripts of the lazarus Macro Editor.

I did finally succeed in getting the BigChimp's (r.i.p) macro to work with some changes :
 
Code: Pascal  [Select][+][-]
  1. const lineEndingInt =  #13#10;
  2.          lineEndingStr = '#13#10';
  3.  
  4. function QuotedStr(const S: string): string;
  5. var
  6.   I: Integer;
  7. begin
  8.   Result := S;
  9.   for I := Length(Result) downto 1 do
  10.     if Result[I] = '''' then Insert('''', Result, I);
  11.   Result := '''' + Result + '''';
  12. end;
  13.  
  14. procedure PascalizeString(Source: string; var Target: TStringList);
  15. var
  16.   i: integer;
  17. begin
  18.   Target.Text:=Source;
  19.   for i:=0 to Target.Count-1 do
  20.   begin
  21.     if i<Target.Count-1 then
  22.       Target[i]:=QuotedStr(Target[i])+ ' + ' + LineEndingStr + ' +'
  23.     else
  24.       Target[i]:=QuotedStr(Target[i])+';';
  25.   end;
  26. end;
  27.  
  28. var
  29.   i: integer;
  30.   First,Last: TPoint;
  31.   s: string;
  32.   SelectionText: string;
  33.   ResultList: TStringList;
  34. begin
  35.   // Make sure text is selected:
  36.   if not Caller.SelAvail then exit;
  37.  
  38.   First := Caller.BlockBegin;
  39.   Last := Caller.BlockEnd;
  40.   // Switch around if backward selection:
  41.   if (First.y > Last.y) or ((First.y = Last.y) and (First.x > Last.x)) then begin
  42.     First := Caller.BlockEnd;
  43.     Last := Caller.BlockBegin;
  44.   end;
  45.   // Copy over selected text
  46.   ResultList:=TStringList.Create;
  47.   try
  48.     for i:=First.y to Last.y do
  49.     begin
  50.       if i=First.y then
  51.         SelectionText:= copy(Caller.Lines[i-1],
  52.         First.x, length(Caller.Lines[i-1])- First.x +1)
  53.       else
  54.         SelectionText:=SelectionText+ LineEndingInt + Caller.Lines[i-1];
  55.     end;
  56.     PascalizeString(SelectionText,ResultList);
  57.     Caller.CutToClipBoard; //Cut out original text
  58.     ClipBoard.AsText:=ResultList.Text; //Assign our own variable
  59.     Caller.PasteFromClipBoard;
  60.   finally
  61.     ResultList.Free;
  62.   end;
  63. end.              
                   

Works on Windows 10  Lazarus 2.0.12 fpc 3.2 and linux Ubuntu 20.04 LTS Lazarus 2.1.0 fpc 3.3.1
on linux modify the beginning of the macro with this :
Code: Pascal  [Select][+][-]
  1. const lineEndingInt =  #10;
  2.       lineEndingStr = '#10';

in attachments :
2 - Use of the MultilineStr Macro in Lazarus IDE (click on image to see animation).

Friendly, J.P
« Last Edit: September 19, 2021, 08:26:01 am by Jurassic Pork »
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

 

TinyPortal © 2005-2018