Recent

Author Topic: Split Name Quiz (Pascal Skill Challenge)  (Read 2191 times)

x2nie

  • Hero Member
  • *****
  • Posts: 515
  • Impossible=I don't know the way
    • impossible is nothing - www.x2nie.com
Split Name Quiz (Pascal Skill Challenge)
« on: September 13, 2022, 07:20:34 pm »


Hi all,
Want do a brain sport?
Show your pascal programming skill here, it might be fun !


The task:
1) Create a function that do split component's name (a string) into several lines (another string separated with #13).
  eg: 'MainMenu1' ==> 'Main'#13'Menu1'.
2) Maximum width per line is 16 chars (100 pixels), with still meaningful per line, if possible.
  eg. OenPictureDialog2 ==> OpenPicture#13Dialog2, or Open#13PictureDialog2
3) Maximum lines count is 4 lines


Easy, isn't it?


I attached a Lazarus program that you can use as startup. But you can create your own program too.


---------------------------------
Story behind:
Why it is useful, or what benefit for Lazarus?
Well, it has been decades that any iconic component dropped in TDataModule that has long name,
and if there are many components, they seem crowded, hard to find, can't be categorized.
Now, having TDatamodule source-code (the Lazarus), we have a chance to make this situation
better.


The only problem is currently we have no function for splitting component name in good proportion.


If you only need the sample names, here is a list I used:
Code: [Select]

Memo1
MainMenu1
PopupMenu2
MenuItem3
TrayIcon4
Timer5
IdleTimer6
ApplicationProperties7
ImageList8
OpenDlg9
SaveDlg10
SelectDirectoryDlg11
ColorDlg12
FontDlg13
FindDlg14
ReplaceDlg15
TaskDlg16
OpenPictureDlg17
SavePictureDlg18
CalendarDlg19
CalculatorDlg20
Field21
StringField22
SmallintField23
LongintField24
WordField25
BooleanField26
FloatField27
CurrencyField28
BCDField29
DateField30
TimeField31
DateTimeField32
BytesField33
VarBytesField34
AutoIncField35
BlobField36
MemoField37
GraphicField38
WideStringField39
LargeintField40
VariantField41
GuidField42
FMTBCDField43
WideMemoField44
IntegerField45
ActionList46
LazCompQueue47
HTMLHelpDatabase48
HTMLBrowserHelpViewer49
PopupNotifier50
AsyncProcess51
XMLPropStorage52
IniPropStorage53
JSONPropStorage54
DataSource55
BufDataset56
CSVDataset57
SimpleIPCClient58
SimpleIPCServer59
XMLConfig60
EventLog61
Process62
SQLQuery63
SQLTransaction64
SQLScript65
SQLConnector66
MSSQLConn67
SybaseConn68
PQConn69
PQTEventMonitor70
OracleConn71
ODBCConn72
MySQL40Conn73
MySQL41Conn74
MySQL50Conn75
MySQL51Conn76
MySQL55Conn77
MySQL56Conn78
MySQL57Conn79
MySQL80Conn80
SQLite3Conn81
IBConn82
FBAdmin83
FBEventMonitor84
SQLDBLibraryLoader85
IDEDlgLayoutStorage86
ProcessUTF887
Carpet88
CarpetLabel89
CarpetImage90
LuiButton91
LuiGroupBox92
Button93
MyButton94
MyGroupBox95
Button96
GroupBox97
SynGutterPartList98
SynGutterSeparator99
SynGutterCodeFolding100
SynGutterLineNumber101
SynGutterChanges102
SynGutterMarks103
SynCompletion104
SynAutoComplete105
SynMacroRecorder106
SynExporterHTML107
SynPluginSyncroEdit108
SynPasSyn109
SynFreePascalSyn110
SynCppSyn111
SynJavaSyn112
SynJScriptSyn113
SynPerlSyn114
SynHTMLSyn115
SynXMLSyn116
SynLFMSyn117
SynDiffSyn118
SynUNIXShellScriptSyn119
SynCssSyn120
SynPHPSyn121
SynTeXSyn122
SynSQLSyn123
SynPythonSyn124
SynVBSyn125
SynAnySyn126
SynMultiSyn127
SynBatSyn128
SynIniSyn129
SynPoSyn130
Bitmap32List131
FPHTTPClient132
FPHttpServer133
HTMLDatasetContentProducer134
HTMLSelectProducer135
HTMLDatasetSelectProducer136
HTMLEntityProducer137
HTMLPageProducer138
HTMLDatasetFormShowProducer139
HTMLDatasetFormEditProducer140
HTMLDatasetFormGridProducer141
WebdataInputAdaptor142
FPWebDataProvider143
SQLDBWebDataProvider144
ExtJSJSonWebdataInputAdaptor145
ExtJSJSONDataFormatter146
ExtJSXMLWebdataInputAdaptor147
ExtJSXMLDataFormatter148
JSONRPCHandler149
JSONRPCDispatcher150
SessionJSONRPCDispatcher151
JSONRPCContentProducer152
ExtDirectDispatcher153
ExtDirectContentProducer154
OAuth2Handler155
FPOAuth2IniStore156
When you were logged in, you can see attachments.
Lazarus Github @ UbuntuCinnamon-v22.04.1 + LinuxMintDebianEdition5

x2nie

  • Hero Member
  • *****
  • Posts: 515
  • Impossible=I don't know the way
    • impossible is nothing - www.x2nie.com
Re: Split Name Quiz (Pascal Skill Challenge)
« Reply #1 on: September 13, 2022, 07:31:35 pm »
my latest split name function is:
Code: Pascal  [Select][+][-]
  1.  
  2. function isUppercase(s:string): boolean;
  3. begin
  4.   result := uppercase(s) = s;
  5. end;
  6.  
  7.  
  8. function isLowercase(s:string): boolean;
  9. begin
  10.   result := lowercase(s) = s;
  11. end;
  12.  
  13.  
  14. function splitName(s:string):string;
  15. var ret : string; //result
  16. var i : integer;
  17.    function nextIsLowercase:boolean;
  18.    var c : string;
  19.    begin
  20.      c := copy(s, i+1,1);
  21.      result := (c <> EmptyStr) and isLowerCase(c);
  22.    end;
  23.  
  24.  
  25. var
  26.   c : char;
  27. begin
  28.   ret := '';
  29.   for i := 1 to length(s) do
  30.   begin
  31.     c := s[i];
  32.     if (i > 1) and isUppercase(c) and nextIsLowercase() then
  33.        ret := ret + #13;
  34.     ret := ret + c;
  35.   end;
  36.   result := ret;
  37. end;    
  38.  

come on, guys.
We can avoid crowded TDataModule by flipping the component names. Don't we?
When you were logged in, you can see attachments.
Lazarus Github @ UbuntuCinnamon-v22.04.1 + LinuxMintDebianEdition5

x2nie

  • Hero Member
  • *****
  • Posts: 515
  • Impossible=I don't know the way
    • impossible is nothing - www.x2nie.com
Re: Split Name Quiz (Pascal Skill Challenge)
« Reply #2 on: September 14, 2022, 08:54:59 am »
well, I found that split with space is the best choice so far.
so the same line spaces need to be re-join soon
When you were logged in, you can see attachments.
Lazarus Github @ UbuntuCinnamon-v22.04.1 + LinuxMintDebianEdition5

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2065
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Split Name Quiz (Pascal Skill Challenge)
« Reply #3 on: September 14, 2022, 11:14:30 am »
I assume that I do fail (max 4 * "split") but anyway I like to show my approach:
Code: Pascal  [Select][+][-]
  1. program CustomSplit;
  2.  
  3. {$IFDEF MSWINDOWS}
  4. {$APPTYPE CONSOLE}
  5. {$R *.res}
  6. {$ENDIF}
  7.  
  8. // beautify a string by putting a space on logical positions
  9. // warning: limited to a-z and 0-9 (!)
  10. // written in a hurry by KodeZwerg 2022 for forum.lazarus.freepascal.org
  11. function PrettyString(const AString: AnsiString; const Force: Boolean = False): AnsiString;
  12.   function IsUpper(const AChar: AnsiChar): Boolean; inline;
  13.   begin
  14.     Result := AChar in ['A'..'Z'];
  15.   end;
  16.   function IsLower(const AChar: AnsiChar): Boolean; inline;
  17.   begin
  18.     Result := AChar in ['a'..'z'];
  19.   end;
  20.   function IsNumber(const AChar: AnsiChar): Boolean; inline;
  21.   begin
  22.     Result := AChar in ['0'..'9'];
  23.   end;
  24. var
  25.   LCopy, LOutput: AnsiString;
  26.   LLen, i: Integer;
  27. begin
  28.   Result := AString;
  29.   // only work on strings that are longer than 16 chars, except you force it
  30.   if ((not Force) and (Length(AString) < 17)) then
  31.     Exit;
  32.   LCopy := AString;
  33.   LLen := Length(LCopy);
  34.   LOutput := '';
  35.   for i := 1 to LLen do
  36.     begin
  37.       if ( (Pred(i) > 0) and (Succ(i) <= LLen) and (IsLower(LCopy[Pred(i)])) and (IsUpper(LCopy[i])) ) then
  38.         LOutput := LOutput + ' ' + LCopy[i]
  39.       else
  40.       if ( (Pred(i) > 0) and (Succ(i) <= LLen) and (IsLower(LCopy[Pred(i)])) and (IsNumber(LCopy[i])) ) then
  41.         LOutput := LOutput + ' ' + LCopy[i]
  42.       else
  43.         LOutput := LOutput + LCopy[i];
  44.     end;
  45.   Result := LOutput;
  46. end;
  47.  
  48. var
  49.   s: AnsiString;
  50. begin
  51.   s := 'HTMLDatasetFormGridProducer14';
  52.   WriteLn(s);
  53.   s := PrettyString(s, True);
  54.   WriteLn(s);
  55.   s := 'ExtJSJSonWebdataInputAdaptor14';
  56.   WriteLn(s);
  57.   s := PrettyString(s, True);
  58.   WriteLn(s);
  59.   {$IFDEF MSWINDOWS}
  60.   ReadLn;
  61.   {$ENDIF}
  62. end.
Have a nice day!

//updated with y.ivanov good suggestion
« Last Edit: September 14, 2022, 12:07:43 pm by KodeZwerg »
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

alpine

  • Hero Member
  • *****
  • Posts: 1064
Re: Split Name Quiz (Pascal Skill Challenge)
« Reply #4 on: September 14, 2022, 11:31:34 am »
Code: Pascal  [Select][+][-]
  1.     case AChar of
  2.       'a'..'z': Result := True;
  3.       else
  4.         Result := False;
  5.     end;

might be just simply:
Code: Pascal  [Select][+][-]
  1. Result := AChar in ['a'..'z'];
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2065
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Split Name Quiz (Pascal Skill Challenge)
« Reply #5 on: September 14, 2022, 11:32:39 am »
Ps: In attachment my Results:
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2065
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Split Name Quiz (Pascal Skill Challenge)
« Reply #6 on: September 14, 2022, 11:33:35 am »
Code: Pascal  [Select][+][-]
  1.     case AChar of
  2.       'a'..'z': Result := True;
  3.       else
  4.         Result := False;
  5.     end;

might be just simply:
Code: Pascal  [Select][+][-]
  1. Result := AChar in ['a'..'z'];
You are correct, welcome to the string party  O:-)
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

x2nie

  • Hero Member
  • *****
  • Posts: 515
  • Impossible=I don't know the way
    • impossible is nothing - www.x2nie.com
Re: Split Name Quiz (Pascal Skill Challenge)
« Reply #7 on: September 14, 2022, 02:16:23 pm »
I assume that I do fail (max 4 * "split") but anyway I like to show my approach:
...
Have a nice day!

//updated with y.ivanov good suggestion


No, @KodeZwerg, you didn't yet exceeded the max limit (4 lines).
It just need another function function to join them.


In my experiment, "Ext JSJSon Webdata Input Adaptor 14" is actually drawn as 3 lines within 100 pixels width per-line.
But you failed with names prefixed with JSONRPCxxxx (see attachment)


Anyway, Awesome code ! Yours is lot better than mine. I forgot much of pascal syntax due I been working with Python & JS daily.
thanks you @y.ivanov too.


---
my function to join the separated string by space:
Code: Pascal  [Select][+][-]
  1.  
  2.  
  3. function canBeALine(s:string; maxLength:integer; Canvas:TCanvas=nil; maxWidth:integer=90):Boolean;
  4. // test if the string occupied to be a single line.
  5. begin
  6.   if (canvas <> nil) then
  7.      result := Canvas.TextWidth(s) <= maxWidth
  8.   else
  9.      result := length(s) <= maxLength;
  10. end;
  11.  
  12.  
  13. function toLines(s:string; maxLength:integer; Canvas:TCanvas=nil; maxWidth:integer=90): string;
  14. var ss : TStringArray;
  15.   i : integer;
  16.   aline : string;
  17. begin
  18.   result := '';
  19.   aline := '';
  20.   ss := s.split(' ');
  21.   //for i := 0 to length(ss) - 1 do
  22.   //    writeln(ss[i]);
  23.   writeln('---------', s);
  24.  
  25.  
  26.   for i := 0 to length(ss) - 1 do
  27.   begin
  28.     //if length(aline + ss[i]) <= maxLength then
  29.     if canBeALine(aline + ss[i], maxLength, canvas, maxWidth) then
  30.        aline := aline + ss[i]
  31.     else
  32.     begin
  33.       if result <> EmptyStr then
  34.          result := result + #13;
  35.       result := result + aline;
  36.       aline := ss[i];
  37.     end;
  38.     if (i = length(ss) -1) and (aline <> EmptyStr) then
  39.        result := result + #13 + aline;
  40.   end;
  41.   writeln('#======> ', result.replace(#13, '|'), #13);
  42. end;                
  43.  


output:

---------Ext JSJSon Webdata Input Adaptor 145
#======> ExtJSJSon|WebdataInput|Adaptor145


Have a nice day ! 8-)
When you were logged in, you can see attachments.
Lazarus Github @ UbuntuCinnamon-v22.04.1 + LinuxMintDebianEdition5

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2065
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Split Name Quiz (Pascal Skill Challenge)
« Reply #8 on: September 14, 2022, 02:37:25 pm »
It just need another function function to join them.
When allowed, then "uses SysUtils" and ->
Code: Pascal  [Select][+][-]
  1. s.Replace(' ', '', [rfReplaceAll]);

I did watched your image and will see if I update code but i like to ask if it is allowed to put "uses" in code?
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

x2nie

  • Hero Member
  • *****
  • Posts: 515
  • Impossible=I don't know the way
    • impossible is nothing - www.x2nie.com
Re: Split Name Quiz (Pascal Skill Challenge)
« Reply #9 on: September 14, 2022, 03:18:01 pm »
yes, you can uses any units.
In fact we will place/call the functions within Designer (lazarus/designer.pp),
.. and it uses SysUtils already. so that is accepted.
When you were logged in, you can see attachments.
Lazarus Github @ UbuntuCinnamon-v22.04.1 + LinuxMintDebianEdition5

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2065
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Split Name Quiz (Pascal Skill Challenge)
« Reply #10 on: September 14, 2022, 03:49:53 pm »
Code: Pascal  [Select][+][-]
  1. var
  2.   LCopy, LOutput: AnsiString;
  3.   LLen, i: Integer;
  4. begin
  5.   Result := AString;
  6.   LCopy := AString;
  7.   LLen := Length(LCopy);
  8.   LOutput := '';
  9.   for i := 1 to LLen do
  10.     begin
  11.       if ( (Pred(i) > 0) and (Succ(i) < LLen) and (IsUpper(LCopy[i])) and (IsLower(LCopy[Succ(i)])) ) then
  12.         LOutput := LOutput + ' ' + LCopy[i]
  13.       else
  14.       if ( (Pred(i) > 0) and (IsLower(LCopy[Pred(i)])) and (IsUpper(LCopy[i])) ) then
  15.         LOutput := LOutput + ' ' + LCopy[i]
  16.       else
  17.       if ( (Pred(i) > 0) and (IsLower(LCopy[Pred(i)])) and (IsNumber(LCopy[i])) ) then
  18.         LOutput := LOutput + ' ' + LCopy[i]
  19.       else
  20.         LOutput := LOutput + LCopy[i];
  21.     end;
  22.   Result := LOutput;
  23. end;
  24.  
Would that be enough to fix your issue?
Else i would need to do a real split afterwards and copy string back together with limit of 16 chars max per "space"
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

x2nie

  • Hero Member
  • *****
  • Posts: 515
  • Impossible=I don't know the way
    • impossible is nothing - www.x2nie.com
Re: Split Name Quiz (Pascal Skill Challenge)
« Reply #11 on: September 14, 2022, 04:04:43 pm »
let me try ..
When you were logged in, you can see attachments.
Lazarus Github @ UbuntuCinnamon-v22.04.1 + LinuxMintDebianEdition5

x2nie

  • Hero Member
  • *****
  • Posts: 515
  • Impossible=I don't know the way
    • impossible is nothing - www.x2nie.com
Re: Split Name Quiz (Pascal Skill Challenge)
« Reply #12 on: September 14, 2022, 04:40:35 pm »
Yes ! it works like a charm  8-)
(see the attachment)


All names are wrapped in less 3 lines within 100 pixels per line.


In case someone wanna try, here is my complete demo source code:
Code: Pascal  [Select][+][-]
  1.  
  2. unit unit2;
  3. //https://forum.lazarus.freepascal.org/index.php/topic,60565.0.html
  4.  
  5.  
  6. {$mode ObjFPC}{$H+}
  7.  
  8.  
  9. interface
  10.  
  11.  
  12. uses
  13.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls;
  14.  
  15.  
  16. type
  17.  
  18.  
  19.   { TForm2 }
  20.  
  21.  
  22.   TForm2 = class(TForm)
  23.     dummyImg: TImage;
  24.     FinalName: TMemo;
  25.     Label1: TLabel;
  26.     Label2: TLabel;
  27.     PaintBox1: TPaintBox;
  28.     Panel1: TPanel;
  29.     Panel2: TPanel;
  30.     RadioGroup1: TRadioGroup;
  31.     SelectedName: TLabeledEdit;
  32.     ListBox1: TListBox;
  33.     SplittedName: TLabeledEdit;
  34.     procedure FormCreate(Sender: TObject);
  35.     procedure ListBox1Click(Sender: TObject);
  36.     procedure PaintBox1Paint(Sender: TObject);
  37.   private
  38.     FComponentName:string;
  39.     FFinalName : string;
  40.   public
  41.  
  42.  
  43.   end;
  44.  
  45.  
  46. var
  47.   Form2: TForm2;
  48.  
  49.  
  50. implementation
  51.  
  52.  
  53. {$R *.lfm}
  54.  
  55.  
  56. { TForm2 }
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63. function toLines(s:string; maxLength:integer; Canvas:TCanvas=nil; maxWidth:integer=90): string;
  64.   function canBeALine(s2:string):Boolean;
  65.   begin
  66.     if (canvas <> nil) then
  67.        result := Canvas.TextWidth(s2) <= maxWidth
  68.     else
  69.        result := length(s2) <= maxLength;
  70.   end;
  71. var ss : TStringArray;
  72.   i : integer;
  73.   aline : string;
  74. begin
  75.   result := '';
  76.   aline := '';
  77.   ss := s.split(' ');
  78.   //for i := 0 to length(ss) - 1 do
  79.   //    writeln(ss[i]);
  80.   writeln('---------', s);
  81.  
  82.  
  83.   for i := 0 to length(ss) - 1 do
  84.   begin
  85.     //if length(aline + ss[i]) <= maxLength then
  86.     if canBeALine(aline + ss[i]) then
  87.        aline := aline + ss[i]
  88.     else
  89.     begin
  90.       if result <> EmptyStr then
  91.          result := result + #13;
  92.       result := result + aline;
  93.       aline := ss[i];
  94.     end;
  95.     if (i = length(ss) -1) and (aline <> EmptyStr) then
  96.        result := result + #13 + aline;
  97.   end;
  98.   writeln('#======> ', result.replace(#13, '|'), #13);
  99. end;
  100.  
  101.  
  102. // beautify a string by putting a space on logical positions
  103. // warning: limited to a-z and 0-9 (!)
  104. // written in a hurry by KodeZwerg 2022 for forum.lazarus.freepascal.org
  105. function PrettyString(const AString: AnsiString; const Force: Boolean = False): AnsiString;
  106.   function IsUpper(const AChar: AnsiChar): Boolean; inline;
  107.   begin
  108.     Result := AChar in ['A'..'Z'];
  109.   end;
  110.   function IsLower(const AChar: AnsiChar): Boolean; inline;
  111.   begin
  112.     Result := AChar in ['a'..'z'];
  113.   end;
  114.   function IsNumber(const AChar: AnsiChar): Boolean; inline;
  115.   begin
  116.     Result := AChar in ['0'..'9'];
  117.   end;
  118. {ver 1 -----------------------------
  119. var
  120.   LCopy, LOutput: AnsiString;
  121.   LLen, i: Integer;
  122. begin
  123.   Result := AString;
  124.   // only work on strings that are longer than 16 chars, except you force it
  125.   if ((not Force) and (Length(AString) < 17)) then
  126.     Exit;
  127.   LCopy := AString;
  128.   LLen := Length(LCopy);
  129.   LOutput := '';
  130.   for i := 1 to LLen do
  131.     begin
  132.       if ( (Pred(i) > 0) and (Succ(i) <= LLen) and (IsLower(LCopy[Pred(i)])) and (IsUpper(LCopy[i])) ) then
  133.         LOutput := LOutput + ' ' + LCopy[i]
  134.       else
  135.       if ( (Pred(i) > 0) and (Succ(i) <= LLen) and (IsLower(LCopy[Pred(i)])) and (IsNumber(LCopy[i])) ) then
  136.         LOutput := LOutput + ' ' + LCopy[i]
  137.       else
  138.         LOutput := LOutput + LCopy[i];
  139.     end;
  140.   Result := LOutput;
  141. end;}
  142. var
  143.   LCopy, LOutput: AnsiString;
  144.   LLen, i: Integer;
  145. begin
  146.   Result := AString;
  147.   LCopy := AString;
  148.   LLen := Length(LCopy);
  149.   LOutput := '';
  150.   for i := 1 to LLen do
  151.     begin
  152.       if ( (Pred(i) > 0) and (Succ(i) < LLen) and (IsUpper(LCopy[i])) and (IsLower(LCopy[Succ(i)])) ) then
  153.         LOutput := LOutput + ' ' + LCopy[i]
  154.       else
  155.       if ( (Pred(i) > 0) and (IsLower(LCopy[Pred(i)])) and (IsUpper(LCopy[i])) ) then
  156.         LOutput := LOutput + ' ' + LCopy[i]
  157.       else
  158.       if ( (Pred(i) > 0) and (IsLower(LCopy[Pred(i)])) and (IsNumber(LCopy[i])) ) then
  159.         LOutput := LOutput + ' ' + LCopy[i]
  160.       else
  161.         LOutput := LOutput + LCopy[i];
  162.     end;
  163.   Result := LOutput;
  164. end;
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171. const
  172.   ATOMS : array [0..3] of string = (
  173.         'JSCRIPT', 'JSON', 'EXTJS', 'XML'
  174.   );
  175. function getAtom(s:string):string;
  176. var i :integer;
  177. begin
  178.   s := uppercase(s);
  179.   for i := 0 to length(ATOMS) -1 do
  180.   if pos(ATOMS[i], s) = 1 then
  181.      exit(ATOMS[i]);
  182.   result := EmptyStr;
  183. end;
  184.  
  185.  
  186.  
  187.  
  188.  
  189.  
  190. function splitName(s:string):UnicodeString;
  191.  
  192.  
  193.   function IsUpper(const AChar: AnsiChar): Boolean; inline;
  194.   begin
  195.     Result := AChar in ['A'..'Z'];
  196.   end;
  197.   function IsLower(const AChar: AnsiChar): Boolean; inline;
  198.   begin
  199.     Result := AChar in ['a'..'z'];
  200.   end;
  201.   function IsNumber(const AChar: AnsiChar): Boolean; inline;
  202.   begin
  203.     Result := AChar in ['0'..'9'];
  204.   end;
  205.  
  206.  
  207. //const numbers = '0123456789';
  208. var ret : UnicodeString; //result
  209. var i : integer;
  210.    function nextIsLower:boolean;
  211.    var c : char;
  212.    begin
  213.      if i+1 > length(s) then exit(false);
  214.      c := s[i+1];
  215.      result := isLower(c);
  216.      //result := (c <> EmptyStr) and {(numbers.IndexOf(c)<=0)} not IsNumber(c) and IsLower(c);
  217.    end;
  218.  
  219.  
  220. var
  221.   c : char;
  222.   sep, atom : String;
  223. begin
  224.   //sep := #13;
  225.   //sep := utf8encode(#$00AD); //shoft hypenation
  226.   sep := ' '; //space
  227.   //sep := utf8encode(#$200B); //Zero-width space. https://en.wikipedia.org/wiki/Zero-width_space
  228.   //sep := utf8encode(#$200c); //Zero-width non-joiner. https://en.wikipedia.org/wiki/Zero-width_space
  229.   //sep := utf8encode(#$200d); //Zero-width joiner. https://en.wikipedia.org/wiki/Zero-width_space
  230.   ////sep := #$20#$0b;
  231.   ////sep := #$0b#$20;
  232.   //sep := #$200B;
  233.   ret := '';
  234.   //for i := 1 to length(s) do
  235.   i := 0;
  236.   while i < length(s) do
  237.   begin
  238.     inc(i);
  239.     c := s[i];
  240.     if (i > 1) then
  241.     begin
  242.       {atom := getAtom(copy(s,i,length(s)));
  243.       if atom <> emptyStr then
  244.       begin
  245.         ret := ret + sep + copy(s,i, length(atom)) + sep;
  246.         inc(i, length(atom));
  247.       end
  248.       else}
  249.       if isNumber(c) then
  250.       begin
  251.         if not isNumber(s[i-1]) then
  252.           ret := ret + sep
  253.       end
  254.       else if IsUpper(c) then
  255.       begin
  256.         if IsLower(s[i-1]) or nextIsLower() then
  257.          ret := ret + sep
  258.         else
  259.         begin
  260.           atom := getAtom(copy(s,i,length(s)));
  261.           if atom <> emptyStr then
  262.           begin
  263.             ret := ret + sep + copy(s,i, length(atom)) + sep;
  264.             inc(i, length(atom)-1);
  265.             continue;
  266.           end
  267.  
  268.  
  269.         end
  270.  
  271.  
  272.       end
  273.     end;
  274.     ret := ret + c;
  275.   end; //while
  276.   result := ret;
  277. end;
  278.  
  279.  
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288. procedure TForm2.ListBox1Click(Sender: TObject);
  289. begin
  290.   FComponentName := ListBox1.Items[ ListBox1.ItemIndex]; // original
  291.  
  292.  
  293.   if RadioGroup1.ItemIndex = 0 then
  294.      FComponentName := PrettyString(FComponentName)
  295.   else
  296.      FComponentName := splitName(FComponentName);
  297.  
  298.  
  299.   FFinalName := toLines(FComponentName, 13, PaintBox1.Canvas, 100);
  300.   PaintBox1.Invalidate;
  301.  
  302.  
  303.   SelectedName.Text:= ListBox1.Items[ ListBox1.ItemIndex];
  304.   SplittedName.Text:=FComponentName;
  305.   FinalName.Text:=FFinalName;
  306. end;
  307.  
  308.  
  309. procedure TForm2.FormCreate(Sender: TObject);
  310. begin
  311.   listBox1.Click;
  312. end;
  313.  
  314.  
  315. procedure TForm2.PaintBox1Paint(Sender: TObject);
  316. var
  317.   style : TTextStyle;
  318.   aRect : TRect;
  319. begin
  320.   style.Alignment:=taCenter;
  321.   style.SingleLine:=false;
  322.   style.Wordbreak:=true;
  323.   //style.SystemFont:=true;
  324.   style.EndEllipsis := true;
  325.   style.Opaque := true;
  326.   aRect:=PaintBox1.ClientRect;
  327.   PaintBox1.Canvas.Brush.Color:=clBtnFace;
  328.   PaintBox1.Canvas.TextRect(aRect,0,0, FFinalName,  style);
  329. end;
  330.  
  331.  
  332. end.
  333.  
  334.  
  335.  


Code: Pascal  [Select][+][-]
  1.  
  2. object Form2: TForm2
  3.   Left = 1465
  4.   Height = 443
  5.   Top = 286
  6.   Width = 694
  7.   Caption = 'Lazarus String Party'
  8.   ClientHeight = 443
  9.   ClientWidth = 694
  10.   OnCreate = FormCreate
  11.   LCLVersion = '2.2.3.0'
  12.   object ListBox1: TListBox
  13.     Left = 498
  14.     Height = 443
  15.     Top = 0
  16.     Width = 196
  17.     Align = alRight
  18.     Items.Strings = (
  19.       'MainMenu1'
  20.       'PopupMenu2'
  21.       'MenuItem3'
  22.       'TrayIcon4'
  23.       'Timer5'
  24.       'IdleTimer6'
  25.       'ApplicationProperties7'
  26.       'ImageList8'
  27.       'OpenDlg9'
  28.       'SaveDlg10'
  29.       'SelectDirectoryDlg11'
  30.       'ColorDlg12'
  31.       'FontDlg13'
  32.       'FindDlg14'
  33.       'ReplaceDlg15'
  34.       'TaskDlg16'
  35.       'OpenPictureDlg17'
  36.       'SavePictureDlg18'
  37.       'CalendarDlg19'
  38.       'CalculatorDlg20'
  39.       'Field21'
  40.       'StringField22'
  41.       'SmallintField23'
  42.       'LongintField24'
  43.       'WordField25'
  44.       'BooleanField26'
  45.       'FloatField27'
  46.       'CurrencyField28'
  47.       'BCDField29'
  48.       'DateField30'
  49.       'TimeField31'
  50.       'DateTimeField32'
  51.       'BytesField33'
  52.       'VarBytesField34'
  53.       'AutoIncField35'
  54.       'BlobField36'
  55.       'MemoField37'
  56.       'GraphicField38'
  57.       'WideStringField39'
  58.       'LargeintField40'
  59.       'VariantField41'
  60.       'GuidField42'
  61.       'FMTBCDField43'
  62.       'WideMemoField44'
  63.       'IntegerField45'
  64.       'ActionList46'
  65.       'LazCompQueue47'
  66.       'HTMLHelpDatabase48'
  67.       'HTMLBrowserHelpViewer49'
  68.       'PopupNotifier50'
  69.       'AsyncProcess51'
  70.       'XMLPropStorage52'
  71.       'IniPropStorage53'
  72.       'JSONPropStorage54'
  73.       'DataSource55'
  74.       'BufDataset56'
  75.       'CSVDataset57'
  76.       'SimpleIPCClient58'
  77.       'SimpleIPCServer59'
  78.       'XMLConfig60'
  79.       'EventLog61'
  80.       'Process62'
  81.       'SQLQuery63'
  82.       'SQLTransaction64'
  83.       'SQLScript65'
  84.       'SQLConnector66'
  85.       'MSSQLConn67'
  86.       'SybaseConn68'
  87.       'PQConn69'
  88.       'PQTEventMonitor70'
  89.       'OracleConn71'
  90.       'ODBCConn72'
  91.       'MySQL40Conn73'
  92.       'MySQL41Conn74'
  93.       'MySQL50Conn75'
  94.       'MySQL51Conn76'
  95.       'MySQL55Conn77'
  96.       'MySQL56Conn78'
  97.       'MySQL57Conn79'
  98.       'MySQL80Conn80'
  99.       'SQLite3Conn81'
  100.       'IBConn82'
  101.       'FBAdmin83'
  102.       'FBEventMonitor84'
  103.       'SQLDBLibraryLoader85'
  104.       'IDEDlgLayoutStorage86'
  105.       'ProcessUTF887'
  106.       'Carpet88'
  107.       'CarpetLabel89'
  108.       'CarpetImage90'
  109.       'LuiButton91'
  110.       'LuiGroupBox92'
  111.       'Button93'
  112.       'MyButton94'
  113.       'MyGroupBox95'
  114.       'Button96'
  115.       'GroupBox97'
  116.       'SynGutterPartList98'
  117.       'SynGutterSeparator99'
  118.       'SynGutterCodeFolding100'
  119.       'SynGutterLineNumber101'
  120.       'SynGutterChanges102'
  121.       'SynGutterMarks103'
  122.       'SynCompletion104'
  123.       'SynAutoComplete105'
  124.       'SynMacroRecorder106'
  125.       'SynExporterHTML107'
  126.       'SynPluginSyncroEdit108'
  127.       'SynPasSyn109'
  128.       'SynFreePascalSyn110'
  129.       'SynCppSyn111'
  130.       'SynJavaSyn112'
  131.       'SynJScriptSyn113'
  132.       'SynPerlSyn114'
  133.       'SynHTMLSyn115'
  134.       'SynXMLSyn116'
  135.       'SynLFMSyn117'
  136.       'SynDiffSyn118'
  137.       'SynUNIXShellScriptSyn119'
  138.       'SynCssSyn120'
  139.       'SynPHPSyn121'
  140.       'SynTeXSyn122'
  141.       'SynSQLSyn123'
  142.       'SynPythonSyn124'
  143.       'SynVBSyn125'
  144.       'SynAnySyn126'
  145.       'SynMultiSyn127'
  146.       'SynBatSyn128'
  147.       'SynIniSyn129'
  148.       'SynPoSyn130'
  149.       'Bitmap32List131'
  150.       'FPHTTPClient132'
  151.       'FPHttpServer133'
  152.       'HTMLDatasetContentProducer134'
  153.       'HTMLSelectProducer135'
  154.       'HTMLDatasetSelectProducer136'
  155.       'HTMLEntityProducer137'
  156.       'HTMLPageProducer138'
  157.       'HTMLDatasetFormShowProducer139'
  158.       'HTMLDatasetFormEditProducer140'
  159.       'HTMLDatasetFormGridProducer141'
  160.       'WebdataInputAdaptor142'
  161.       'FPWebDataProvider143'
  162.       'SQLDBWebDataProvider144'
  163.       'ExtJSJSonWebdataInputAdaptor145'
  164.       'ExtJSJSONDataFormatter146'
  165.       'ExtJSXMLWebdataInputAdaptor147'
  166.       'ExtJSXMLDataFormatter148'
  167.       'JSONRPCHandler149'
  168.       'JSONRPCDispatcher150'
  169.       'SessionJSONRPCDispatcher151'
  170.       'JSONRPCContentProducer152'
  171.       'ExtDirectDispatcher153'
  172.       'ExtDirectContentProducer154'
  173.       'OAuth2Handler155'
  174.       'FPOAuth2IniStore156'
  175.       'InternmentDataset'
  176.       'PatientScoreDataset'
  177.       'PatientScoreDatasource'
  178.       'DiagnosticsDatasource'
  179.       'DiagnosticsDatasource'
  180.       'PatientTransferRequestDataset'
  181.       'PatientTransferRequestDatasource'
  182.       'PatientProblemsDatasource'
  183.       'PrescriptionProfilesDataSet'
  184.       'PrescriptionProfilesDataSource'
  185.       'PendenciesDataSource'
  186.       'PendenciesDataSet'
  187.       'PendencyGroupDatasource'
  188.       'PendencyGroupDataset'
  189.     )
  190.     ItemHeight = 22
  191.     ItemIndex = 0
  192.     OnClick = ListBox1Click
  193.     TabOrder = 0
  194.   end
  195.   object SelectedName: TLabeledEdit
  196.     Left = 136
  197.     Height = 27
  198.     Top = 288
  199.     Width = 328
  200.     EditLabel.Height = 16
  201.     EditLabel.Width = 86
  202.     EditLabel.Caption = 'SelectedName'
  203.     EditLabel.ParentColor = False
  204.     Font.Name = 'Monospace'
  205.     LabelPosition = lpLeft
  206.     ParentFont = False
  207.     TabOrder = 1
  208.     Text = 'SelectedName'
  209.   end
  210.   object SplittedName: TLabeledEdit
  211.     Left = 136
  212.     Height = 27
  213.     Top = 320
  214.     Width = 328
  215.     EditLabel.Height = 16
  216.     EditLabel.Width = 85
  217.     EditLabel.Caption = 'Splitted Name'
  218.     EditLabel.ParentColor = False
  219.     Font.Name = 'Monospace'
  220.     LabelPosition = lpLeft
  221.     ParentFont = False
  222.     TabOrder = 2
  223.     Text = 'Splitted Name'
  224.   end
  225.   object Panel1: TPanel
  226.     Left = 40
  227.     Height = 136
  228.     Top = 56
  229.     Width = 424
  230.     BevelInner = bvLowered
  231.     BevelOuter = bvLowered
  232.     ClientHeight = 136
  233.     ClientWidth = 424
  234.     Color = clWindow
  235.     ParentColor = False
  236.     TabOrder = 3
  237.     object PaintBox1: TPaintBox
  238.       Left = 144
  239.       Height = 64
  240.       Top = 51
  241.       Width = 100
  242.       OnPaint = PaintBox1Paint
  243.     end
  244.     object Panel2: TPanel
  245.       Left = 183
  246.       Height = 28
  247.       Top = 18
  248.       Width = 28
  249.       BevelInner = bvRaised
  250.       ClientHeight = 28
  251.       ClientWidth = 28
  252.       Color = clBtnFace
  253.       ParentColor = False
  254.       TabOrder = 0
  255.       object dummyImg: TImage
  256.         Left = 2
  257.         Height = 24
  258.         Top = 1
  259.         Width = 24
  260.         AutoSize = True
  261.         Picture.Data = {
  262.           1754506F727461626C654E6574776F726B477261706869639E05000089504E47
  263.           0D0A1A0A0000000D4948445200000018000000180806000000E0773DF8000000
  264.           1974455874536F6674776172650041646F626520496D616765526561647971C9
  265.           653C000005404944415478DAB4565B6C1465183DB3333B97BD75775B7A414ACB
  266.           BD81784B05A2112404D484C4182186105F4C2431F1C1177DF085671F7CF481C8
  267.           0389BE11131F8C06FA00463104A112635B2A2D5DAEEDDEBBB7CEECECCCBFE399
  268.           DDED1690C42726F97666FECB39E73BDFFCFFBF92E779789697E2FFFCF98DB4D6
  269.           5063E40029CD972CE25209E352112FA38421460236A778F112105F047A6F7888
  270.           4F02FDA52606D1C4003CC4BA58CF7B27DB044FB9C2EC39A20CF61C89EE7D636B
  271.           6CD7A18D6A62242E6B3D21381244D1321BA942A97271E65EF5F2FD3951917FE6
  272.           9C9F182B4FCDE0896B08BAF45962FFBBFBFA5EFA60A762D6C3F8670698653CE4
  273.           7CD380620C4594C47024F4DEA10D7DC78C17F3E7A676162FDCDD4BF95F71FED2
  274.           7F08BC015AD2046413EB839AF1E5D0BE4F5F8FF7EFD984B95F807491BA748E0C
  275.           D2953810E4B3CBE782092CDE81121D080F1E7D6DB7BE717BDFD2B7737DA2AE7E
  276.           D14464D183BC46D02481EC221AA849A706377D72201EDF318C873FB237002493
  277.           804AD0A0CA770ED77D821EC0A1D7F5083362FB952AE23B463679EFC79507DFDD
  278.           3BD5F4E29F7B0856BB04357E48111DC7D70DBC7520313C3E8CE50B40CC078C12
  279.           304C8210432309951B1D023BDA26F0FBAA8CD90012BB46876B7BD403D9AB95E3
  280.           1670A64B5091D18760E444EFC8B1D166E03704624C4FE1648D2A3502A9E17616
  281.           8ADACEC0F109D8BFC27699E092411B0C78F31A7AF78D8E2EFC357BA256777F20
  282.           74BE4590F67030191BDFECAA75AD8A32743949B11104745F21C1D48ED220B3D0
  283.           B5368149F020DB10822774B88E0ABB18804B49D81ADBBC34953FC8CE732D8265
  284.           E07024B13B59C03C02D061480CD580A684697D049246402DD22EB06EB4ED51DB
  285.           CA5D5743C39161D5C9C9EE06C1D42D89E4F254F670972027301630FAF53C6E22
  286.           081575FEDA1462047484B43691DCCA84AA75025B613429A20D2CC1625226CB63
  287.           12CDA6F94ED4D0731063DD1A64049E13AAAEE4094DED0497D160D8EC6E90CC90
  288.           550A37A006639048E2481AEA04AE07DBC0164B66AE46D34755950CC4FA2E41B6
  289.           894009260A7C6696B03A613C720F49120C7E45015A520F48AD25EBF7994FB937
  290.           6D7F9769CA5D82B440F6AE9DD960EA8A5C8360D90441FD70F9ECB6DE23AD724A
  291.           2036F3E49749A52BACA8E530048145FB6EB1BD52B2451A22DB25587431375DBB
  292.           F742528FC982803A9C9651211A1425B8C3D20B860FCCA5870649561815AE9F2A
  293.           0956EC0E11096D92DCC9D7DC45883974C6A3E860E2E2E2DF96C902A709932578
  294.           8144652AAEB216650E5BF6C7317C1B97095EE2CC2A4D28F3B940D5D9066B4905
  295.           69C6D5078B560ECEC4DA5E64E1FCCCD29DCCAE6DA528BF4FB9E1FB4860A9B59F
  296.           C8A4925AEA594FF81B3B85C2F6B320498D08B50E5199EA73254BA4724B190FEE
  297.           F96E06F420635B8DB3BFCF5EA7B5511630881A812B8C12219719C54732683D4B
  298.           1D5022549476367E4CCFCF561DB77E161099358296B1389D4ADD9E9C5AB86936
  299.           58812A932BB1A3D40297082C21EFAFFD4E74497C02DF2E92CCDF5E30971EA478
  300.           0089D3F4E591F3C06CFDFA969F9CBE76F97BD78D8D6DD97E30E4B0C166E81D7B
  301.           560F0FB16A93FF6976AC9ABF79CB9CFFE3C62CED384923CB8F1F386BE7504AD4
  302.           9C6333972E9C293C6C8C6F79E59D6822BA4ED63A03E54E0D5609FC5A952A5531
  303.           3771BD9ABE746B1236CF4828A9FF3BD152A83B473393D73E2E4C673F4C6E7E75
  304.           60706CBF11EB551423D2234B42C02AAF88CAED829BFE75D62A5C59C8B8F7EDB3
  305.           7082B4452D3F0926F9FF2AA4AFA5C75B85BFE6FDFD3E3E0075E86D60DD9B8C6D
  306.           405F3F2C2EB98294450E732CC604B781F35856332873BD5BEA639A3DEFA336C1
  307.           B3BCFE15600074E530349B0B13190000000049454E44AE426082
  308.         }
  309.       end
  310.     end
  311.   end
  312.   object FinalName: TMemo
  313.     Left = 136
  314.     Height = 75
  315.     Top = 352
  316.     Width = 328
  317.     Font.Name = 'Monospace'
  318.     Lines.Strings = (
  319.       'FinalName'
  320.     )
  321.     ParentFont = False
  322.     TabOrder = 4
  323.   end
  324.   object Label1: TLabel
  325.     Left = 62
  326.     Height = 16
  327.     Top = 352
  328.     Width = 67
  329.     Alignment = taRightJustify
  330.     Caption = 'Final Name'
  331.     ParentColor = False
  332.   end
  333.   object RadioGroup1: TRadioGroup
  334.     Left = 38
  335.     Height = 45
  336.     Top = 216
  337.     Width = 424
  338.     AutoFill = True
  339.     Caption = 'Split Function:'
  340.     ChildSizing.LeftRightSpacing = 6
  341.     ChildSizing.EnlargeHorizontal = crsHomogenousChildResize
  342.     ChildSizing.EnlargeVertical = crsHomogenousChildResize
  343.     ChildSizing.ShrinkHorizontal = crsScaleChilds
  344.     ChildSizing.ShrinkVertical = crsScaleChilds
  345.     ChildSizing.Layout = cclLeftToRightThenTopToBottom
  346.     ChildSizing.ControlsPerLine = 2
  347.     ClientHeight = 27
  348.     ClientWidth = 420
  349.     Columns = 2
  350.     ItemIndex = 0
  351.     Items.Strings = (
  352.       'KodeZwerg''s PrettyString'
  353.       'x2nie''s SplitName'
  354.     )
  355.     OnClick = ListBox1Click
  356.     TabOrder = 5
  357.   end
  358.   object Label2: TLabel
  359.     Left = 168
  360.     Height = 16
  361.     Top = 32
  362.     Width = 136
  363.     Caption = 'TDataModule preview:'
  364.     ParentColor = False
  365.   end
  366. end
  367.  

I want to integrate the functions into Designer.pp next time :P
When you were logged in, you can see attachments.
Lazarus Github @ UbuntuCinnamon-v22.04.1 + LinuxMintDebianEdition5

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2065
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Split Name Quiz (Pascal Skill Challenge)
« Reply #13 on: September 14, 2022, 05:08:34 pm »
Yes ! it works like a charm  8-)
I want to integrate the functions into Designer.pp next time :P
I am glad that you like, feel free to use in whatever way you need  O:-)
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2065
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Split Name Quiz (Pascal Skill Challenge)
« Reply #14 on: September 14, 2022, 10:31:42 pm »
I was just by now sniffing a little in your provided demo code and saw that you like to play with "UnicodeString" so here are both versions:
(that should eliminate warnings and hints on your side)
Code: Pascal  [Select][+][-]
  1. // beautify a ansistring by putting a space on logical positions
  2. // warning: limited to a-z and 0-9 (!)
  3. // written in a hurry by KodeZwerg 2022 for forum.lazarus.freepascal.org
  4. function PrepareStringA(const AString: AnsiString): AnsiString;
  5.   function IsUpper(const AChar: AnsiChar): Boolean; inline;
  6.   begin
  7.     Result := AChar in ['A'..'Z'];
  8.   end;
  9.   function IsLower(const AChar: AnsiChar): Boolean; inline;
  10.   begin
  11.     Result := AChar in ['a'..'z'];
  12.   end;
  13.   function IsNumber(const AChar: AnsiChar): Boolean; inline;
  14.   begin
  15.     Result := AChar in ['0'..'9'];
  16.   end;
  17. var
  18.   LCopy, LOutput: AnsiString;
  19.   LLen, i: Integer;
  20. begin
  21.   LCopy := AString;
  22.   LLen := Length(LCopy);
  23.   LOutput := '';
  24.   for i := 1 to LLen do
  25.     begin
  26.       if ( (Pred(i) > 0) and (Succ(i) < LLen) and (IsUpper(LCopy[i])) and (IsLower(LCopy[Succ(i)])) ) then
  27.         LOutput := LOutput + ' ' + LCopy[i]
  28.       else
  29.       if ( (Pred(i) > 0) and (IsLower(LCopy[Pred(i)])) and (IsUpper(LCopy[i])) ) then
  30.         LOutput := LOutput + ' ' + LCopy[i]
  31.       else
  32.       if ( (Pred(i) > 0) and (IsLower(LCopy[Pred(i)])) and (IsNumber(LCopy[i])) ) then
  33.         LOutput := LOutput + ' ' + LCopy[i]
  34.       else
  35.         LOutput := LOutput + LCopy[i];
  36.     end;
  37.   Result := LOutput;
  38. end;
  39.  
  40. // beautify a unicodestring by putting a space on logical positions
  41. // warning: limited to a-z and 0-9 (!)
  42. // written in a hurry by KodeZwerg 2022 for forum.lazarus.freepascal.org
  43. function PrepareStringU(const AString: UnicodeString): UnicodeString;
  44.   function IsUpper(const AChar: UnicodeChar): Boolean; inline;
  45.   begin
  46.     Result := AChar in ['A'..'Z'];
  47.   end;
  48.   function IsLower(const AChar: UnicodeChar): Boolean; inline;
  49.   begin
  50.     Result := AChar in ['a'..'z'];
  51.   end;
  52.   function IsNumber(const AChar: UnicodeChar): Boolean; inline;
  53.   begin
  54.     Result := AChar in ['0'..'9'];
  55.   end;
  56. var
  57.   LCopy, LOutput: UnicodeString;
  58.   LLen, i: Integer;
  59. begin
  60.   LCopy := AString;
  61.   LLen := Length(LCopy);
  62.   LOutput := '';
  63.   for i := 1 to LLen do
  64.     begin
  65.       if ( (Pred(i) > 0) and (Succ(i) < LLen) and (IsUpper(LCopy[i])) and (IsLower(LCopy[Succ(i)])) ) then
  66.         LOutput := LOutput + ' ' + LCopy[i]
  67.       else
  68.       if ( (Pred(i) > 0) and (IsLower(LCopy[Pred(i)])) and (IsUpper(LCopy[i])) ) then
  69.         LOutput := LOutput + ' ' + LCopy[i]
  70.       else
  71.       if ( (Pred(i) > 0) and (IsLower(LCopy[Pred(i)])) and (IsNumber(LCopy[i])) ) then
  72.         LOutput := LOutput + ' ' + LCopy[i]
  73.       else
  74.         LOutput := LOutput + LCopy[i];
  75.     end;
  76.   Result := LOutput;
  77. end;
Since i did used no units for my method i can not overload, but you can  :P
Code: Pascal  [Select][+][-]
  1. var
  2.   sa: AnsiString;
  3.   su: UnicodeString;
  4. begin
  5.   sa := 'HTMLDatasetFormGridProducer14';
  6.   su := 'HTMLDatasetFormGridProducer14';
  7.   WriteLn('ANSI: ', PrepareStringA(sa));
  8.   WriteLn('Unicode: ', PrepareStringU(su));
  9.   sa := 'ExtJSJSonWebdataInputAdaptor14';
  10.   su := 'ExtJSJSonWebdataInputAdaptor14';
  11.   WriteLn('ANSI: ', PrepareStringA(sa));
  12.   WriteLn('Unicode: ', PrepareStringU(su));
  13.   sa := 'JSONRPCHandler150';
  14.   su := 'JSONRPCHandler150';
  15.   WriteLn('ANSI: ', PrepareStringA(sa));
  16.   WriteLn('Unicode: ', PrepareStringU(su));
  17.   {$IFDEF MSWINDOWS}
  18.   ReadLn;
  19.   {$ENDIF}
  20. end.
For the ones that are curious what i am doing watch attached image.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

 

TinyPortal © 2005-2018