diff --git a/components/jvcllaz/design/JvNet/Images/images.txt b/components/jvcllaz/design/JvNet/Images/images.txt
new file mode 100644
index 000000000..90f34d4de
--- /dev/null
+++ b/components/jvcllaz/design/JvNet/Images/images.txt
@@ -0,0 +1,4 @@
+tjvhtmlparser.bmp
+tjvformtohtml.bmp
+tjvstringlisttohtml.bmp
+tjvstrtohtml.bmp
\ No newline at end of file
diff --git a/components/jvcllaz/design/JvNet/Images/make_res.bat b/components/jvcllaz/design/JvNet/Images/make_res.bat
new file mode 100644
index 000000000..eb9f509ab
--- /dev/null
+++ b/components/jvcllaz/design/JvNet/Images/make_res.bat
@@ -0,0 +1 @@
+lazres ../../../resource/jvnet.res @images.txt
diff --git a/components/jvcllaz/design/JvNet/Images/tjvformtohtml.bmp b/components/jvcllaz/design/JvNet/Images/tjvformtohtml.bmp
new file mode 100644
index 000000000..8abcffafc
Binary files /dev/null and b/components/jvcllaz/design/JvNet/Images/tjvformtohtml.bmp differ
diff --git a/components/jvcllaz/design/JvNet/Images/tjvhtmlparser.bmp b/components/jvcllaz/design/JvNet/Images/tjvhtmlparser.bmp
new file mode 100644
index 000000000..8ef224f65
Binary files /dev/null and b/components/jvcllaz/design/JvNet/Images/tjvhtmlparser.bmp differ
diff --git a/components/jvcllaz/design/JvNet/Images/tjvmail.bmp b/components/jvcllaz/design/JvNet/Images/tjvmail.bmp
new file mode 100644
index 000000000..b40517f28
Binary files /dev/null and b/components/jvcllaz/design/JvNet/Images/tjvmail.bmp differ
diff --git a/components/jvcllaz/design/JvNet/Images/tjvrgbtohtml.bmp b/components/jvcllaz/design/JvNet/Images/tjvrgbtohtml.bmp
new file mode 100644
index 000000000..dbf98f3e1
Binary files /dev/null and b/components/jvcllaz/design/JvNet/Images/tjvrgbtohtml.bmp differ
diff --git a/components/jvcllaz/design/JvNet/Images/tjvstringlisttohtml.bmp b/components/jvcllaz/design/JvNet/Images/tjvstringlisttohtml.bmp
new file mode 100644
index 000000000..a06da2746
Binary files /dev/null and b/components/jvcllaz/design/JvNet/Images/tjvstringlisttohtml.bmp differ
diff --git a/components/jvcllaz/design/JvNet/Images/tjvstrtohtml.bmp b/components/jvcllaz/design/JvNet/Images/tjvstrtohtml.bmp
new file mode 100644
index 000000000..e9e507e00
Binary files /dev/null and b/components/jvcllaz/design/JvNet/Images/tjvstrtohtml.bmp differ
diff --git a/components/jvcllaz/design/JvNet/jvnetreg.pas b/components/jvcllaz/design/JvNet/jvnetreg.pas
new file mode 100644
index 000000000..9ee192a14
--- /dev/null
+++ b/components/jvcllaz/design/JvNet/jvnetreg.pas
@@ -0,0 +1,27 @@
+unit JvNetReg;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ SysUtils;
+
+procedure Register;
+
+implementation
+
+{$R ../../resource/jvnet.res}
+
+uses
+ Classes, Controls,
+ JvDsgnConsts, JvHtmlParser, JvFormToHtml, JvStringListToHtml, JvStrToHtml;
+
+procedure Register;
+begin
+ RegisterComponents(RsPaletteJvcl, [
+ TJvHtmlParser, TJvFormToHtml, TJvStringListToHtml, TJvStrToHtml
+ ]);
+end;
+
+end.
diff --git a/components/jvcllaz/examples/JvDialButton/JvDialButtonDemo.lpi b/components/jvcllaz/examples/JvDialButton/JvDialButtonDemo.lpi
index 0953e3f5e..f85119ff8 100644
--- a/components/jvcllaz/examples/JvDialButton/JvDialButtonDemo.lpi
+++ b/components/jvcllaz/examples/JvDialButton/JvDialButtonDemo.lpi
@@ -60,6 +60,9 @@
+
+
+
diff --git a/components/jvcllaz/examples/JvHTMLParser/JvHTMLParserMainFormU.lfm b/components/jvcllaz/examples/JvHTMLParser/JvHTMLParserMainFormU.lfm
new file mode 100644
index 000000000..84048bf10
--- /dev/null
+++ b/components/jvcllaz/examples/JvHTMLParser/JvHTMLParserMainFormU.lfm
@@ -0,0 +1,263 @@
+object JvHTMLParserMainForm: TJvHTMLParserMainForm
+ Left = 365
+ Height = 530
+ Top = 143
+ Width = 684
+ Caption = 'JvHtmlParser DEMO'
+ ClientHeight = 530
+ ClientWidth = 684
+ Color = clBtnFace
+ Constraints.MinHeight = 200
+ Constraints.MinWidth = 300
+ DefaultMonitor = dmDesktop
+ Font.Color = clWindowText
+ OnCreate = FormCreate
+ Position = poScreenCenter
+ LCLVersion = '2.1.0.0'
+ Scaled = False
+ object PageControl1: TPageControl
+ Left = 0
+ Height = 507
+ Top = 0
+ Width = 684
+ ActivePage = TabSheet1
+ Align = alClient
+ ParentShowHint = False
+ ShowHint = True
+ TabIndex = 0
+ TabOrder = 0
+ object TabSheet1: TTabSheet
+ Hint = 'Table Demo'
+ Caption = 'Table'
+ ClientHeight = 479
+ ClientWidth = 676
+ object JvSplitter1: TSplitter
+ Cursor = crVSplit
+ Left = 0
+ Height = 4
+ Top = 189
+ Width = 676
+ Align = alTop
+ ResizeAnchor = akTop
+ end
+ object TreeView1: TTreeView
+ Left = 0
+ Height = 189
+ Top = 0
+ Width = 676
+ Align = alTop
+ Indent = 19
+ ReadOnly = True
+ ScrollBars = ssAutoBoth
+ TabOrder = 0
+ Options = [tvoAutoItemHeight, tvoHideSelection, tvoKeepCollapsedNodes, tvoReadOnly, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoThemedDraw]
+ end
+ object DisplayMemo1: TMemo
+ Left = 0
+ Height = 252
+ Top = 193
+ Width = 676
+ Align = alClient
+ ReadOnly = True
+ ScrollBars = ssAutoBoth
+ TabOrder = 1
+ WordWrap = False
+ end
+ object Panel1: TPanel
+ Left = 0
+ Height = 34
+ Top = 445
+ Width = 676
+ Align = alBottom
+ AutoSize = True
+ BevelOuter = bvNone
+ ClientHeight = 34
+ ClientWidth = 676
+ TabOrder = 2
+ object btnProcessTable: TButton
+ AnchorSideTop.Control = Panel1
+ AnchorSideTop.Side = asrCenter
+ AnchorSideRight.Control = Panel1
+ AnchorSideRight.Side = asrBottom
+ Left = 606
+ Height = 25
+ Top = 5
+ Width = 66
+ Anchors = [akTop, akRight]
+ AutoSize = True
+ BorderSpacing.Around = 4
+ Caption = 'Execute'
+ OnClick = btnProcessTableClick
+ TabOrder = 0
+ end
+ object btnOpen: TButton
+ AnchorSideLeft.Control = Panel1
+ AnchorSideTop.Control = Panel1
+ AnchorSideTop.Side = asrCenter
+ Left = 4
+ Height = 25
+ Top = 5
+ Width = 64
+ AutoSize = True
+ BorderSpacing.Around = 4
+ Caption = '&Open...'
+ OnClick = btnOpenClick
+ TabOrder = 1
+ end
+ end
+ end
+ object TabSheet2: TTabSheet
+ Hint = 'HTML to text converter'
+ Caption = 'HTML2Text'
+ ClientHeight = 479
+ ClientWidth = 676
+ ImageIndex = 1
+ object DisplayMemo2: TMemo
+ Left = 0
+ Height = 445
+ Top = 0
+ Width = 676
+ Align = alClient
+ ReadOnly = True
+ ScrollBars = ssAutoBoth
+ TabOrder = 0
+ end
+ object Panel2: TPanel
+ Left = 0
+ Height = 34
+ Top = 445
+ Width = 676
+ Align = alBottom
+ AutoSize = True
+ BevelOuter = bvNone
+ ClientHeight = 34
+ ClientWidth = 676
+ TabOrder = 1
+ object btnProcessHTML2Text: TButton
+ AnchorSideTop.Control = Panel2
+ AnchorSideTop.Side = asrCenter
+ AnchorSideRight.Control = Panel2
+ AnchorSideRight.Side = asrBottom
+ Left = 606
+ Height = 25
+ Top = 5
+ Width = 66
+ Anchors = [akTop, akRight]
+ AutoSize = True
+ BorderSpacing.Around = 4
+ Caption = 'Execute'
+ OnClick = btnProcessHTML2TextClick
+ TabOrder = 0
+ end
+ end
+ end
+ object TabSheet3: TTabSheet
+ Hint = 'Simple URL detector'
+ Caption = 'URL detect'
+ ClientHeight = 479
+ ClientWidth = 676
+ ImageIndex = 2
+ object DisplayMemo3: TMemo
+ Left = 0
+ Height = 445
+ Top = 0
+ Width = 676
+ Align = alClient
+ ReadOnly = True
+ ScrollBars = ssAutoBoth
+ TabOrder = 0
+ end
+ object Panel3: TPanel
+ Left = 0
+ Height = 34
+ Top = 445
+ Width = 676
+ Align = alBottom
+ AutoSize = True
+ BevelOuter = bvNone
+ ClientHeight = 34
+ ClientWidth = 676
+ TabOrder = 1
+ object btnProcessURL: TButton
+ AnchorSideTop.Control = Panel3
+ AnchorSideTop.Side = asrCenter
+ AnchorSideRight.Control = Panel3
+ AnchorSideRight.Side = asrBottom
+ Left = 606
+ Height = 25
+ Top = 5
+ Width = 66
+ Anchors = [akTop, akRight]
+ AutoSize = True
+ BorderSpacing.Around = 4
+ Caption = 'Execute'
+ OnClick = btnProcessURLClick
+ TabOrder = 0
+ end
+ end
+ end
+ object TabSheet4: TTabSheet
+ Hint = 'Tags detector'
+ Caption = 'Tags'
+ ClientHeight = 479
+ ClientWidth = 676
+ ImageIndex = 3
+ object DisplayMemo4: TMemo
+ Left = 0
+ Height = 445
+ Top = 0
+ Width = 676
+ Align = alClient
+ ReadOnly = True
+ ScrollBars = ssAutoBoth
+ TabOrder = 0
+ end
+ object Panel4: TPanel
+ Left = 0
+ Height = 34
+ Top = 445
+ Width = 676
+ Align = alBottom
+ AutoSize = True
+ BevelOuter = bvNone
+ ClientHeight = 34
+ ClientWidth = 676
+ TabOrder = 1
+ object btnProcessTags: TButton
+ AnchorSideTop.Control = Panel4
+ AnchorSideTop.Side = asrCenter
+ AnchorSideRight.Control = Panel4
+ AnchorSideRight.Side = asrBottom
+ Left = 606
+ Height = 25
+ Top = 5
+ Width = 66
+ Anchors = [akTop, akRight]
+ AutoSize = True
+ BorderSpacing.Around = 4
+ Caption = 'Execute'
+ OnClick = btnProcessTagsClick
+ TabOrder = 0
+ end
+ end
+ end
+ end
+ object StatusBar1: TStatusBar
+ Left = 0
+ Height = 23
+ Top = 507
+ Width = 684
+ Panels = <>
+ end
+ object JvHtmlParser1: TJvHTMLParser
+ FileName = 'data\sample.htm'
+ left = 224
+ top = 72
+ end
+ object OpenDialog1: TOpenDialog
+ Filter = 'HTML files|*.htm;*.html;*.htt|All files|*.*'
+ InitialDir = '.'
+ left = 336
+ top = 72
+ end
+end
diff --git a/components/jvcllaz/examples/JvHTMLParser/JvHTMLParserMainFormU.pas b/components/jvcllaz/examples/JvHTMLParser/JvHTMLParserMainFormU.pas
new file mode 100644
index 000000000..a102dd4de
--- /dev/null
+++ b/components/jvcllaz/examples/JvHTMLParser/JvHTMLParserMainFormU.pas
@@ -0,0 +1,299 @@
+{******************************************************************
+
+ JEDI-VCL Demo
+
+ Copyright (C) 2002 Project JEDI
+
+ Original author:
+
+ Contributor(s):
+
+ You may retrieve the latest version of this file at the JEDI-JVCL
+ home page, located at http://jvcl.delphi-jedi.org
+
+ The contents of this file are used with permission, subject to
+ the Mozilla Public License Version 1.1 (the "License"); you may
+ not use this file except in compliance with the License. You may
+ obtain a copy of the License at
+ http://www.mozilla.org/MPL/MPL-1_1Final.html
+
+ Software distributed under the License is distributed on an
+ "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ rights and limitations under the License.
+
+******************************************************************}
+
+unit JvHTMLParserMainFormU;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ //Windows, Messages,
+ Forms, SysUtils, Classes, Controls, StdCtrls, ExtCtrls, ComCtrls, Dialogs,
+ JvHtmlParser;
+
+type
+ TJvHTMLParserMainForm = class(TForm)
+ PageControl1: TPageControl;
+ TabSheet1: TTabSheet;
+ TabSheet2: TTabSheet;
+ TabSheet3: TTabSheet;
+ TreeView1: TTreeView;
+ StatusBar1: TStatusBar;
+ TabSheet4: TTabSheet;
+ JvSplitter1: TSplitter;
+ DisplayMemo1: TMemo;
+ Panel1: TPanel;
+ btnProcessTable: TButton;
+ JvHtmlParser1: TJvHtmlParser;
+ DisplayMemo2: TMemo;
+ DisplayMemo3: TMemo;
+ DisplayMemo4: TMemo;
+ Panel2: TPanel;
+ btnProcessHTML2Text: TButton;
+ Panel3: TPanel;
+ btnProcessURL: TButton;
+ Panel4: TPanel;
+ btnProcessTags: TButton;
+ btnOpen: TButton;
+ OpenDialog1: TOpenDialog;
+ procedure btnProcessTableClick(Sender: TObject);
+ procedure TableKeyFound(Sender: TObject; Key, Results, OriginalLine: string);
+ procedure TableKeyFoundEx(Sender: TObject; Key, Results,
+ OriginalLine: String; TagInfo: TTagInfo; Attributes: TStrings);
+ procedure HTML2TextKeyFound(Sender: TObject; Key, Results, OriginalLine: string);
+ procedure URLDetectKeyFound(Sender: TObject; Key, Results, OriginalLine: string);
+ procedure TagsKeyFound(Sender: TObject; Key, Results, OriginalLine: string);
+ procedure btnProcessHTML2TextClick(Sender: TObject);
+ procedure btnProcessURLClick(Sender: TObject);
+ procedure btnProcessTagsClick(Sender: TObject);
+ procedure btnOpenClick(Sender: TObject);
+ procedure FormCreate(Sender: TObject);
+ private
+ CurNode: TTreeNode;
+ FText: string;
+ FStartTime: TTime;
+ public
+ function ReplaceSpecials(Str: string): string;
+ procedure ShowStatus(t: TTime);
+ procedure DoKeyFoundEx(Sender: TObject; Key, Results, OriginalLine: string; TagInfo:TTagInfo; Attributes:TStrings);
+ end;
+
+var
+ JvHTMLParserMainForm: TJvHTMLParserMainForm;
+
+implementation
+
+uses
+ StrUtils;
+
+ {
+uses
+ JclStrings;
+ }
+{$R *.lfm}
+
+procedure TJvHTMLParserMainForm.btnProcessTableClick(Sender: TObject);
+begin
+ Screen.Cursor := crHourGlass;
+ Self.Tag := 0;
+ FStartTime := Now();
+ with JvHtmlParser1 do
+ begin
+ ClearConditions;
+ AddCondition('TD', '', ' ');
+ AddCondition('TH', '', ' ');
+ AddCondition('TR', '', ' ');
+// OnKeyFound := TableKeyFound;
+ OnKeyFoundEx := @TableKeyFoundEx;
+ end;
+ TreeView1.Items.BeginUpdate;
+ DisplayMemo1.Lines.BeginUpdate;
+ try
+ DisplayMemo1.Clear;
+ JvHtmlParser1.AnalyseFile;
+ ShowStatus(Now() - FStartTime);
+ finally
+ TreeView1.Items.EndUpdate;
+ DisplayMemo1.Lines.EndUpdate;
+ Screen.Cursor := crDefault;
+ end;
+end;
+
+procedure TJvHTMLParserMainForm.btnProcessHTML2TextClick(Sender: TObject);
+begin
+ Screen.Cursor := crHourGlass;
+ Self.Tag := 0;
+ FStartTime := Now();
+ with JvHtmlParser1 do
+ begin
+ ClearConditions;
+ AddCondition('Text', '>', '<');
+ OnKeyFound := @HTML2TextKeyFound;
+ end;
+ DisplayMemo2.Lines.BeginUpdate;
+ try
+ DisplayMemo2.Clear;
+ JvHtmlParser1.AnalyseFile;
+ ShowStatus(Now() - FStartTime);
+ DisplayMemo2.Text := ReplaceSpecials(FText);
+ finally
+ FText := '';
+ DisplayMemo2.Lines.EndUpdate;
+ Screen.Cursor := crDefault;
+ end;
+end;
+
+procedure TJvHTMLParserMainForm.btnProcessURLClick(Sender: TObject);
+begin
+ Screen.Cursor := crHourGlass;
+ Self.Tag := 0;
+ FStartTime := Now();
+ with JvHtmlParser1 do
+ begin
+ ClearConditions;
+ AddCondition('URL', 'href=http://', '>');
+ AddCondition('URL', 'href="http://', '">');
+ OnKeyFound := @URLDetectKeyFound;
+ end;
+ DisplayMemo3.Lines.BeginUpdate;
+ try
+ DisplayMemo3.Clear;
+ JvHtmlParser1.AnalyseFile;
+ ShowStatus(Now() - FStartTime);
+ finally
+ DisplayMemo3.Lines.EndUpdate;
+ Screen.Cursor := crDefault;
+ end;
+end;
+
+procedure TJvHTMLParserMainForm.btnProcessTagsClick(Sender: TObject);
+begin
+ Screen.Cursor := crHourGlass;
+ Self.Tag := 0;
+ FStartTime := Now();
+ with JvHtmlParser1 do
+ begin
+ ClearConditions;
+ AddCondition('URL', '<', '>');
+ OnKeyFound := nil;
+ OnKeyFoundEx := @DoKeyFoundEx;
+ end;
+ DisplayMemo4.Lines.BeginUpdate;
+ try
+ DisplayMemo4.Clear;
+ JvHtmlParser1.AnalyseFile;
+ ShowStatus(Now() - FStartTime);
+ finally
+ DisplayMemo4.Lines.EndUpdate;
+ Screen.Cursor := crDefault;
+ end;
+end;
+
+procedure TJvHTMLParserMainForm.TableKeyFound(Sender: TObject; Key, Results,
+ OriginalLine: string);
+begin
+ Self.Tag := Self.Tag + 1;
+ DisplayMemo1.Lines.Add(Key + #13#10 + Results);
+ if UpperCase(Key) = 'TR' then
+ CurNode := TreeView1.Items.AddChild(nil, 'TR')
+ else
+ TreeView1.Items.AddChild(CurNode, Results);
+end;
+
+procedure TJvHTMLParserMainForm.TableKeyFoundEx(Sender: TObject;
+ Key, Results, OriginalLine: String; TagInfo: TTagInfo;
+ Attributes: TStrings);
+var
+ i : integer;
+begin
+ Self.Tag := Self.Tag + 1;
+ DisplayMemo1.Lines.Add(Key + #13#10 + Results);
+ for i:=0 to Attributes.Count-1 do
+ DisplayMemo1.Lines.Add('Attributes=' + Attributes[i]);
+ if UpperCase(Key) = 'TR' then
+ CurNode := TreeView1.Items.AddChild(nil, 'TR')
+ else
+ TreeView1.Items.AddChild(CurNode, Results);
+end;
+
+procedure TJvHTMLParserMainForm.HTML2TextKeyFound(Sender: TObject; Key, Results,
+ OriginalLine: string);
+begin
+ //this is only for sample!
+ Self.Tag := Self.Tag + 1;
+ if (FText <> '') and (FText[Length(FText)] <> ' ') then
+ FText := FText + ' ';
+ FText := FText + Results;
+end;
+
+procedure TJvHTMLParserMainForm.URLDetectKeyFound(Sender: TObject; Key, Results,
+ OriginalLine: string);
+begin
+ Self.Tag := Self.Tag + 1;
+ DisplayMemo3.Lines.Add('http://' + Results);
+end;
+
+procedure TJvHTMLParserMainForm.TagsKeyFound(Sender: TObject; Key, Results,
+ OriginalLine: string);
+begin
+ Self.Tag := Self.Tag + 1;
+ DisplayMemo4.Lines.Add('<' + Results + '>');
+end;
+
+procedure TJvHTMLParserMainForm.ShowStatus(t: TTime);
+var
+ h, m, s, ms: Word;
+begin
+ DecodeTime(t, h, m, s, ms);
+ StatusBar1.SimpleText :=
+ Format('%d tags are processed for period: %0.2d:%0.2d:%0.2d.%0.3d',
+ [Self.Tag, h, m, s, ms]);
+end;
+
+function TJvHTMLParserMainForm.ReplaceSpecials(Str: string): string;
+begin
+ Result := Str;
+ Result := StringReplace(Result, '>', '>', [rfReplaceAll, rfIgnoreCase]);
+ Result := StringReplace(Result, '<', '<', [rfReplaceAll, rfIgnoreCase]);
+ Result := StringReplace(Result, '&', '&', [rfReplaceAll, rfIgnoreCase]);
+ Result := StringReplace(Result, ' ', ' ', [rfReplaceAll, rfIgnoreCase]);
+ Result := StringReplace(Result, '"', '"', [rfReplaceAll, rfIgnoreCase]);
+ Result := StringReplace(Result, '©', #169, [rfReplaceAll, rfIgnoreCase]);
+ // add more here...
+end;
+
+procedure TJvHTMLParserMainForm.btnOpenClick(Sender: TObject);
+var
+ I: Integer;
+begin
+ if OpenDialog1.Execute then
+ begin
+ JvHtmlParser1.FileName := OpenDialog1.FileName;
+ for I := 0 to ComponentCount - 1 do
+ if (Components[I] <> btnOpen) and (Components[I] is TButton) then
+ TButton(Components[I]).OnClick(nil);
+ end;
+end;
+
+procedure TJvHTMLParserMainForm.FormCreate(Sender: TObject);
+begin
+ JvHtmlParser1.OnKeyFoundEx := @DoKeyFoundEx;
+end;
+
+procedure TJvHTMLParserMainForm.DoKeyFoundEx(Sender: TObject; Key, Results,
+ OriginalLine: string; TagInfo: TTagInfo; Attributes: TStrings);
+begin
+ Self.Tag := Self.Tag + 1;
+ DisplayMemo4.Lines.Add('<' + Results + '>');
+ if Attributes.Count > 0 then
+ begin
+ DisplayMemo4.Lines.Add('Attributes:');
+ DisplayMemo4.Lines.AddStrings(Attributes);
+ end;
+end;
+
+end.
diff --git a/components/jvcllaz/examples/JvHTMLParser/JvHtmlParserProj.lpi b/components/jvcllaz/examples/JvHTMLParser/JvHtmlParserProj.lpi
new file mode 100644
index 000000000..f1c0e694a
--- /dev/null
+++ b/components/jvcllaz/examples/JvHTMLParser/JvHtmlParserProj.lpi
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/jvcllaz/examples/JvHTMLParser/JvHtmlParserProj.lpr b/components/jvcllaz/examples/JvHTMLParser/JvHtmlParserProj.lpr
new file mode 100644
index 000000000..70ad73ef8
--- /dev/null
+++ b/components/jvcllaz/examples/JvHTMLParser/JvHtmlParserProj.lpr
@@ -0,0 +1,16 @@
+program JvHtmlParserProj;
+
+uses
+ Interfaces, Forms,
+ JvHTMLParserMainFormU in 'JvHTMLParserMainFormU.pas' {JvHTMLParserMainForm};
+
+{$R *.res}
+
+begin
+ Application.Scaled:=True;
+ Application.Initialize;
+ Application.Title:='JvHtmlParserProj';
+ Application.CreateForm(TJvHTMLParserMainForm, JvHTMLParserMainForm);
+ Application.Run;
+end.
+
diff --git a/components/jvcllaz/examples/JvHTMLParser/sample.htm b/components/jvcllaz/examples/JvHTMLParser/sample.htm
new file mode 100644
index 000000000..8be303f8a
--- /dev/null
+++ b/components/jvcllaz/examples/JvHTMLParser/sample.htm
@@ -0,0 +1,61 @@
+
+
+This is a JvHtmlParser Demo
+
+EmpNo LastName FirstName PhoneExt HireDate Salary
+2 Nelson Roberto 250 28.12.1988 40000
+4 Young Bruce 233 28.12.1988 55500
+5 Lambert Kim 22 06.02.1989 25000
+8 Johnson Leslie 410 05.04.1989 25050
+9 Forest Phil 229 17.04.1989 25050
+11 Weston K. J. 34 17.01.1990 33292,9375
+12 Lee Terri 256 01.05.1990 45332
+14 Hall Stewart 227 04.06.1990 34482,625
+15 Young Katherine 231 14.06.1990 24400
+20 Papadopoulos Chris 887 01.01.1990 25050
+24 Fisher Pete 888 12.09.1990 23040
+28 Bennet Ann 5 01.02.1991 34482,8
+29 De Souza Roger 288 18.02.1991 25500
+34 Baldwin Janet 2 21.03.1991 23300
+36 Reeves Roger 6 25.04.1991 33620
+37 Stansbury Willie 7 25.04.1991 39224
+44 Phong Leslie 216 03.06.1991 40350
+45 Ramanathan Ashok 209 01.08.1991 33292,94
+46 Steadman Walter 210 09.08.1991 19599
+52 Nordstrom Carol 420 02.10.1991 4500
+61 Leung Luke 3 18.02.1992 34500
+65 O'Brien Sue Anne 877 23.03.1992 31275
+71 Burbank Jennifer M. 289 15.04.1992 45332
+72 Sutherland Claudia 20.04.1992 35699
+83 Bishop Dana 290 01.06.1992 45000
+85 MacDonald Mary S. 477 01.06.1992 35699
+94 Williams Randy 892 08.08.1992 28900
+105 Bender Oliver H. 255 08.10.1992 36799
+107 Cook Kevin 894 01.02.1993 35500
+109 Brown Kelly 202 04.02.1993 27000
+110 Ichida Yuki 22 04.02.1993 25689
+113 Page Mary 845 12.04.1993 48000
+114 Parker Bill 247 01.06.1993 35000
+118 Yamamoto Takashi 23 01.07.1993 32500
+121 Ferrari Roberto 1 12.07.1993 40500
+127 Yanowski Michael 492 09.08.1993 44000
+134 Glon Jacques 23.08.1993 24855
+136 Johnson Scott 265 13.09.1993 30588,99
+138 Green T.J. 218 01.11.1993 36000
+141 Osborne Pierre 03.01.1994 35600
+144 Montgomery John 820 30.03.1994 35699
+145 Guckenheimer Mark 221 02.05.1994 32000
+
+PARTICIPATION
+
+If you would like to participate in JVCL development (donate new components, refactor existing ones, write help files and documentation, develop examples), please join us.
+
+
+BUGS
+
+To report bugs, please contact us.
+We hope that you'll find JVCL useful.
+May the Source be with you!
+Team JVCL
+
+
diff --git a/components/jvcllaz/examples/JvHTMLParser/sample2.htm b/components/jvcllaz/examples/JvHTMLParser/sample2.htm
new file mode 100644
index 000000000..845ec3935
--- /dev/null
+++ b/components/jvcllaz/examples/JvHTMLParser/sample2.htm
@@ -0,0 +1,61 @@
+
+
+This is a JvHtmlParser Demo
+
+EmpNo LastName FirstName PhoneExt HireDate Salary
+2 Nelson Roberto 250 28.12.1988 40000
+4 Young Bruce 233 28.12.1988 55500
+5 Lambert Kim 22 06.02.1989 25000
+8 Johnson Leslie 410 05.04.1989 25050
+9 Forest Phil 229 17.04.1989 25050
+11 Weston K. J. 34 17.01.1990 33292,9375
+12 Lee Terri 256 01.05.1990 45332
+14 Hall Stewart 227 04.06.1990 34482,625
+15 Young Katherine 231 14.06.1990 24400
+20 Papadopoulos Chris 887 01.01.1990 25050
+24 Fisher Pete 888 12.09.1990 23040
+28 Bennet Ann 5 01.02.1991 34482,8
+29 De Souza Roger 288 18.02.1991 25500
+34 Baldwin Janet 2 21.03.1991 23300
+36 Reeves Roger 6 25.04.1991 33620
+37 Stansbury Willie 7 25.04.1991 39224
+44 Phong Leslie 216 03.06.1991 40350
+45 Ramanathan Ashok 209 01.08.1991 33292,94
+46 Steadman Walter 210 09.08.1991 19599
+52 Nordstrom Carol 420 02.10.1991 4500
+61 Leung Luke 3 18.02.1992 34500
+65 O'Brien Sue Anne 877 23.03.1992 31275
+71 Burbank Jennifer M. 289 15.04.1992 45332
+72 Sutherland Claudia 20.04.1992 35699
+83 Bishop Dana 290 01.06.1992 45000
+85 MacDonald Mary S. 477 01.06.1992 35699
+94 Williams Randy 892 08.08.1992 28900
+105 Bender Oliver H. 255 08.10.1992 36799
+107 Cook Kevin 894 01.02.1993 35500
+109 Brown Kelly 202 04.02.1993 27000
+110 Ichida Yuki 22 04.02.1993 25689
+113 Page Mary 845 12.04.1993 48000
+114 Parker Bill 247 01.06.1993 35000
+118 Yamamoto Takashi 23 01.07.1993 32500
+121 Ferrari Roberto 1 12.07.1993 40500
+127 Yanowski Michael 492 09.08.1993 44000
+134 Glon Jacques 23.08.1993 24855
+136 Johnson Scott 265 13.09.1993 30588,99
+138 Green T.J. 218 01.11.1993 36000
+141 Osborne Pierre 03.01.1994 35600
+144 Montgomery John 820 30.03.1994 35699
+145 Guckenheimer Mark 221 02.05.1994 32000
+
+PARTICIPATION
+
+If you would like to participate in JVCL development (donate new components, refactor existing ones, write help files and documentation, develop examples), please join us.
+
+
+BUGS
+
+To report bugs, please contact us.
+We hope that you'll find JVCL useful.
+May the Source be with you!
+Team JVCL
+
+
diff --git a/components/jvcllaz/examples/JvLED/JvLEDDemo.lpi b/components/jvcllaz/examples/JvLED/JvLEDDemo.lpi
index 5080ac236..07dbfc1f1 100644
--- a/components/jvcllaz/examples/JvLED/JvLEDDemo.lpi
+++ b/components/jvcllaz/examples/JvLED/JvLEDDemo.lpi
@@ -58,6 +58,9 @@
+
+
+
diff --git a/components/jvcllaz/examples/JvLED/LEDMain.lfm b/components/jvcllaz/examples/JvLED/LEDMain.lfm
index aa52b202e..1c1d95f8a 100644
--- a/components/jvcllaz/examples/JvLED/LEDMain.lfm
+++ b/components/jvcllaz/examples/JvLED/LEDMain.lfm
@@ -422,6 +422,7 @@ object LEDDemoMain: TLEDDemoMain
Height = 23
Top = 128
Width = 25
+ Alignment = taCenter
MaxLength = 2
OnChange = HexTextChange
TabOrder = 0
diff --git a/components/jvcllaz/packages/jvnetlazd.lpk b/components/jvcllaz/packages/jvnetlazd.lpk
new file mode 100644
index 000000000..6944f79df
--- /dev/null
+++ b/components/jvcllaz/packages/jvnetlazd.lpk
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/jvcllaz/packages/jvnetlazr.lpk b/components/jvcllaz/packages/jvnetlazr.lpk
new file mode 100644
index 000000000..87fa91a49
--- /dev/null
+++ b/components/jvcllaz/packages/jvnetlazr.lpk
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/jvcllaz/resource/jvnet.res b/components/jvcllaz/resource/jvnet.res
new file mode 100644
index 000000000..2cf41e341
Binary files /dev/null and b/components/jvcllaz/resource/jvnet.res differ
diff --git a/components/jvcllaz/run/JvNet/jvformtohtml.pas b/components/jvcllaz/run/JvNet/jvformtohtml.pas
new file mode 100644
index 000000000..440bf75f1
--- /dev/null
+++ b/components/jvcllaz/run/JvNet/jvformtohtml.pas
@@ -0,0 +1,259 @@
+{-----------------------------------------------------------------------------
+The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/MPL-1.1.html
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+the specific language governing rights and limitations under the License.
+
+The Original Code is: JvFormToHtml.PAS, released on 2001-02-28.
+
+The Initial Developer of the Original Code is Sébastien Buysse [sbuysse att buypin dott com]
+Portions created by Sébastien Buysse are Copyright (C) 2001 Sébastien Buysse.
+All Rights Reserved.
+
+Contributor(s): Michael Beck [mbeck att bigfoot dott com].
+
+You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
+located at http://jvcl.delphi-jedi.org
+
+Known Issues:
+-----------------------------------------------------------------------------}
+// $Id$
+
+unit JvFormToHtml;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ SysUtils, Classes, Graphics, Controls, Forms, StdCtrls;
+// JvComponentBase;
+
+type
+ TJvFormToHtml = class(TComponent) //TJvComponent)
+ public
+ procedure FormToHtml(const Form: TCustomForm; const Filename: string);
+ end;
+
+
+implementation
+
+function FontToCss(const Font: TFont): string;
+begin
+ Result := Format(';font-Size:%d;color:#%d;font-weight:', [Font.Size, Font.Color]);
+ if fsBold in Font.Style then
+ Result := Result + 'bold;'
+ else
+ Result := Result + 'normal;';
+ Result := Result + 'font-family:' + Font.Name;
+end;
+
+procedure TJvFormToHtml.FormToHtml(const Form: TCustomForm; const Filename: string);
+var
+ I, J: Integer;
+ C: TComponent;
+ S, S2, St: string;
+ HTML: TStringList;
+begin
+ HTML := TStringList.Create;
+ try
+ HTML.Add('');
+ for I := 0 to Form.ComponentCount - 1 do
+ begin
+ C := Form.Components[I];
+ St := '';
+ if C is TLabel then
+ begin
+ St := Format('' +
+ TLabel(C).Caption + ' ';
+ end
+ else
+ if C is TButton then
+ begin
+ if not TButton(C).Enabled then
+ S := ' DISABLED'
+ else
+ S := '';
+
+ St := Format('' +
+ TButton(C).Caption + ' ';
+ end
+ else
+ if C is TMemo then
+ begin
+ S := '';
+ if TMemo(C).ReadOnly then
+ S := S + ' ReadOnly';
+ if not TMemo(C).Enabled then
+ S := S + ' DISABLED';
+
+ S2 := '';
+ if TMemo(C).WordWrap then
+ S2 := S2 + ' WRAP=PHYSICAL'
+ else
+ S2 := S2 + ' WRAP=OFF';
+
+ St := Format('';
+ end
+ else
+ if C is TCheckBox then
+ begin
+ S := '';
+ if not TCheckBox(C).Enabled then
+ S := S + ' DISABLED';
+ if TCheckBox(C).Checked then
+ S := S + ' CHECKED';
+
+ St := Format(' ';
+ HTML.Add(St);
+ St := Format('' +
+ TCheckBox(C).Caption + ' ';
+ end
+ else
+ if C is TRadioButton then
+ begin
+ S := '';
+ if not TRadioButton(C).Enabled then
+ S := S + ' DISABLED';
+ if TRadioButton(C).Checked then
+ S := S + ' CHECKED';
+
+ St := Format(' ';
+ HTML.Add(St);
+ St := Format('' +
+ TRadioButton(C).Caption + ' ';
+ end
+ else
+ if C is TEdit then
+ begin
+ S := '';
+ if TEdit(C).ReadOnly then
+ S := S + ' ReadOnly';
+ if TEdit(C).MaxLength <> 0 then
+ S := S + ' MAXLENGTH=' + IntToStr(TEdit(C).MaxLength);
+ if not TEdit(C).Enabled then
+ S := S + ' DISABLED';
+
+ St := Format(' ';
+ end
+ else
+ if C is TComboBox then
+ begin
+ if not TComboBox(C).Enabled then
+ S := ' DISABLED'
+ else
+ S := '';
+
+ St := Format('';
+ HTML.Add(St);
+ for J := 0 to TComboBox(C).Items.Count - 1 do
+ begin
+ if TComboBox(C).ItemIndex = J then
+ HTML.Add('' + TComboBox(C).Items[J])
+ else
+ HTML.Add(' ' + TComboBox(C).Items[J]);
+ end;
+ St := ' ';
+ end
+ else
+ if C is TListBox then
+ begin
+ if not TListBox(C).Enabled then
+ S := ' DISABLED'
+ else
+ S := '';
+
+ St := Format('';
+ HTML.Add(St);
+ for J := 0 to TListBox(C).Items.Count - 1 do
+ begin
+ if TListBox(C).ItemIndex = J then
+ HTML.Add('' + TListBox(C).Items[J])
+ else
+ HTML.Add(' ' + TListBox(C).Items[J]);
+ end;
+ St := ' ';
+ end;
+
+ if St <> '' then
+ HTML.Add(St);
+ end;
+ HTML.Add('');
+
+ HTML.SaveToFile(Filename);
+ finally
+ HTML.Free;
+ end;
+end;
+
+end.
diff --git a/components/jvcllaz/run/JvNet/jvhtmlparser.pas b/components/jvcllaz/run/JvNet/jvhtmlparser.pas
new file mode 100644
index 000000000..97035d74a
--- /dev/null
+++ b/components/jvcllaz/run/JvNet/jvhtmlparser.pas
@@ -0,0 +1,483 @@
+{-----------------------------------------------------------------------------
+The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/MPL-1.1.html
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+the specific language governing rights and limitations under the License.
+
+The Original Code is: JvHTMLParser.PAS, released on 2001-02-28.
+
+The Initial Developer of the Original Code is Sébastien Buysse [sbuysse att buypin dott com]
+Portions created by Sébastien Buysse are Copyright (C) 2001 Sébastien Buysse.
+All Rights Reserved.
+
+Contributor(s): Michael Beck [mbeck att bigfoot dott com].
+ Alexander Samusenko[sandx att chat dott ru].
+ CarlEfird.
+
+You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
+located at http://jvcl.delphi-jedi.org
+
+Known Issues:
+-----------------------------------------------------------------------------}
+// $Id$
+
+unit JvHtmlParser;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ SysUtils, Classes;
+ ///JclStrings,
+// JvComponentBase;
+
+type
+ PTagInfo = ^TTagInfo;
+
+ TTagInfo = record
+ BeginPos: Integer;
+ EndPos: Integer;
+ BeginContext: Integer;
+ EndContext: Integer;
+ Key: Integer;
+ end;
+
+ // (rom) definitely needs improvement
+ TJvParserInfo = class(TObject)
+ public
+ StartTag: string;
+ EndTag: string;
+ MustBe: Integer;
+ TakeText: Integer;
+ end;
+
+ TTagInfoList = class(TList)
+ public
+ procedure AddValue(const Value: TTagInfo);
+ procedure Clear; override;
+ end;
+
+ TJvKeyFoundEvent = procedure(Sender: TObject; Key, Results, OriginalLine: string) of object;
+ TJvKeyFoundExEvent = procedure(Sender: TObject; Key, Results, OriginalLine: string;
+ TagInfo: TTagInfo; Attributes: TStrings) of object;
+
+ TJvHTMLParser = class(TComponent) //TJvComponent)
+ private
+ FParser: TStringList;
+ FKeys: TStringList;
+ FFileName: TFileName;
+ FTagList: TTagInfoList;
+ FContent: string;
+ FOnKeyFound: TJvKeyFoundEvent;
+ FOnKeyFoundEx: TJvKeyFoundExEvent;
+ function GetParser: TStrings;
+ procedure SetParser(Value: TStrings);
+ procedure SetFileName(Value: TFileName);
+ procedure SetTagList(const Value: TTagInfoList);
+ function GetConditionsCount: Integer;
+ protected
+ procedure Loaded; override;
+ property TagList: TTagInfoList read FTagList write SetTagList;
+ public
+ procedure AnalyseString(const Str: string);
+ procedure AnalyseFile;
+ procedure AddCondition(const Keyword: string; const StartTag: string = '<';
+ const EndTag: string = '>'; TextSelection: Integer = 0);
+ procedure RemoveCondition(Index: Integer);
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ property ConditionsCount: Integer read GetConditionsCount;
+ procedure ClearConditions;
+ procedure GetCondition(Index: Integer; var Keyword, StartTag, EndTag: string); overload;
+ procedure GetCondition(Index: Integer; var Keyword, StartTag, EndTag: string;
+ var TextSelection: Integer); overload;
+ property Content: string read FContent;
+ published
+ property FileName: TFileName read FFileName write SetFileName;
+ property Parser: TStrings read GetParser write SetParser;
+ property OnKeyFound: TJvKeyFoundEvent read FOnKeyFound write FOnKeyFound;
+ property OnKeyFoundEx: TJvKeyFoundExEvent read FOnKeyFoundEx write FOnKeyFoundEx;
+ end;
+
+
+implementation
+
+uses
+ StrUtils,
+ {$IFNDEF COMPILER12_UP}
+ JvJCLUtils,
+ {$ENDIF ~COMPILER12_UP}
+ JvConsts;
+
+{Comparison function. Used internally for observance of the sequences tags}
+function CompareTags(Item1, Item2: Pointer): Integer;
+begin
+ Result := (PTagInfo(Item1)^.BeginPos - PTagInfo(Item2)^.BeginPos);
+end;
+
+{ Utilities similar to corresponding JCL routines }
+
+function StrFind(const Substr, S: string; const Index: SizeInt = 1): SizeInt;
+begin
+ Result := PosEx(SubStr, S, Index);
+end;
+
+
+//=== { TJvHTMLParser } ======================================================
+
+constructor TJvHTMLParser.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FParser := TStringList.Create;
+ FKeys := TStringList.Create;
+ FTagList := TTagInfoList.Create;
+end;
+
+destructor TJvHTMLParser.Destroy;
+var
+ Index: Integer;
+begin
+ FParser.Free;
+ for Index := FKeys.Count - 1 downto 0 do
+ FKeys.Objects[Index].Free;
+ FKeys.Free;
+ FTagList.Free;
+ inherited Destroy;
+end;
+
+procedure TJvHTMLParser.Loaded;
+begin
+ inherited Loaded;
+ SetParser(FParser);
+end;
+
+procedure TJvHTMLParser.SetFileName(Value: TFileName);
+begin
+ if FFileName <> Value then
+ begin
+ FFileName := Value;
+ if not (csDesigning in ComponentState) then
+ AnalyseFile;
+ end;
+end;
+
+function TJvHTMLParser.GetParser: TStrings;
+begin
+ Result := FParser;
+end;
+
+procedure TJvHTMLParser.SetParser(Value: TStrings);
+var
+ I: Integer;
+ Obj: TJvParserInfo;
+ Cap: string;
+begin
+ if FParser <> Value then // make sure we don't assign to ourselves (that will clear the list)
+ FParser.Assign(Value);
+ for I := FKeys.Count - 1 downto 0 do
+ FKeys.Objects[I].Free;
+ FKeys.Clear;
+ I := 0;
+ while I < FParser.Count do
+ begin
+ Obj := TJvParserInfo.Create;
+ try
+ Cap := FParser[I];
+ Inc(I);
+ Obj.StartTag := FParser[I];
+ Inc(I);
+ Obj.EndTag := FParser[I];
+ Inc(I);
+ Obj.MustBe := StrToInt(FParser[I]);
+ Inc(I);
+ Obj.TakeText := StrToInt(FParser[I]);
+ Inc(I);
+ finally
+ FKeys.AddObject(Cap, Obj);
+ end;
+ end;
+end;
+
+// (rom) reimplemented with a TStringList
+
+procedure TJvHTMLParser.AnalyseFile;
+var
+ List: TStringList;
+begin
+ List := TStringList.Create;
+ try
+ if FileExists(FileName) then
+ begin
+ List.LoadFromFile(FileName);
+ AnalyseString(List.Text);
+ end;
+ finally
+ List.Free;
+ end;
+end;
+
+procedure TJvHTMLParser.AnalyseString(const Str: string);
+var
+ Str2, Str3: string;
+ StartTag1, StartTag2: string;
+ I, J, K, Index: Integer;
+ TagInfo: TTagInfo;
+ AttributesList: TStringList;
+
+ procedure InnerParseAttributes(Content: PChar; Strings: TStrings);
+ var
+ Head, Tail: PChar;
+ EOS, InQuote, LeadQuote: Boolean;
+ QuoteChar: Char;
+ begin
+ if (Content = nil) or (Content^ = #0) then
+ Exit;
+ Tail := Content;
+ QuoteChar := #0;
+ repeat
+ while CharInSet(Tail^, [Cr, Lf, ' ']) do
+ Inc(Tail);
+ Head := Tail;
+ InQuote := False;
+ LeadQuote := False;
+ while True do
+ begin
+ while (InQuote and not CharInSet(Tail^, [#0, '"'])) or
+ not CharInSet(Tail^, [#0, Cr, Lf, ' ', '"']) do
+ Inc(Tail);
+ if Tail^ = '"' then
+ begin
+ if (QuoteChar <> #0) and (QuoteChar = Tail^) then
+ QuoteChar := #0
+ else
+ begin
+ LeadQuote := Head = Tail;
+ QuoteChar := Tail^;
+ if LeadQuote then
+ Inc(Head);
+ end;
+ InQuote := QuoteChar <> #0;
+ if InQuote then
+ Inc(Tail)
+ else
+ Break;
+ end
+ else
+ Break;
+ end;
+ if not LeadQuote and (Tail^ <> #0) and (Tail^ = '"') then
+ Inc(Tail);
+ EOS := Tail^ = #0;
+ Tail^ := #0;
+ if Head^ <> #0 then
+ Strings.Add(Head);
+ Inc(Tail);
+ until EOS;
+ end;
+
+ procedure ParseAttributes(Strings: TStrings; const Value: string);
+ var
+ P: PChar;
+ Tmp: string;
+ begin
+ Strings.Clear;
+ Tmp := Value;
+ UniqueString(Tmp);
+ P := PChar(Tmp);
+// if P^ in [#0, '<', '>'] then
+ if CharInSet(P^, [#0, '>']) then
+ Exit;
+ // skip first word (the tag) and any whitespace
+ while (P^ <> #0) and (P <> nil) do
+ begin
+ if P^ = ' ' then
+ begin
+ Inc(P);
+ Break;
+ end;
+ Inc(P);
+ end;
+ InnerParseAttributes(P, Strings);
+ end;
+
+begin
+ if (FKeys.Count = 0) and (FParser.Count <> 0) then
+ SetParser(FParser);
+ FContent := Str;
+ AttributesList := TStringList.Create;
+ try
+ if FKeys.Count > 0 then
+ begin
+ FTagList.Clear;
+ for I := 0 to FKeys.Count - 1 do
+ begin
+ StartTag1 := TJvParserInfo(FKeys.Objects[I]).StartTag;
+ Starttag2 := '';
+ if (Length(StartTag1) > 2) and (StartTag1[Length(StartTag1)] = '>') then
+ begin
+ // split the tag so tags with attributes can be found
+ Delete(StartTag1, Length(StartTag1), 1);
+ StartTag2 := '>';
+ end;
+ J := 1;
+ while J <> 0 do
+ begin
+ // changed from StrSearch(case sensitive) to StrFind (case insensitive)
+ J := StrFind(StartTag1, Str, J);
+ if J > 0 then
+ begin
+ // changed from StrSearch(case sensitive) to StrFind (case insensitive)
+ K := StrFind(TJvParserInfo(FKeys.Objects[I]).EndTag, Str, J);
+ TagInfo.BeginPos := J;
+ TagInfo.EndPos := K + Length(TJvParserInfo(FKeys.Objects[I]).EndTag);
+ TagInfo.Key := I;
+ case TJvParserInfo(FKeys.Objects[I]).TakeText of
+ 0: //Between limits
+ begin
+ if StartTag2 = '' then
+ TagInfo.BeginContext := J + Length(TJvParserInfo(FKeys.Objects[I]).StartTag)
+ else
+ // changed from StrSearch(case sensitive) to StrFind (case insensitive)
+ TagInfo.BeginContext := StrFind(StartTag2, Str, j) + 1;
+ TagInfo.EndContext := K;
+ end;
+ 1: //All before start tag
+ begin
+ TagInfo.BeginContext := 1;
+ TagInfo.EndContext := J;
+ end;
+ 2: //All after start tag
+ begin
+ if StartTag2 = '' then
+ TagInfo.BeginContext := J + Length(TJvParserInfo(FKeys.Objects[I]).StartTag)
+ else
+ // changed from StrSearch(case sensitive) to StrFind (case insensitive)
+ TagInfo.BeginContext := StrFind(StartTag2, Str, j) + 1;
+ TagInfo.EndContext := Length(Str);
+ end;
+ 3: //The whole line if containing start tag
+ begin
+ TagInfo.BeginContext := J;
+ // changed from StrSearch(case sensitive) to StrFind (case insensitive)
+ TagInfo.EndContext := StrFind(Lf, Str, J);
+ end;
+ end;
+ FTagList.AddValue(TagInfo);
+ J := J + Length(TJvParserInfo(FKeys.Objects[I]).StartTag);
+ end;
+ end;
+ end;
+ end;
+ FTagList.Sort(@CompareTags);
+ with FTagList do
+ begin
+ for Index := 0 to Count - 1 do
+ begin
+ // Str2 now contains eveything between the start and end tags
+ Str2 := Copy(Str, PTagInfo(Items[Index])^.BeginContext,
+ PTagInfo(Items[Index])^.EndContext - PTagInfo(Items[Index])^.BeginContext);
+ if StartTag2 = '' then
+ Str3 := ''
+ else
+ //Str3 contains the start tag as found, may include attributes or other tags
+ Str3 := Copy(Str, PTagInfo(Items[Index])^.BeginPos,
+ PTagInfo(Items[Index])^.BeginContext - PTagInfo(Items[Index])^.BeginPos - 1);
+ if Assigned(FOnKeyFound) then
+ FOnKeyFound(Self, FKeys[PTagInfo(Items[Index])^.Key], Str2, Str);
+ if Assigned(FOnKeyFoundEx) then
+ begin
+ if Str3 <> '' then
+ ParseAttributes(AttributesList, Str3)
+ else
+ ParseAttributes(AttributesList, Str2);
+ FOnKeyFoundEx(Self, FKeys[PTagInfo(Items[Index])^.Key], Str2, Str,
+ PTagInfo(Items[Index])^, AttributesList);
+ end;
+ end;
+ end;
+ finally
+ AttributesList.Free;
+ end;
+end;
+
+procedure TJvHTMLParser.AddCondition(const Keyword: string;
+ const StartTag: string; const EndTag: string; TextSelection: Integer);
+var
+ Obj: TJvParserInfo;
+begin
+ Obj := TJvParserInfo.Create;
+ Obj.StartTag := StartTag;
+ Obj.EndTag := EndTag;
+ Obj.TakeText := TextSelection;
+ FKeys.AddObject(Keyword, TObject(Obj));
+end;
+
+procedure TJvHTMLParser.RemoveCondition(Index: Integer);
+begin
+ FKeys.Objects[Index].Free;
+ FKeys.Delete(Index);
+end;
+
+procedure TJvHTMLParser.ClearConditions;
+var
+ Index: Integer;
+begin
+ FParser.Clear;
+ for Index := FKeys.Count - 1 downto 0 do
+ FKeys.Objects[Index].Free;
+ FKeys.Clear;
+end;
+
+procedure TJvHTMLParser.GetCondition(Index: Integer; var Keyword, StartTag, EndTag: string);
+begin
+ Keyword := FKeys[Index];
+ StartTag := TJvParserInfo(FKeys.Objects[Index]).StartTag;
+ EndTag := TJvParserInfo(FKeys.Objects[Index]).EndTag;
+end;
+
+procedure TJvHTMLParser.GetCondition(Index: Integer; var Keyword, StartTag, EndTag: string;
+ var TextSelection: Integer);
+begin
+ GetCondition(Index, Keyword, StartTag, EndTag);
+ TextSelection := TJvParserInfo(FKeys.Objects[Index]).TakeText;
+end;
+
+function TJvHTMLParser.GetConditionsCount: Integer;
+begin
+ Result := FKeys.Count;
+end;
+
+procedure TJvHTMLParser.SetTagList(const Value: TTagInfoList);
+begin
+ FTagList := Value;
+end;
+
+//=== { TTagInfoList } =======================================================
+
+procedure TTagInfoList.AddValue(const Value: TTagInfo);
+var
+ P: PTagInfo;
+begin
+ GetMem(P, SizeOf(TTagInfo));
+ if P <> nil then
+ begin
+ P^ := Value;
+ Add(P);
+ end;
+end;
+
+procedure TTagInfoList.Clear;
+var
+ I: Integer;
+begin
+ for I := 0 to Count - 1 do
+ FreeMem(Items[I], SizeOf(TTagInfo));
+ inherited Clear;
+end;
+
+end.
diff --git a/components/jvcllaz/run/JvNet/jvstringlisttohtml.pas b/components/jvcllaz/run/JvNet/jvstringlisttohtml.pas
new file mode 100644
index 000000000..6bec869d8
--- /dev/null
+++ b/components/jvcllaz/run/JvNet/jvstringlisttohtml.pas
@@ -0,0 +1,160 @@
+{-----------------------------------------------------------------------------
+The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/MPL-1.1.html
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+the specific language governing rights and limitations under the License.
+
+The Original Code is: JvStringListToHtml.PAS, released on 2001-02-28.
+
+The Initial Developer of the Original Code is Sébastien Buysse [sbuysse att buypin dott com]
+Portions created by Sébastien Buysse are Copyright (C) 2001 Sébastien Buysse.
+All Rights Reserved.
+
+Contributor(s): Michael Beck [mbeck att bigfoot dott com].
+
+You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
+located at http://jvcl.delphi-jedi.org
+
+Known Issues:
+-----------------------------------------------------------------------------}
+// $Id$
+
+unit JvStringListToHtml;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ SysUtils, Classes;
+// JvComponentBase;
+
+type
+ TJvStringListToHtml = class(TComponent) // TJvComponent)
+ private
+ FStrings: TStringList;
+ FHTML: TStringList;
+ FHTMLTitle: string;
+ FHTMLLineBreak: string;
+ FIncludeHeader: Boolean;
+ function GetHTML: TStrings;
+ function GetStrings: TStrings;
+ procedure SetStrings(const Value: TStrings);
+ procedure DoStringsChange(Sender: TObject);
+ procedure SetHTML(const Value: TStrings);
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ procedure ConvertToHTML(Source: TStrings; const FileName: string);
+ procedure ConvertToHTMLStrings(Source, Destination: TStrings);
+ published
+ property HTML: TStrings read GetHTML write SetHTML stored False;
+ property Strings: TStrings read GetStrings write SetStrings;
+ property HTMLLineBreak: string read FHTMLLineBreak write FHTMLLineBreak;
+ property HTMLTitle: string read FHTMLTitle write FHTMLTitle;
+ property IncludeHeader: Boolean read FIncludeHeader write FIncludeHeader default True;
+ end;
+
+
+implementation
+
+procedure ConvertStringsToHTML(Source, Destination: TStrings; const HTMLTitle, HTMLLineBreak: string; IncludeHeader: Boolean);
+var
+ I: Integer;
+begin
+ if (Source = nil) or (Destination = nil) then
+ Exit;
+ Destination.BeginUpdate;
+ Source.BeginUpdate;
+ try
+ if IncludeHeader then
+ begin
+ Destination.Add('');
+ Destination.Add('' + HTMLTitle + ' ');
+ Destination.Add('');
+ end;
+ for I := 0 to Source.Count - 1 do
+ Destination.Add(Source[I] + HTMLLineBreak);
+ if IncludeHeader then
+ begin
+ Destination.Add('');
+ Destination.Add('');
+ end;
+ finally
+ Source.EndUpdate;
+ Destination.EndUpdate;
+ end;
+end;
+
+procedure TJvStringListToHtml.ConvertToHTML(Source: TStrings; const FileName: string);
+var
+ Dest: TStringList;
+begin
+ if Source = nil then
+ Exit;
+ Dest := TStringList.Create;
+ try
+ ConvertStringsToHTML(Source, Dest, HTMLTitle, HTMLLineBreak, True);
+ Dest.SaveToFile(FileName);
+ finally
+ Dest.Free;
+ end;
+end;
+
+procedure TJvStringListToHtml.ConvertToHTMLStrings(Source, Destination: TStrings);
+begin
+ ConvertStringsToHTML(Source, Destination, HTMLTitle, HTMLLineBreak, IncludeHeader);
+end;
+
+constructor TJvStringListToHtml.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FStrings := TStringList.Create;
+ FHTML := TStringList.Create;
+ FStrings.OnChange := @DoStringsChange;
+ FHTMLLineBreak := ' ';
+ FHTMLTitle := 'Converted by TJvStringListToHtml';
+ FIncludeHeader := True;
+end;
+
+destructor TJvStringListToHtml.Destroy;
+begin
+ FreeAndNil(FStrings);
+ FreeAndNil(FHTML);
+ inherited Destroy;
+end;
+
+procedure TJvStringListToHtml.DoStringsChange(Sender: TObject);
+begin
+ FreeAndNil(FHTML);
+end;
+
+function TJvStringListToHtml.GetHTML: TStrings;
+begin
+ if ComponentState * [csLoading, csDestroying] <> [] then
+ if FHTML.Count = 0 then
+ ConvertToHTMLStrings(Strings, FHTML);
+ Result := FHTML;
+end;
+
+procedure TJvStringListToHtml.SetHTML(const Value: TStrings);
+begin
+ // do nothing
+end;
+
+function TJvStringListToHtml.GetStrings: TStrings;
+begin
+ Result := FStrings;
+end;
+
+procedure TJvStringListToHtml.SetStrings(const Value: TStrings);
+begin
+ FStrings.Assign(Value);
+ FHTML.Clear;
+end;
+
+end.
diff --git a/components/jvcllaz/run/JvNet/jvstrtohtml.pas b/components/jvcllaz/run/JvNet/jvstrtohtml.pas
new file mode 100644
index 000000000..c532c2bd6
--- /dev/null
+++ b/components/jvcllaz/run/JvNet/jvstrtohtml.pas
@@ -0,0 +1,492 @@
+{-----------------------------------------------------------------------------
+The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/MPL-1.1.html
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+the specific language governing rights and limitations under the License.
+
+The Original Code is: JvStrToHtml.PAS, released on 2001-02-28.
+
+The Initial Developer of the Original Code is Sébastien Buysse [sbuysse att buypin dott com]
+Portions created by Sébastien Buysse are Copyright (C) 2001 Sébastien Buysse.
+All Rights Reserved.
+
+Contributor(s): Michael Beck [mbeck att bigfoot dott com].
+ Andreas Hausladen [Andreas dott Hausladen att gmx dott de]
+
+You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
+located at http://jvcl.delphi-jedi.org
+
+Known Issues:
+-----------------------------------------------------------------------------}
+// $Id$
+
+unit JvStrToHtml;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ SysUtils, Classes;
+// JvComponentBase;
+
+type
+ TJvStrToHtml = class(TComponent) // TJvComponent)
+ private
+ FHtml: string;
+ FValue: string;
+ procedure SetHtml(const Value: string);
+ procedure SetValue(const Value: string);
+ public
+ constructor Create(AOwner: TComponent); override;
+ function TextToHtml(const Text: string): string;
+ function HtmlToText(const Text: string): string;
+ published
+ property Text: string read FValue write SetValue;
+ property Html: string read FHtml write SetHtml;
+ end;
+
+function StringToHtml(const Value: string): string;
+function HtmlToString(const Value: string): string;
+//function CharToHtml(Ch: Char): string;
+
+
+implementation
+
+uses
+ LazUtf8;
+
+type
+ TJvHtmlCodeRec = record
+ Ch: Cardinal;
+ Html: string;
+ end;
+
+const
+ { References:
+ http://www.w3.org/TR/REC-html40/charset.html#h-5.3
+ http://www.w3.org/TR/REC-html40/sgml/entities.html#h-24.2.1
+ http://www.w3.org/TR/REC-html40/sgml/entities.html#h-24.4.1
+ }
+
+ Conversions: array [0..240] of TJvHtmlCodeRec = (
+ (Ch: 34; Html: '"'),
+ (Ch: 38; Html: '&'),
+ (Ch: 39; Html: '''),
+ (Ch: 60; Html: '<'),
+ (Ch: 62; Html: '>'),
+ (Ch: 160; Html: ' '),
+ (Ch: 161; Html: '¡'),
+ (Ch: 162; Html: '¢'),
+ (Ch: 163; Html: '£'),
+ (Ch: 164; Html: '¤'),
+ (Ch: 165; Html: '¥'),
+ (Ch: 166; Html: '¦'),
+ (Ch: 167; Html: '§'),
+ (Ch: 168; Html: '¨'),
+ (Ch: 169; Html: '©'),
+ (Ch: 170; Html: 'ª'),
+ (Ch: 171; Html: '«'),
+ (Ch: 172; Html: '¬'),
+ (Ch: 173; Html: ''),
+ (Ch: 174; Html: '®'),
+ (Ch: 175; Html: '¯'),
+ (Ch: 176; Html: '°'),
+ (Ch: 177; Html: '±'),
+ (Ch: 178; Html: '²'),
+ (Ch: 179; Html: '³'),
+ (Ch: 180; Html: '´'),
+ (Ch: 181; Html: 'µ'),
+ (Ch: 182; Html: '¶'),
+ (Ch: 183; Html: '·'),
+ (Ch: 184; Html: '¸'),
+ (Ch: 185; Html: '¹'),
+ (Ch: 186; Html: 'º'),
+ (Ch: 187; Html: '»'),
+ (Ch: 188; Html: '¼'),
+ (Ch: 189; Html: '½'),
+ (Ch: 190; Html: '¾'),
+ (Ch: 191; Html: '¿'),
+ (Ch: 192; Html: 'À'),
+ (Ch: 193; Html: 'Á'),
+ (Ch: 194; Html: 'Â'),
+ (Ch: 195; Html: 'Ã'),
+ (Ch: 196; Html: 'Ä'),
+ (Ch: 197; Html: 'Å'),
+ (Ch: 198; Html: 'Æ'),
+ (Ch: 199; Html: 'Ç'),
+ (Ch: 200; Html: 'È'),
+ (Ch: 201; Html: 'É'),
+ (Ch: 202; Html: 'Ê'),
+ (Ch: 203; Html: 'Ë'),
+ (Ch: 204; Html: 'Ì'),
+ (Ch: 205; Html: 'Í'),
+ (Ch: 206; Html: 'Î'),
+ (Ch: 207; Html: 'Ï'),
+ (Ch: 208; Html: 'Ð'),
+ (Ch: 209; Html: 'Ñ'),
+ (Ch: 210; Html: 'Ò'),
+ (Ch: 211; Html: 'Ó'),
+ (Ch: 212; Html: 'Ô'),
+ (Ch: 213; Html: 'Õ'),
+ (Ch: 214; Html: 'Ö'),
+ (Ch: 215; Html: '×'),
+ (Ch: 216; Html: 'Ø'),
+ (Ch: 217; Html: 'Ù'),
+ (Ch: 218; Html: 'Ú'),
+ (Ch: 219; Html: 'Û'),
+ (Ch: 220; Html: 'Ü'),
+ (Ch: 221; Html: 'Ý'),
+ (Ch: 222; Html: 'Þ'),
+ (Ch: 223; Html: 'ß'),
+ (Ch: 224; Html: 'à'),
+ (Ch: 225; Html: 'á'),
+ (Ch: 226; Html: 'â'),
+ (Ch: 227; Html: 'ã'),
+ (Ch: 228; Html: 'ä'),
+ (Ch: 229; Html: 'å'),
+ (Ch: 230; Html: 'æ'),
+ (Ch: 231; Html: 'ç'),
+ (Ch: 232; Html: 'è'),
+ (Ch: 233; Html: 'é'),
+ (Ch: 234; Html: 'ê'),
+ (Ch: 235; Html: 'ë'),
+ (Ch: 236; Html: 'ì'),
+ (Ch: 237; Html: 'í'),
+ (Ch: 238; Html: 'î'),
+ (Ch: 239; Html: 'ï'),
+ (Ch: 240; Html: 'ð'),
+ (Ch: 241; Html: 'ñ'),
+ (Ch: 242; Html: 'ò'),
+ (Ch: 243; Html: 'ó'),
+ (Ch: 244; Html: 'ô'),
+ (Ch: 245; Html: 'õ'),
+ (Ch: 246; Html: 'ö'),
+ (Ch: 247; Html: '÷'),
+ (Ch: 248; Html: 'ø'),
+ (Ch: 249; Html: 'ù'),
+ (Ch: 250; Html: 'ú'),
+ (Ch: 251; Html: 'û'),
+ (Ch: 252; Html: 'ü'),
+ (Ch: 253; Html: 'ý'),
+ (Ch: 254; Html: 'þ'),
+ (Ch: 255; Html: 'ÿ'),
+ (Ch: 338; Html: 'Œ'),
+ (Ch: 339; Html: 'œ'),
+ (Ch: 352; Html: 'Š'),
+ (Ch: 353; Html: 'š'),
+ (Ch: 376; Html: 'Ÿ'),
+ (Ch: 402; Html: 'ƒ'),
+ (Ch: 710; Html: 'ˆ'),
+ (Ch: 732; Html: '˜'),
+ (Ch: 913; Html: 'Α'),
+ (Ch: 914; Html: 'Β'),
+ (Ch: 915; Html: 'Γ'),
+ (Ch: 916; Html: 'Δ'),
+ (Ch: 917; Html: 'Ε'),
+ (Ch: 918; Html: 'Ζ'),
+ (Ch: 919; Html: 'Η'),
+ (Ch: 920; Html: 'Θ'),
+ (Ch: 921; Html: 'Ι'),
+ (Ch: 922; Html: 'Κ'),
+ (Ch: 923; Html: 'Λ'),
+ (Ch: 924; Html: 'Μ'),
+ (Ch: 925; Html: 'Ν'),
+ (Ch: 926; Html: 'Ξ'),
+ (Ch: 927; Html: 'Ο'),
+ (Ch: 928; Html: 'Π'),
+ (Ch: 929; Html: 'Ρ'),
+ (Ch: 931; Html: 'Σ'),
+ (Ch: 932; Html: 'Τ'),
+ (Ch: 933; Html: 'Υ'),
+ (Ch: 934; Html: 'Φ'),
+ (Ch: 935; Html: 'Χ'),
+ (Ch: 936; Html: 'Ψ'),
+ (Ch: 937; Html: 'Ω'),
+ (Ch: 945; Html: 'α'),
+ (Ch: 946; Html: 'β'),
+ (Ch: 947; Html: 'γ'),
+ (Ch: 948; Html: 'δ'),
+ (Ch: 949; Html: 'ε'),
+ (Ch: 950; Html: 'ζ'),
+ (Ch: 951; Html: 'η'),
+ (Ch: 952; Html: 'θ'),
+ (Ch: 953; Html: 'ι'),
+ (Ch: 954; Html: 'κ'),
+ (Ch: 955; Html: 'λ'),
+ (Ch: 956; Html: 'μ'),
+ (Ch: 957; Html: 'ν'),
+ (Ch: 958; Html: 'ξ'),
+ (Ch: 959; Html: 'ο'),
+ (Ch: 960; Html: 'π'),
+ (Ch: 961; Html: 'ρ'),
+ (Ch: 962; Html: 'ς'),
+ (Ch: 963; Html: 'σ'),
+ (Ch: 964; Html: 'τ'),
+ (Ch: 965; Html: 'υ'),
+ (Ch: 966; Html: 'φ'),
+ (Ch: 967; Html: 'χ'),
+ (Ch: 968; Html: 'ψ'),
+ (Ch: 969; Html: 'ω'),
+ (Ch: 977; Html: 'ϑ'),
+ (Ch: 978; Html: 'ϒ'),
+ (Ch: 982; Html: 'ϖ'),
+ (Ch: 8194; Html: ' '),
+ (Ch: 8195; Html: ' '),
+ (Ch: 8201; Html: ' '),
+ (Ch: 8204; Html: ''),
+ (Ch: 8205; Html: ''),
+ (Ch: 8206; Html: ''),
+ (Ch: 8207; Html: ''),
+ (Ch: 8211; Html: '–'),
+ (Ch: 8212; Html: '—'),
+ (Ch: 8216; Html: '‘'),
+ (Ch: 8217; Html: '’'),
+ (Ch: 8218; Html: '‚'),
+ (Ch: 8220; Html: '“'),
+ (Ch: 8221; Html: '”'),
+ (Ch: 8222; Html: '„'),
+ (Ch: 8224; Html: '†'),
+ (Ch: 8225; Html: '‡'),
+ (Ch: 8226; Html: '•'),
+ (Ch: 8230; Html: '…'),
+ (Ch: 8240; Html: '‰'),
+ (Ch: 8242; Html: '′'),
+ (Ch: 8243; Html: '″'),
+ (Ch: 8249; Html: '‹'),
+ (Ch: 8250; Html: '›'),
+ (Ch: 8254; Html: '‾'),
+ (Ch: 8364; Html: '€'),
+ (Ch: 8482; Html: '™'),
+ (Ch: 8592; Html: '←'),
+ (Ch: 8593; Html: '↑'),
+ (Ch: 8594; Html: '→'),
+ (Ch: 8595; Html: '↓'),
+ (Ch: 8596; Html: '↔'),
+ (Ch: 8629; Html: '↵'),
+ (Ch: 8704; Html: '∀'),
+ (Ch: 8706; Html: '∂'),
+ (Ch: 8707; Html: '∃'),
+ (Ch: 8709; Html: '∅'),
+ (Ch: 8711; Html: '∇'),
+ (Ch: 8712; Html: '∈'),
+ (Ch: 8713; Html: '∉'),
+ (Ch: 8715; Html: '∋'),
+ (Ch: 8719; Html: '∏'),
+ (Ch: 8721; Html: '∑'),
+ (Ch: 8722; Html: '−'),
+ (Ch: 8727; Html: '∗'),
+ (Ch: 8730; Html: '√'),
+ (Ch: 8733; Html: '∝'),
+ (Ch: 8734; Html: '∞'),
+ (Ch: 8736; Html: '∠'),
+ (Ch: 8743; Html: '∧'),
+ (Ch: 8744; Html: '∨'),
+ (Ch: 8745; Html: '∩'),
+ (Ch: 8746; Html: '∪'),
+ (Ch: 8747; Html: '∫'),
+ (Ch: 8756; Html: '∴'),
+ (Ch: 8764; Html: '∼'),
+ (Ch: 8773; Html: '≅'),
+ (Ch: 8776; Html: '≈'),
+ (Ch: 8800; Html: '≠'),
+ (Ch: 8801; Html: '≡'),
+ (Ch: 8804; Html: '≤'),
+ (Ch: 8805; Html: '≥'),
+ (Ch: 8834; Html: '⊂'),
+ (Ch: 8835; Html: '⊃'),
+ (Ch: 8836; Html: '⊄'),
+ (Ch: 8838; Html: '⊆'),
+ (Ch: 8839; Html: '⊇'),
+ (Ch: 8853; Html: '⊕'),
+ (Ch: 8855; Html: '⊗'),
+ (Ch: 8869; Html: '⊥'),
+ (Ch: 8901; Html: '⋅'),
+ (Ch: 8968; Html: '⌈'),
+ (Ch: 8969; Html: '⌉'),
+ (Ch: 8970; Html: '⌊'),
+ (Ch: 8971; Html: '⌋'),
+ (Ch: 9674; Html: '◊'),
+ (Ch: 9824; Html: '♠'),
+ (Ch: 9827; Html: '♣'),
+ (Ch: 9829; Html: '♥'),
+ (Ch: 9830; Html: '♦')
+ );
+
+var
+ ConversionsHash: array of Word;
+
+{$IFNDEF UNICODE}
+const
+ MB_ERR_INVALID_CHARS = 8;
+{$ENDIF ~UNICODE}
+
+{ TJvStrToHtml }
+
+constructor TJvStrToHtml.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FValue := '';
+ FHtml := '';
+end;
+
+function TJvStrToHtml.HtmlToText(const Text: string): string;
+begin
+ Result := HtmlToString(Text);
+end;
+
+procedure TJvStrToHtml.SetHtml(const Value: string);
+begin
+ FValue := HtmlToText(Value);
+end;
+
+procedure TJvStrToHtml.SetValue(const Value: string);
+begin
+ FHtml := TextToHtml(Value);
+end;
+
+function TJvStrToHtml.TextToHtml(const Text: string): string;
+begin
+ Result := StringToHtml(Text);
+end;
+
+function GetHtmlHash(const S: string): Word;
+var
+ I: Integer;
+begin
+ Result := Length(S);
+ for I := 1 to Length(S) do
+ Result := Word(Result + Ord(S[I]) shl (I mod 4));
+end;
+
+procedure InitConversionsHash;
+var
+ I: Integer;
+begin
+ SetLength(ConversionsHash, Length(Conversions));
+ for I := 0 to High(ConversionsHash) do
+ ConversionsHash[I] := GetHtmlHash(Conversions[I].Html);
+end;
+
+function StringToHtml(const Value: String): String;
+var
+ ResultLen: Integer;
+ CurrPos: Integer;
+ P, PEnd: PChar;
+
+ procedure Append(s: String);
+ var
+ n: Integer;
+ begin
+ n := Length(s);
+ if CurrPos + n > ResultLen then begin
+ ResultLen := ResultLen + 100;
+ SetLength(Result, ResultLen);
+ end;
+ Move(s[1], Result[CurrPos], n);
+ inc(CurrPos, n);
+ end;
+
+var
+ J, n: Integer;
+ ch: Cardinal;
+ found: Boolean;
+begin
+ if Value = '' then begin
+ Result := '';
+ exit;
+ end;
+
+ ResultLen := Length(Value);
+ SetLength(Result, ResultLen);
+
+ P := @Value[1];
+ PEnd := @Value[ResultLen];
+ CurrPos := 1;
+ while P <= PEnd do begin
+ n := 1;
+ if P^ in ['a'..'z', 'A'..'Z', '0'..'9', '_', ' '] then
+ Append(P^)
+ else begin
+ ch := UTF8CodePointToUniCode(P, n);
+ found := false;
+ for J := Low(Conversions) to High(Conversions) do
+ if ch = Conversions[J].Ch then begin
+ Append(Conversions[J].Html);
+ found := true;
+ break;
+ end;
+ if not found then
+ Append(Format('%d;', [ch]));
+ end;
+ inc(P, n);
+ end;
+ SetLength(Result, CurrPos-1);
+end;
+
+function HtmlToString(const Value: String): String;
+var
+ ResultLen: Integer;
+ P, PEnd: PChar;
+ CurrPos: Integer;
+
+ procedure Append(s: String);
+ var
+ n: Integer;
+ begin
+ n := Length(s);
+ Move(s[1], Result[CurrPos], n);
+ inc(CurrPos, n);
+ end;
+
+var
+ html: String;
+ found: Boolean;
+ J: Integer;
+begin
+ if Value = '' then begin
+ Result := '';
+ exit;
+ end;
+
+ ResultLen := Length(Value);
+ SetLength(Result, ResultLen);
+
+ P := @Value[1];
+ PEnd := @Value[ResultLen];
+ CurrPos := 1;
+
+ while P <= PEnd do begin
+ if P^ = '&' then begin
+ html := '&';
+ while P < PEnd do begin
+ inc(P);
+ html := html + P^;
+ if P^ = ';' then break;
+ end;
+ found := false;
+ for J := Low(Conversions) to High(Conversions) do
+ if html = Conversions[J].Html then begin
+ Append(UnicodeToUTF8(Conversions[j].Ch));
+ found := true;
+ break;
+ end;
+ if not found then begin
+ Delete(html, Length(html), 1);
+ Delete(html, 1, 1);
+ if html[1] = 'x' then html[1] := '$';
+ Append(UnicodeToUTF8(StrToInt(html)));
+ end;
+ end else
+ Append(P^);
+ inc(P);
+ end;
+ SetLength(Result, CurrPos-1);
+end;
+
+end.
+