OSDN Git Service

レスアンカー付加ルーチンの高速化
[gikonavigoeson/gikonavi.git] / HTMLCreate.pas
1 unit HTMLCreate;
2
3 interface
4
5 uses
6         Windows, Messages, SysUtils, Classes, {Graphics,} Controls, {Forms,}
7         ComCtrls, IniFiles, ShellAPI, Math, GikoSystem,
8 {$IF Defined(DELPRO) }
9         SHDocVw,
10         MSHTML,
11 {$ELSE}
12         SHDocVw_TLB,
13         MSHTML_TLB,
14 {$IFEND}
15         {HttpApp,} YofUtils, {URLMon,} BoardGroup, {gzip,} {Dolib,}
16         {bmRegExp,} AbonUnit,   MojuUtils, Setting,
17         ExternalBoardManager, ExternalBoardPlugInMain{,}
18         {Sort,} ,GikoBayesian;
19
20 type
21         THTMLCreate = class(TObject)
22         private
23                 { Private \90é\8c¾ }
24                 anchorLen                       : Integer;
25                 pURLCHARs,pURLCHARe : PChar;
26                 pANCHORs, pANCHORe  : PChar;
27                 pCTAGLs,  pCTAGLe   : PChar;
28                 pCTAGUs,  pCTAGUe   : PChar;
29                 pREF_MARKSs : array[0..9] of PChar;
30                 pREF_MARKSe : array[0..9] of PChar;
31                 constructor Create;
32
33                 function AddBeProfileLink(AID : string; ANum: Integer):string ;
34                 procedure CreateUsePluginHTML(doc: Variant; ThreadItem: TThreadItem; var sTitle: string);
35                 procedure CreateUseSKINHTML(doc: Variant; ThreadItem: TThreadItem; ReadList: TStringList);
36                 procedure CreateUseCSSHTML(doc: Variant; ThreadItem: TThreadItem; ReadList: TStringList; sTitle: string );
37                 procedure CreateDefaultHTML (doc: Variant; ThreadItem: TThreadItem; ReadList: TStringList; sTitle: string );
38                 function ConvertResAnchor(res: string): string;
39                 procedure separateNumber(var st: String; var et: String; const Text, Separator: String);
40         public
41                 { Public \90é\8c¾ }
42                 function AddAnchorTag(s: string): string;
43                 function LoadFromSkin(fileName: string; ThreadItem: TThreadItem; SizeByte: Integer): string;
44                 function SkinedRes(skin: string; Res: TResRec; No: string): string;
45                 function ConvRes(const Body, Bbs, Key,  ParamBBS, ParamKey, ParamStart, ParamTo, ParamNoFirst, ParamTrue : string; DatToHTML: boolean = false): string; overload;
46 //              function ConvRes(const Body, Bbs, Key,  ParamBBS, ParamKey, ParamStart, ParamTo, ParamNoFirst, ParamTrue, FullURL : string): string; overload;
47                 procedure CreateHTML2(doc: Variant; ThreadItem: TThreadItem; var sTitle: string);
48                 procedure CreateHTML3(var html: TStringList; ThreadItem: TThreadItem; var sTitle: string);
49         end;
50
51 var
52         HTMLCreater: THTMLCreate;
53
54 implementation
55
56 const
57         URL_CHAR: string = '0123456789'
58                                                                          + 'abcdefghijklmnopqrstuvwxyz'
59                                                                          + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
60                                                                          + '#$%&()*+,-./:;=?@[]^_`{|}~!''\';
61         ANCHOR_REF      = 'href=';
62         CLOSE_TAGAL = '</a>';
63         CLOSE_TAGAU = '</A>';
64         RES_REF                 = '&gt;&gt;';
65         REF_MARK: array[0..9] of string = ('http://', 'ttp://', 'tp://',
66                                                                          'ms-help://','p://', 'https://',
67                                                                          'www.', 'ftp://','news://','rtsp://');
68
69 constructor THTMLCreate.Create;
70 var
71         j : Integer;
72 begin
73         // + 3 \82Í 'href="' ('"'\82Â\82«)\82È\82Ç\82Ì\83o\83\8a\83G\81[\83V\83\87\83\93\82É\97]\97T\82ð\8e\9d\82½\82¹\82é\82½\82ß
74         anchorLen := Length( ANCHOR_REF ) + 3;
75         pANCHORs  := PChar(ANCHOR_REF);
76         pANCHORe  := pANCHORs + Length(ANCHOR_REF);
77         pURLCHARs := PChar(URL_CHAR);
78         pURLCHARe := pURLCHARs + Length(URL_CHAR);
79         pCTAGLs   := PChar(CLOSE_TAGAL);
80         pCTAGLe   := pCTAGLs + 4;
81         pCTAGUs   := PChar(CLOSE_TAGAU);
82         pCTAGUe   := pCTAGUs + 4;
83         for j := 0 to 9 do begin
84                 pREF_MARKSs[j] := PChar(REF_MARK[j]);
85                 pREF_MARKSe[j] := pREF_MARKSs[j] + Length(REF_MARK[j]);
86         end;
87 end;
88 // \83X\83L\83\93\82ð\93Ç\82Ý\8d\9e\82Ý\81A\92l\82ð\92u\8a·\82·\82é
89 function THTMLCreate.LoadFromSkin(
90         fileName: string;
91         ThreadItem: TThreadItem;
92         SizeByte: Integer
93 ): string;
94 var
95         Skin: TStringList;
96 begin
97
98         Skin := TStringList.Create;
99         try
100                 if FileExists( fileName ) then begin
101                         Skin.LoadFromFile( fileName );
102
103                         // \82â\82è\82©\82½\82ª\8bê\82µ\82¢\82¯\82Ç\81A\83I\83v\83V\83\87\83\93\83_\83C\83A\83\8d\83O\82Ì\83v\83\8c\83r\83\85\81[\97p try
104                         try
105                                 if ThreadItem.ParentBoard <> nil then
106                                         if ThreadItem.ParentBoard.ParentCategory <> nil then
107                                                 CustomStringReplace( Skin, '<BBSNAME/>', ThreadItem.ParentBoard.ParentCategory.ParenTBBS.Title);
108                                         CustomStringReplace( Skin, '<THREADURL/>', ThreadItem.URL);
109                         except end;
110                         CustomStringReplace( Skin, '<BOARDNAME/>', ThreadItem.ParentBoard.Title);
111                         CustomStringReplace( Skin, '<BOARDURL/>', ThreadItem.ParentBoard.URL);
112                         CustomStringReplace( Skin, '<THREADNAME/>', ThreadItem.Title);
113                         CustomStringReplace( Skin, '<SKINPATH/>', GikoSys.Setting.CSSFileName);
114                         CustomStringReplace( Skin, '<GETRESCOUNT/>', IntToStr( ThreadItem.Count - ThreadItem.NewResCount ));
115                         CustomStringReplace( Skin, '<NEWRESCOUNT/>', IntToStr( ThreadItem.NewResCount ));
116                         CustomStringReplace( Skin, '<ALLRESCOUNT/>', IntToStr( ThreadItem.Count ));
117
118                         CustomStringReplace( Skin, '<NEWDATE/>',FormatDateTime('yyyy/mm/dd(ddd) hh:mm', ThreadItem.RoundDate));
119                         CustomStringReplace( Skin, '<SIZEKB/>', IntToStr( Floor( SizeByte / 1024 ) ));
120                         CustomStringReplace( Skin, '<SIZE/>', IntToStr( SizeByte ));
121
122                         //----- \82Æ\82è\82 \82¦\82¸\82©\82¿\82ã\81`\82µ\82á\8cÝ\8a·\97p\81B\83R\83\81\83\93\83g\83A\83E\83g\82µ\82Ä\82à\82æ\82µ
123                         // \82â\82è\82©\82½\82ª\8bê\82µ\82¢\82¯\82Ç\81A\83I\83v\83V\83\87\83\93\83_\83C\83A\83\8d\83O\82Ì\83v\83\8c\83r\83\85\81[\97p try
124                         try
125                                 if ThreadItem.ParentBoard <> nil then
126                                         if ThreadItem.ParentBoard.ParentCategory <> nil then
127                                                 CustomStringReplace( Skin, '&BBSNAME', ThreadItem.ParentBoard.ParentCategory.ParenTBBS.Title);
128                                         CustomStringReplace( Skin, '&THREADURL', ThreadItem.URL);
129                         except end;
130                         CustomStringReplace( Skin, '&BOARDNAME', ThreadItem.ParentBoard.Title);
131                         CustomStringReplace( Skin, '&BOARDURL', ThreadItem.ParentBoard.URL);
132                         CustomStringReplace( Skin, '&THREADNAME', ThreadItem.Title);
133                         CustomStringReplace( Skin, '&SKINPATH', GikoSys.Setting.CSSFileName);
134                         CustomStringReplace( Skin, '&GETRESCOUNT', IntToStr( ThreadItem.NewReceive - 1 ));
135                         CustomStringReplace( Skin, '&NEWRESCOUNT', IntToStr( ThreadItem.NewResCount ));
136                         CustomStringReplace( Skin, '&ALLRESCOUNT', IntToStr( ThreadItem.AllResCount ));
137
138                         CustomStringReplace( Skin, '&NEWDATE', FormatDateTime('yyyy/mm/dd(ddd) hh:mm', ThreadItem.RoundDate));
139                         CustomStringReplace( Skin, '&SIZEKB', IntToStr( Floor( SizeByte / 1024 ) ));
140                         CustomStringReplace( Skin, '&SIZE', IntToStr( SizeByte ));
141                         //----- \82±\82±\82Ü\82Å
142                 end;
143                 Result := Skin.Text;
144         finally
145                 Skin.Free;
146         end;
147 end;
148
149 // \83\8c\83X\82Ì\92l\82ð\92u\8a·\82·\82é
150 function THTMLCreate.SkinedRes(
151         skin: string;
152         Res: TResRec;
153         No: string
154 ): string;
155 var
156         spamminess      : Extended;
157         wordCount               : TWordCount;
158 begin
159
160         wordCount := TWordCount.Create;
161         try
162                 spamminess := Floor( GikoSys.SpamParse(
163                         Res.FName + '<>' + Res.FMailTo + '<>' + Res.FBody, wordCount ) * 100 );
164
165                 Skin := CustomStringReplace( Skin, '<NUMBER/>',
166                         '<a href="menu:' + No + '" name="' + No + '">' + No + '</a>');
167                 Skin := CustomStringReplace( Skin, '<PLAINNUMBER/>', No);
168                 Skin := CustomStringReplace( Skin, '<NAME/>', '<b>' + Res.FName + '</b>');
169                 Skin := CustomStringReplace( Skin, '<MAILNAME/>',
170                         '<a href="mailto:' + Res.FMailTo + '"><b>' + Res.FName + '</b></a>');
171                 Skin := CustomStringReplace( Skin, '<MAIL/>', Res.FMailTo);
172                 Skin := CustomStringReplace( Skin, '<DATE/>', Res.FDateTime);
173                 Skin := CustomStringReplace( Skin, '<MESSAGE/>', Res.FBody);
174                 Skin := CustomStringReplace( Skin, '<SPAMMINESS/>', FloatToStr( spamminess ) );
175                 Skin := CustomStringReplace( Skin, '<NONSPAMMINESS/>', FloatToStr( 100 - spamminess ) );
176
177                 //----- \82©\82¿\82ã\81`\82µ\82á\8cÝ\8a·\97p\81B\83R\83\81\83\93\83g\83A\83E\83g\82µ\82Ä\82à\82æ\82µ
178                 Skin := CustomStringReplace( Skin, '&NUMBER',
179                         '<a href="menu:' + No + '" name="' + No + '">' + No + '</a>');
180                 Skin := CustomStringReplace( Skin, '&PLAINNUMBER', No);
181                 Skin := CustomStringReplace( Skin, '&NAME', '<b>' + Res.FName + '</b>');
182                 Skin := CustomStringReplace( Skin, '&MAILNAME',
183                         '<a href="mailto:' + Res.FMailTo + '"><b>' + Res.FName + '</b></a>');
184                 Skin := CustomStringReplace( Skin, '&MAIL', Res.FMailTo);
185                 Skin := CustomStringReplace( Skin, '&DATE', Res.FDateTime);
186                 Skin := CustomStringReplace( Skin, '&MESSAGE', Res.FBody);
187                 Skin := CustomStringReplace( Skin, '&SPAMMINESS', FloatToStr( spamminess ) );
188                 Skin := CustomStringReplace( Skin, '&NONSPAMMINESS', FloatToStr( 100 - spamminess ) );
189                 //----- \82±\82±\82Ü\82Å
190
191                 Result := Skin;
192         finally
193                 wordCount.Free;
194         end;
195
196 end;
197 (*************************************************************************
198  *http://\82Ì\95\8e\9a\97ñ\82ðanchor\83^\83O\95t\82«\82É\82·\82é\81B
199  *************************************************************************)
200 function THTMLCreate.AddAnchorTag(s: string): string;
201 var
202         url: string;
203         href: string;
204         i, j, b: Integer;
205         tmp: Integer;
206         idx, idx2: Integer;
207         pos : PChar;
208         pp, pe : PChar;
209 begin
210         Result := '';
211
212         while True do begin
213                 idx  := MaxInt;
214                 idx2 := MaxInt;
215                 pp := PChar(s);
216                 pe := pp + Length(s);
217
218                 for j := 0 to 9 do begin
219                         pos := AnsiStrPosEx(pp, pe, pREF_MARKSs[j], pREF_MARKSe[j]);
220                         if pos <> nil then begin
221                                 tmp := pos - pp + 1;
222                                 idx := Min(tmp, idx);
223                                 if idx = tmp then idx2 := j;   //\82Ç\82Ì\83}\81[\83N\82Å\88ø\82Á\82©\82©\82Á\82½\82©\82ð\95Û\91
224                         end;
225                 end;
226
227                 if idx = MaxInt then begin
228                         //\83\8a\83\93\83N\82ª\96³\82¢\82æ\81B
229                         Result := Result + s;
230                         Break;
231                 end;
232
233                 if (idx > 1) and (idx > anchorLen) and
234                         (AnsiStrPosEx(pp + idx - 1 - anchorLen, pp + idx, pANCHORs, pANCHORe) <> nil) then begin
235                         //\8aù\82É\83\8a\83\93\83N\83^\83O\82ª\82Â\82¢\82Ä\82¢\82é\82Á\82Û\82¢\82Æ\82«\82Í\83\80\83V
236                         //</a></A>\82ð\92T\82·\81A\8f¬\95\8e\9a\82Å\8c©\82Â\82©\82ç\82È\82¯\82ê\82Î\91å\95\8e\9a\82Å\8c\9f\8dõ
237                         pos := AnsiStrPosEx(pp + idx, pe, pCTAGLs, pCTAGLe);
238                         if pos = nil then
239                                 pos := AnsiStrPosEx(pp + idx, pe, pCTAGUs, pCTAGUe);
240                         if pos = nil then
241                                 b := Length(REF_MARK[idx2])
242                         else
243                                 b := pos - pp + 1;
244
245                         Result := Result + Copy(s, 1, idx + b);
246                         Delete(s, 1, idx + b);
247                         Continue;
248                 end;
249
250                 Result := Result + Copy(s, 1, idx - 1);
251                 Delete(s, 1, idx - 1);
252                 b := Length( s ) + 1;
253                 pp      := PChar(s);
254                 for i := 1 to b do begin
255                         pe := AnsiStrPosEx(pURLCHARs, pURLCHARe, pp, pp + 1);
256
257                         if pe = nil then begin
258                                 //URL\82\82á\82È\82¢\95\8e\9a\94­\8c©\81I\82Æ\82©\81A\95\8e\9a\82ª\82È\82­\82È\82Á\82½\81B
259                                 url := Copy(s, 1, i - 1);
260                                 case idx2 of
261                                         1 : href := 'h' + url;
262                                         2 : href := 'ht' + url;
263                                         4 : href := 'htt' + url;
264                                         6 : href := 'http://' + url;
265                                 else
266                                         href := url;
267                                 end;
268
269                                 Result := Result + '<a href="' + href + '" target="_blank">' + url + '</a>';
270                                 Delete(s, 1, i - 1);
271                                 Break;
272                         end;
273                         //\88ê\95\8e\9a\90i\82ß\82é\81B
274                         Inc(pp);
275                 end;
276         end;
277 end;
278
279 //\88ø\90\94\81AAID\81F\91Î\8fÛ\82Æ\82È\82é\93ú\95tID\95\8e\9a\97ñ\81AANum:\83\8c\83X\94Ô AURL\81F\82»\82Ì\83X\83\8c\83b\83h\82ÌURL
280 function THTMLCreate.AddBeProfileLink(AID : string; ANum: Integer):string ;
281 var
282         p : integer;
283         BNum, BMark : string;
284 begin
285         p := AnsiPos('BE:', AnsiUpperCase(AID));
286         if p > 0 then begin
287                 BNum := Copy(AID, p, Length(AID));
288                 AID := Copy(AID, 1, p - 1);
289                 p := AnsiPos('-', BNum);
290                 if p > 0 then begin
291                         BMark := '?' + Trim(Copy(BNum, p + 1, Length(BNum)));
292                         BNum := Copy(BNum, 1, p - 1);
293                 end;
294                 BNum := Trim(BNum);
295                 Result := AID + ' <a href="'  + BNum + '/' + IntToStr(ANum)
296                         + '" target=_blank>' + BMark + '</a>';
297         end else
298                 Result := AID;
299 end;
300 procedure THTMLCreate.separateNumber(var st: String; var et: String; const Text, Separator: String);
301 var
302         p : Integer;
303 begin
304         p := Pos(Separator,Text);
305         if (p > 0 ) then begin
306                 st := Copy(Text, 1, p - 1);
307                 et := Copy(Text, p + Length(Separator), Length(Text));
308         end else begin
309                 st := Text;
310                 et := Text;
311         end;
312 end;
313 (*************************************************************************
314  *
315  * from HotZonu
316  *************************************************************************)
317 function THTMLCreate.ConvRes(const Body, Bbs, Key,
318         ParamBBS, ParamKey, ParamStart, ParamTo, ParamNoFirst, ParamTrue : string;
319         DatToHTML: boolean = false): string;
320 const
321         GT      = '&gt;';
322         SN      = '0123456789';
323         FORMAT_LINK = '<a href="../test/read.cgi?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s" target="_blank">';
324 var
325         i : integer;
326         s : string;
327         sw: boolean;
328         cm: boolean;
329         No: string;
330         oc      : string;
331         pos, pmin : integer;
332         j : integer;
333         token : array[0..5] of string;
334         ch : string;
335         db : boolean;
336         len : integer;
337         rink : string;
338         function addResAnchor(const Left :string) : string;
339         var
340                 st,et : string;
341         begin
342                 //\8fI\92[\82Ü\82Å\8ds\82Á\82Ä\82Ì\8fI\97¹\82©\83`\83F\83b\83N
343                 if j <= len then begin
344                         if db then j := j - 2
345                         else j := j - 1;
346                 end;
347                 //\89½\82à\90\94\8e\9a\82ª\8c©\82Â\82©\82ç\82È\82¢\82Æ\82«
348                 if No = '' then begin
349                         Result := Left + Copy(s, 1, j - 1);
350                 end else begin
351                         separateNumber(st, et, No, '-');
352
353                         if not DatToHTML then begin
354                                 Result := Left + Format(FORMAT_LINK,
355                                                         [ParamBBS, Bbs, ParamKey, Key, ParamStart, st, ParamTo, et, ParamNoFirst, ParamTrue]);
356                         end else begin
357                                 Result := Left + Format('<a href="#%s">', [st]);
358                         end;
359                         Result := Result + Copy(s, 1, j - 1) + '</a>';
360                 end;
361                 Delete(s, 1, j - 1);
362         end;
363
364         procedure getNumberString;
365         begin
366                 while (j <= len) do begin
367                         if (ByteType(s, j) = mbSingleByte) then begin
368                                 //1byte\95\8e\9a
369                                 ch := s[j];
370                                 Inc(j);
371                                 db := false;
372                         end else begin
373                                 //2byte\95\8e\9a
374                                 ch := ZenToHan(Copy(s, j, 2));
375                                 Inc(j, 2);
376                                 db := true;
377                         end;
378
379                         if System.Pos(ch, SN) > 0 then begin
380                                 No := No + ch;
381                         end else if (ch = '-') then begin
382                                 if sw then break;
383                                 if No = '' then break;
384                                 No := No + ch;
385                                 sw := true;
386                         end else begin
387                                 break;
388                         end;
389                 end;
390         end;
391
392         function checkComma : boolean;
393         begin
394                 j := 1;
395                 len := Length(s);
396                 if ((len > 0) and (s[j] = ',')) or ((len > 1) and (ZenToHan(Copy(s, j ,2)) = ','))  then begin
397                         Result := true;
398                         if (ByteType(s, j) = mbSingleByte) then
399                                 Inc(j)
400                         else
401                                 Inc(j, 2);
402                         No := '';
403                 end else begin
404                         Result := false;
405                 end;
406         end;
407 begin
408         //s \82É\96{\95\82ð\91S\95\94\93ü\82ê\82é
409         s        :=     Body;
410         //\8c\8b\89Ê\82ð\83N\83\8a\83A
411         Result   :=     '';
412         //\8c\9f\8dõ\91Î\8fÛ\82Ì\95\8e\9a\97ñ\8cS
413         token[0] := GT + GT;
414         token[1] := GT;
415         token[2] := '\81\84\81\84';
416         token[3] := '\81\84';
417         token[4] := '<a ';
418         token[5] := '<A ';
419
420         //
421         while Length(s) > 2 do begin
422                 pmin := Length(s) + 1;
423                 i       := Length(token);
424                 for j := 0 to 5 do begin
425                         pos := AnsiPos(token[j], s);
426                         if pos <> 0 then begin
427                                 if pos < pmin then begin
428                                         //\82Ç\82ê\82Å\83q\83b\83g\82µ\82½\82©\95Û\91
429                                         i := j;
430                                         //\8dÅ\8f¬\92l\82ð\8dX\90V
431                                         pmin := pos;
432                                 end;
433                         end;
434                 end;
435
436                 //\83q\83b\83g\82µ\82½\95\8e\9a\97ñ\82Ì\88ê\82Â\8eè\91O\82Ü\82Å\8c\8b\89Ê\82É\83R\83s\81[
437                 Result := Result + Copy(s, 1, pmin - 1);
438                 Delete(s, 1, pmin - 1);
439
440                 if i = 6 then begin
441                         //\83q\83b\83g\82È\82µ
442                 end else if (i = 4) or (i = 5) then begin
443                         //'<a ' or '<A' \82Å\83q\83b\83g '</a>' or '</A>' \82Ü\82Å\83R\83s\81[
444                         pmin := AnsiPos('</a>' , s);
445                         pos := AnsiPos('</A>' , s);
446                         if (pmin <> 0) and (pos <> 0) then begin
447                                 if (pmin > pos) then begin
448                                         pmin := pos;
449                                 end;
450                         end else if (pos <> 0) then begin
451                                 pmin := pos;
452                         end;
453                         rink := Copy(s, 1, pmin + 3);
454                         Result := Result + rink;
455                         Delete(s, 1, pmin + 3);
456
457                         pmin := Length(rink);
458                         i       := Length(token);
459                         for j := 0 to 3 do begin
460                                 pos := AnsiPos(token[j], rink);
461                                 if pos <> 0 then begin
462                                         if pos < pmin then begin
463                                                 //\82Ç\82ê\82Å\83q\83b\83g\82µ\82½\82©\95Û\91
464                                                 i := j;
465                                                 //\8dÅ\8f¬\92l\82ð\8dX\90V
466                                                 pmin := pos;
467                                         end;
468                                 end;
469                         end;
470                         // \83\8c\83X\83A\83\93\83J\81[\82ª\8aÜ\82Ü\82ê\82Ä\82¢\82½\82ç,\82ª\91±\82­\8cÀ\82è\83A\83\93\83J\81[\82Æ\82µ\82Ä\88µ\82¤
471                         if i <= 3 then begin
472                                 No := '';
473                                 cm := checkComma;
474                                 len := Length(s);
475                                 while cm do begin
476                                         oc := '';
477                                         No := '';
478                                         sw := false;
479                                         db := false;
480                                         getNumberString;
481                                         Result := addResAnchor(Result);
482                                         cm := checkComma;
483                                 end;
484                         end;
485                 end else begin
486                         //\89½\82©\82µ\82ç\8c©\82Â\82©\82Á\82½\83p\83^\81[\83\93
487                         j := Length(token[i]) + 1;
488                         oc := '';
489                         No := '';
490                         sw := false;
491                         db := false;
492                         len := Length(s);
493                         getNumberString;
494                         Result := addResAnchor(Result);
495                 end;
496         end;
497         Result := Result + s;
498 end;
499
500 function THTMLCreate.ConvertResAnchor(res: string): string;
501 const
502         _HEAD : string = '<a href="../';
503         _TAIL : string = ' target="_blank">';
504         _ST: string = '&st=';
505         _TO: string = '&to=';
506         _STA: string = '&START=';
507         _END: string = '&END=';
508 var
509         i, j, k: Integer;
510         tmp: string;
511 begin
512         Result := '';
513         i := AnsiPos(_HEAD, res);
514         while i <> 0 do begin
515                 Result := Result + Copy(res, 1, i -1);
516                 Delete(res, 1, i - 1);
517                 j := AnsiPos(_TAIL, res);
518                 if j = 0 then begin
519                         Result := Result + res;
520                         Exit;
521                 end;
522                 tmp := Copy(res, 1, j - 1);
523                 Delete(res, 1, j + 16);
524                 if (AnsiPos(_ST, tmp) <> 0) and (AnsiPos(_TO, tmp) <> 0) then begin
525                         Delete(tmp, 1, AnsiPos(_ST, tmp) + 3);
526                         Delete(tmp, AnsiPos(_TO, tmp), Length(tmp));
527                         Result := Result + '<a href="#' + tmp + '">';
528                 end else if (AnsiPos(_STA, tmp) <> 0) and (AnsiPos(_END, tmp) <> 0) then begin
529                         Delete(tmp, 1, AnsiPos(_STA, tmp) + 6);
530                         Delete(tmp, AnsiPos(_END, tmp), Length(tmp));
531                         Result := Result + '<a href="#' + tmp + '">';
532                 end else begin
533                         k := LastDelimiter('/', tmp);
534                         Delete(tmp, 1, k);
535                         if AnsiPos('-', tmp) < AnsiPos('"', tmp) then
536                                 Delete(tmp, AnsiPos('-', tmp), Length(tmp))
537                         else
538                                 Delete(tmp, AnsiPos('"', tmp), Length(tmp));
539
540                         Result := Result + '<a href="#' + tmp + '">';
541                 end;
542                 i := AnsiPos(_HEAD, res);
543         end;
544         Result := Result + res;
545
546 end;
547
548 //Plugin\82ð\97\98\97p\82·\82éBoard\82Ì\83X\83\8c\83b\83h\82ÌHTML\82ð\8dì\90¬\82µ\82Ädoc\82É\8f\91\82«\8d\9e\82Þ
549 procedure THTMLCreate.CreateUsePluginHTML(doc: Variant; ThreadItem: TThreadItem; var sTitle: string);
550 var
551         i: integer;
552         NewReceiveNo: Integer;
553         boardPlugIn : TBoardPlugIn;
554         UserOptionalStyle: string;
555 begin
556         if ThreadItem <> nil then begin
557                 if ThreadItem.ParentBoard.IsBoardPlugInAvailable then begin
558                         //===== \83v\83\89\83O\83C\83\93\82É\82æ\82é\95\\8e¦
559                         boardPlugIn             := ThreadItem.ParentBoard.BoardPlugIn;
560                         NewReceiveNo    := ThreadItem.NewReceive;
561                         // \83t\83H\83\93\83g\82â\83T\83C\83Y\82Ì\90Ý\92è
562                         UserOptionalStyle := GikoSys.SetUserOptionalStyle;
563                         try
564                                 doc.open;
565                                 // \83w\83b\83_
566                                 doc.Write( boardPlugIn.GetHeader( DWORD( threadItem ),
567                                         '<style type="text/css">body {' + UserOptionalStyle + '}</style>' ) + #13#10 );
568                                 doc.Write('<p id="idSearch"></p>' + #13#10 );
569
570                                 for i := 0 to threadItem.Count - 1 do begin
571                                         // 1 \82Í\95K\82¸\95\\8e¦
572                                         if i <> 0 then begin
573                                                 // \95\\8e¦\94Í\88Í\82ð\8cÀ\92è
574                                                 case GikoSys.ResRange of
575                                                 Ord( grrKoko ):
576                                                         if ThreadItem.Kokomade > (i + 1) then
577                                                                 Continue;
578                                                 Ord( grrNew ):
579                                                         if NewReceiveNo > (i + 1) then
580                                                                 Continue;
581                                                 10..65535:
582                                                         if (threadItem.Count - i) > GikoSys.ResRange then
583                                                                 Continue;
584                                                 end;
585                                         end;
586
587                                         // \90V\92\85\83}\81[\83N
588                                         if (NewReceiveNo = (i + 1)) or ((NewReceiveNo = 0) and (i = 0)) then begin
589                                                 try
590                                                         if GikoSys.Setting.UseSkin then begin
591                                                                 if FileExists( GikoSys.GetSkinNewmarkFileName ) then
592                                                                         doc.Write( LoadFromSkin( GikoSys.GetSkinNewmarkFileName, ThreadItem, ThreadItem.Size ) + #13#10 )
593                                                                 else
594                                                                         doc.Write( '<a name="new"></a>' + #13#10 );
595                                                         end else if GikoSys.Setting.UseCSS then begin
596                                                                 doc.Write('<a name="new"></a><div class="new">\90V\92\85\83\8c\83X <span class="newdate">' + FormatDateTime('yyyy/mm/dd(ddd) hh:mm', ThreadItem.RoundDate) + '</span></div>' + #13#10);
597                                                         end else begin
598                                                                 doc.Write('</dl>');
599                                                                 doc.Write('<a name="new"></a>');
600                                                                 doc.Write('<table width="100%" bgcolor="#3333CC" cellpadding="0" cellspacing="1"><tr><td align="center" bgcolor="#6666FF" valign="middle"><font size="-1" color="#ffffff"><b>\90V\92\85\83\8c\83X ' + FormatDateTime('yyyy/mm/dd(ddd) hh:mm', ThreadItem.RoundDate) + '</b></font></td></tr></table>');
601                                                                 doc.Write('<dl> + #13#10');
602                                                         end;
603                                                 except
604                                                         doc.Write( '<a name="new"></a>' + #13#10);
605                                                 end;
606                                         end;
607
608                                         // \83\8c\83X
609                                         doc.Write( boardPlugIn.GetRes( DWORD( threadItem ), i + 1 ) + #13#10 );
610
611                                         if ThreadItem.Kokomade = (i + 1) then begin
612                                                 // \82±\82±\82Ü\82Å\93Ç\82ñ\82¾
613                                                 try
614                                                         if GikoSys.Setting.UseSkin then begin
615                                                                 if FileExists( GikoSys.GetSkinBookmarkFileName ) then
616                                                                         doc.Write( LoadFromSkin( GikoSys.GetSkinBookmarkFileName, ThreadItem, ThreadItem.Size ) + #13#10 )
617                                                                 else
618                                                                         doc.Write( '<a name="koko"></a>' + #13#10 );
619                                                         end else if GikoSys.Setting.UseCSS then begin
620                                                                 doc.Write('<a name="koko"></a><div class="koko">\83R\83R\82Ü\82Å\93Ç\82ñ\82¾</div>' + #13#10 );
621                                                         end else begin
622                                                                 doc.Write('</dl>');
623                                                                 doc.Write('<a name="koko"></a><table width="100%" bgcolor="#55AA55" cellpadding="0" cellspacing="1"><tr><td align="center" bgcolor="#77CC77" valign="middle"><font size="-1" color="#ffffff"><b>\83R\83R\82Ü\82Å\93Ç\82ñ\82¾</b></font></td></tr></table>');
624                                                                 doc.Write('<dl>' + #13#10 );
625                                                         end;
626                                                 except
627                                                         doc.Write( '<a name="koko"></a>' + #13#10 );
628                                                 end;
629                                         end;
630                                 end;
631
632
633                                 // \83X\83L\83\93(\83t\83b\83^)
634                                 doc.Write( boardPlugIn.GetFooter( DWORD( threadItem ), '<a name="bottom"></a>' ) + #13#10 );
635                         finally
636                                 doc.Close;
637                         end;
638
639                 end;
640         end;
641 end;
642
643
644 procedure THTMLCreate.CreateUseSKINHTML(doc: Variant; ThreadItem: TThreadItem; ReadList: TStringList);
645 var
646         i: integer;
647         No: string;
648         CSSFileName: string;
649         NewReceiveNo: Integer;
650         Res: TResRec;
651         UserOptionalStyle: string;
652         SkinHeader: string;
653         SkinNewRes: string;
654         SkinRes: string;
655         strTmp : string;
656         function ReplaceRes( skin: string ): string;
657         begin
658                 Result := SkinedRes( skin, Res, No );
659         end;
660 begin
661         if ThreadItem <> nil then begin
662                 // \83X\83L\83\93\8eg\97p
663                 if GikoSys.Setting.UseSkin then begin
664                         NewReceiveNo := ThreadItem.NewReceive;
665                         // \83t\83H\83\93\83g\82â\83T\83C\83Y\82Ì\90Ý\92è
666                         UserOptionalStyle := GikoSys.SetUserOptionalStyle;
667                         CSSFileName := GikoSys.GetStyleSheetDir + GikoSys.Setting.CSSFileName;
668                         doc.open;
669                         try
670                                 doc.charset := 'Shift_JIS';
671
672                                 // \83X\83L\83\93\82Ì\90Ý\92è
673                                 try
674                                         SkinHeader := LoadFromSkin( GikoSys.GetSkinHeaderFileName, ThreadItem, ThreadItem.Size);
675                                         if Length( UserOptionalStyle ) > 0 then
676                                                 SkinHeader := CustomStringReplace( SkinHeader, '</head>',
677                                                         '<style type="text/css">body {' + UserOptionalStyle + '}</style></head>');
678                                         doc.Write( SkinHeader + #13#10);
679                                 except
680                                 end;
681
682                                 try
683                                         SkinNewRes := LoadFromSkin( GikoSys.GetSkinNewResFileName, ThreadItem, ThreadItem.Size);
684                                 except
685                                 end;
686
687                                 try
688                                         SkinRes := LoadFromSkin( GikoSys.GetSkinResFileName, ThreadItem, ThreadItem.Size );
689                                 except
690                                 end;
691
692                                 doc.Write('<p id="idSearch"></p>' + #13#10);
693                                 doc.Write('<a name="top"></a>' + #13#10);
694
695                                 for i := 0 to ReadList.Count - 1 do begin
696                                         // 1 \82Í\95K\82¸\95\\8e¦
697                                         if i <> 0 then begin
698                                                 // \95\\8e¦\94Í\88Í\82ð\8cÀ\92è
699                                                 case GikoSys.ResRange of
700                                                 Ord( grrKoko ):
701                                                         if ThreadItem.Kokomade > (i + 1) then
702                                                                 Continue;
703                                                 Ord( grrNew ):
704                                                         if NewReceiveNo > (i + 1) then
705                                                                 Continue;
706                                                 10..65535:
707                                                         if (threadItem.Count - i) > GikoSys.ResRange then
708                                                                 Continue;
709                                                 end;
710                                         end;
711
712                                         // \90V\92\85\83}\81[\83N
713                                         if (NewReceiveNo = i + 1) or ((NewReceiveNo = 0) and (i = 0)) then begin
714                                                 try
715                                                         if FileExists( GikoSys.GetSkinNewmarkFileName ) then
716                                                                 doc.Write( LoadFromSkin( GikoSys.GetSkinNewmarkFileName, ThreadItem, ThreadItem.Size )  + #13#10)
717                                                         else
718                                                                 doc.Write( '<a name="new"></a>' + #13#10 );
719                                                 except
720                                                         doc.Write( '<a name="new"></a>' + #13#10 );
721                                                 end;
722                                         end;
723
724                                         if (Trim(ReadList[i]) <> '') then begin
725                                                 No := IntToStr(i + 1);
726
727                                                 Res := DivideStrLine(ReadList[i]);
728                                                 Res.FBody := ConvRes(AddAnchorTag(Res.FBody), ThreadItem.ParentBoard.BBSID, ChangeFileExt(ThreadItem.FileName, ''), 'bbs', 'key', 'st', 'to', 'nofirst', 'true');
729                                                 Res.FDateTime := AddBeProfileLink(Res.FDateTime, i + 1);
730
731                                                 try
732                                                         if NewReceiveNo <= (i + 1) then
733                                                                 // \90V\92\85\83\8c\83X
734                                                                 strTmp := ReplaceRes( SkinNewRes )
735                                                         else
736                                                                 // \92Ê\8fí\82Ì\83\8c\83X
737                                                                 strTmp := ReplaceRes( SkinRes );
738
739                                                         doc.Write( strTmp + #13#10 );
740                                                 except
741                                                 end;
742                                         end;
743
744                                         if ThreadItem.Kokomade = (i + 1) then begin
745                                                 // \82±\82±\82Ü\82Å\93Ç\82ñ\82¾
746                                                 try
747                                                         if FileExists( GikoSys.GetSkinBookmarkFileName ) then
748                                                                 doc.Write( LoadFromSkin( GikoSys.GetSkinBookmarkFileName, ThreadItem, ThreadItem.Size ) + #13#10 )
749                                                         else
750                                                                 doc.Write( '<a name="koko"></a>' + #13#10 );
751                                                 except
752                                                         doc.Write( '<a name="koko"></a>' + #13#10 );
753                                                 end;
754                                         end;
755                                 end;
756
757                                 doc.Write('<a name="bottom"></a>' + #13#10);
758                                 // \83X\83L\83\93(\83t\83b\83^)
759                                 try
760                                         doc.Write( LoadFromSkin( GikoSys.GetSkinFooterFileName, ThreadItem, ThreadItem.Size ) + #13#10 );
761                                 except
762                                 end;
763                         finally
764                                 doc.close;
765                         end;
766                 end;
767         end;
768 end;
769
770 procedure THTMLCreate.CreateUseCSSHTML(doc: Variant; ThreadItem: TThreadItem; ReadList: TStringList; sTitle: string );
771 var
772         i: integer;
773         No: string;
774         CSSFileName: string;
775         NewReceiveNo: Integer;
776         Res: TResRec;
777         UserOptionalStyle: string;
778 begin
779         if ThreadItem <> nil then begin
780                 doc.open;
781                 try
782                         doc.charset := 'Shift_JIS';
783                         NewReceiveNo := ThreadItem.NewReceive;
784                         // \83t\83H\83\93\83g\82â\83T\83C\83Y\82Ì\90Ý\92è
785                         UserOptionalStyle := GikoSys.SetUserOptionalStyle;
786                         CSSFileName := GikoSys.GetStyleSheetDir + GikoSys.Setting.CSSFileName;
787                         if GikoSys.Setting.UseCSS and FileExists(CSSFileName) then begin
788                                 //CSS\8eg\97p
789                                 doc.Write('<html><head>' + #13#10);
790                                 doc.Write('<meta http-equiv="Content-type" content="text/html; charset=Shift_JIS">' + #13#10);
791                                 doc.Write('<title>' + sTitle + '</title>' + #13#10);
792                                 doc.Write('<link rel="stylesheet" href="'+CSSFileName+'" type="text/css">' + #13#10);
793                                 if Length( UserOptionalStyle ) > 0 then
794                                         doc.Write('<style type="text/css">body {' + UserOptionalStyle + '}</style>' + #13#10);
795                                 doc.Write('</head>' + #13#10);
796                                 doc.Write('<body>' + #13#10);
797                                 doc.Write('<a name="top"></a>' + #13#10);
798                                 doc.Write('<p id="idSearch"></p>' + #13#10);
799                                 doc.Write('<div class="title">' + sTitle + '</div>' + #13#10);
800                                 for i := 0 to ReadList.Count - 1 do begin
801                                         // 1 \82Í\95K\82¸\95\\8e¦
802                                         if i <> 0 then begin
803                                                 // \95\\8e¦\94Í\88Í\82ð\8cÀ\92è
804                                                 case GikoSys.ResRange of
805                                                 Ord( grrKoko ):
806                                                         if ThreadItem.Kokomade > (i + 1) then
807                                                                 Continue;
808                                                 Ord( grrNew ):
809                                                         if NewReceiveNo > (i + 1) then
810                                                                 Continue;
811                                                 10..65535:
812                                                         if (threadItem.Count - i) > GikoSys.ResRange then
813                                                                 Continue;
814                                                 end;
815                                         end;
816
817                                         if (NewReceiveNo = (i + 1)) or ((NewReceiveNo = 0) and (i = 0)) then begin
818                                                 doc.Write('<a name="new"></a><div class="new">\90V\92\85\83\8c\83X <span class="newdate">' + FormatDateTime('yyyy/mm/dd(ddd) hh:mm', ThreadItem.RoundDate) + '</span></div>' + #13#10);
819                                         end;
820
821                                         if (Trim(ReadList[i]) <> '') then begin
822                                                 No := IntToStr(i + 1);
823                                                 Res := DivideStrLine(ReadList[i]);
824                                                 Res.FBody := ConvRes(AddAnchorTag(Res.FBody), ThreadItem.ParentBoard.BBSID, ChangeFileExt(ThreadItem.FileName, ''), 'bbs', 'key', 'st', 'to', 'nofirst', 'true');
825                                                 Res.FDateTime := AddBeProfileLink(Res.FDateTime, i + 1);
826                                                 if Res.FMailTo = '' then
827                                                         doc.Write('<a name="' + No + '"></a>'
828                                                                                 + '<div class="header"><span class="no"><a href="menu:' + No + '">' + No + '</a></span> '
829                                                                                 + '<span class="name_label">\96¼\91O\81F</span> '
830                                                                                 + '<span class="name"><b>' + Res.FName + '</b></span> '
831                                                                                 + '<span class="date_label">\93\8a\8de\93ú\81F</span> '
832                                                                                 + '<span class="date">' + Res.FDateTime+ '</span></div>'
833                                                                                 + '<div class="mes">' + Res.FBody + ' </div>' + #13#10)
834                                                 else if GikoSys.Setting.ShowMail then
835                                                         doc.Write('<a name="' + No + '"></a>'
836                                                                                 + '<div class="header"><span class="no"><a href="menu:' + No + '">' + No + '</a></span>'
837                                                                                 + '<span class="name_label"> \96¼\91O\81F </span>'
838                                                                                 + '<a class="name_mail" href="mailto:' + Res.FMailTo + '">'
839                                                                                 + '<b>' + Res.FName + '</b></a><span class="mail"> [' + Res.FMailTo + ']</span>'
840                                                                                 + '<span class="date_label"> \93\8a\8de\93ú\81F</span>'
841                                                                                 + '<span class="date"> ' + Res.FDateTime+ '</span></div>'
842                                                                                 + '<div class="mes">' + Res.FBody + ' </div>' + #13#10)
843                                                 else
844                                                         doc.Write('<a name="' + No + '"></a>'
845                                                                                 + '<div class="header"><span class="no"><a href="menu:' + No + '">' + No + '</a></span>'
846                                                                                 + '<span class="name_label"> \96¼\91O\81F </span>'
847                                                                                 + '<a class="name_mail" href="mailto:' + Res.FMailTo + '">'
848                                                                                 + '<b>' + Res.FName + '</b></a>'
849                                                                                 + '<span class="date_label"> \93\8a\8de\93ú\81F</span>'
850                                                                                 + '<span class="date"> ' + Res.FDateTime+ '</span></div>'
851                                                                                 + '<div class="mes">' + Res.FBody + ' </div>' + #13#10);
852                                         end;
853
854                                         if ThreadItem.Kokomade = (i + 1) then begin
855                                                 doc.Write('<a name="koko"></a><div class="koko">\83R\83R\82Ü\82Å\93Ç\82ñ\82¾</div>' + #13#10);
856                                         end;
857
858                                 end;
859
860                                 doc.Write('<a name="bottom"></a>' + #13#10);
861                                 doc.Write('<a name="last"></a>' + #13#10);
862                                 doc.Write('</body></html>' + #13#10);
863                         end;
864                 finally
865                         doc.Close;
866                 end;
867         end;
868 end;
869
870 procedure THTMLCreate.CreateDefaultHTML (doc: Variant; ThreadItem: TThreadItem; ReadList: TStringList; sTitle: string );
871 var
872         i: integer;
873         No: string;
874         NewReceiveNo: Integer;
875         Res: TResRec;
876 begin
877         if ThreadItem <> nil then begin
878                 doc.open;
879                 try
880                         doc.charset := 'Shift_JIS';
881                         NewReceiveNo := ThreadItem.NewReceive;
882                         doc.Write('<html><head>' + #13#10);
883                         doc.Write('<meta http-equiv="Content-type" content="text/html; charset=Shift_JIS">' + #13#10);
884                         doc.Write('<title>' + sTitle + '</title></head>' + #13#10);
885                         doc.Write('<body TEXT="#000000" BGCOLOR="#EFEFEF" link="#0000FF" alink="#FF0000" vlink="#660099">' + #13#10);
886                         doc.Write('<a name="top"></a>' + #13#10);
887                         doc.Write('<font size=+1 color="#FF0000">' + sTitle + '</font>' + #13#10);
888                         doc.Write('<dl>' + #13#10);
889                         doc.Write('<p id="idSearch"></p>' + #13#10);
890                         for i := 0 to ReadList.Count - 1 do begin
891                                 // 1 \82Í\95K\82¸\95\\8e¦
892                                 if i <> 0 then begin
893                                         // \95\\8e¦\94Í\88Í\82ð\8cÀ\92è
894                                         case GikoSys.ResRange of
895                                         Ord( grrKoko ):
896                                                 if ThreadItem.Kokomade > (i + 1) then
897                                                         Continue;
898                                         Ord( grrNew ):
899                                                 if NewReceiveNo > (i + 1) then
900                                                         Continue;
901                                         10..65535:
902                                                 if (threadItem.Count - i) > GikoSys.ResRange then
903                                                         Continue;
904                                         end;
905                                 end;
906
907                                 if (NewReceiveNo = (i + 1)) or ((NewReceiveNo = 0) and (i = 0)) then begin
908                                         doc.Write('</dl>' + #13#10);
909                                         doc.Write('<a name="new"></a>' + #13#10);
910                                         doc.Write('<table width="100%" bgcolor="#3333CC" cellpadding="0" cellspacing="1"><tr><td align="center" bgcolor="#6666FF" valign="middle"><font size="-1" color="#ffffff"><b>\90V\92\85\83\8c\83X ' + FormatDateTime('yyyy/mm/dd(ddd) hh:mm', ThreadItem.RoundDate) + '</b></font></td></tr></table>' + #13#10);
911                                         doc.Write('<dl>' + #13#10);
912                                 end;
913
914                                 if (Trim(ReadList[i]) <> '') then begin
915                                         No := IntToStr(i + 1);
916                                         Res := DivideStrLine(ReadList[i]);
917                                         Res.FBody := ConvRes(AddAnchorTag(Res.FBody), ThreadItem.ParentBoard.BBSID, ChangeFileExt(ThreadItem.FileName, ''), 'bbs', 'key', 'st', 'to', 'nofirst', 'true');
918                                         Res.FDateTime := AddBeProfileLink(Res.FDateTime, i + 1);
919                                         if Res.FMailTo = '' then
920                                                 doc.Write('<a name="' + No + '"></a><dt><a href="menu:' + No + '">' + No + '</a> \96¼\91O\81F<font color="forestgreen"><b> ' + Res.FName + ' </b></font> \93\8a\8de\93ú\81F <span class="date">' + Res.FDateTime+ '</span><br><dd>' + Res.Fbody + ' <br><br><br>' + #13#10)
921                                         else if GikoSys.Setting.ShowMail then
922                                                 doc.Write('<a name="' + No + '"></a><dt><a href="menu:' + No + '">' + No + '</a> \96¼\91O\81F<a href="mailto:' + Res.FMailTo + '"><b> ' + Res.FName + ' </B></a> [' + Res.FMailTo + '] \93\8a\8de\93ú\81F <span class="date">' + Res.FDateTime+ '</span><br><dd>' + Res.Fbody + ' <br><br><br>' + #13#10)
923                                         else
924                                                 doc.Write('<a name="' + No + '"></a><dt><a href="menu:' + No + '">' + No + '</a> \96¼\91O\81F<a href="mailto:' + Res.FMailTo + '"><b> ' + Res.FName + ' </B></a> \93\8a\8de\93ú\81F <span class="date">' + Res.FDateTime+ '</span><br><dd>' + Res.Fbody + ' <br><br><br>' + #13#10);
925                                 end;
926                                 if ThreadItem.Kokomade = (i + 1) then begin
927                                         doc.Write('</dl>' + #13#10);
928                                         doc.Write('<a name="koko"></a><table width="100%" bgcolor="#55AA55" cellpadding="0" cellspacing="1"><tr><td align="center" bgcolor="#77CC77" valign="middle"><font size="-1" color="#ffffff"><b>\83R\83R\82Ü\82Å\93Ç\82ñ\82¾</b></font></td></tr></table>' + #13#10);
929                                         doc.Write('<dl>' + #13#10);
930                                 end;
931                         end;
932                         doc.Write('</dl>' + #13#10);
933                         doc.Write('<a name="bottom"></a>' + #13#10);
934                         doc.Write('</body></html>' + #13#10);
935                 finally
936                         doc.Close;
937                 end;
938         end;
939 end;
940
941 procedure THTMLCreate.CreateHTML2(doc: Variant; ThreadItem: TThreadItem; var sTitle: string);
942 var
943         ReadList: TStringList;
944         CSSFileName: string;
945         FileName: string;
946         Res: TResRec;
947 {$IFDEF DEBUG}
948         st, rt: Cardinal;
949 {$ENDIF}
950 begin
951 {$IFDEF DEBUG}
952         Writeln('Create HTML');
953         st := GetTickCount;
954 {$ENDIF}
955         if ThreadItem <> nil then begin
956                 if ThreadItem.ParentBoard.IsBoardPlugInAvailable then begin
957                         CreateUsePluginHTML(doc, ThreadItem, sTitle);
958                 end else begin
959                         ShortDayNames[1] := '\93ú';               ShortDayNames[2] := '\8c\8e';
960                         ShortDayNames[3] := '\89Î';               ShortDayNames[4] := '\90\85';
961                         ShortDayNames[5] := '\96Ø';               ShortDayNames[6] := '\8bà';
962                         ShortDayNames[7] := '\93y';
963
964                         ReadList := TStringList.Create;
965                         try
966                                 if ThreadItem.IsLogFile then begin
967                                         FileName := ThreadItem.GetThreadFileName;
968                                         ReadList.LoadFromFile(FileName);
969                                         GikoSys.FAbon.IndividualAbon(ReadList, ChangeFileExt(FileName,'.NG'));
970                                         GikoSys.FAbon.Execute(ReadList);                //       \82 \82Ú\81`\82ñ\82µ\82Ä
971                                         GikoSys.FSelectResFilter.Execute(ReadList); //\83\8c\83X\82Ì\83t\83B\83\8b\83^\83\8a\83\93\83O\82ð\82·\82é
972                                         if ThreadItem.Title = '' then begin
973                                                 Res := DivideStrLine(ReadList[0]);
974                                                 sTitle := Res.FTitle;
975                                         end else
976                                                 sTitle := ThreadItem.Title
977                                 end else begin
978                                         sTitle := CustomStringReplace(ThreadItem.Title, '\81\97\81M', ',');
979                                 end;
980
981                                 // \83t\83H\83\93\83g\82â\83T\83C\83Y\82Ì\90Ý\92è
982                                 CSSFileName := GikoSys.GetStyleSheetDir + GikoSys.Setting.CSSFileName;
983                                 if GikoSys.Setting.UseSkin then begin
984                                         CreateUseSKINHTML(doc, ThreadItem, ReadList);
985                                 end else if GikoSys.Setting.UseCSS and FileExists(CSSFileName) then begin
986                                         CreateUseCSSHTML(doc, ThreadItem, ReadList, sTitle);
987                                 end else begin
988                                         CreateDefaultHTML(doc, ThreadItem, ReadList, sTitle);
989                                 end;
990                         finally
991                                 ReadList.Free;
992                         end;
993                 end;
994         end;
995 {$IFDEF DEBUG}
996         rt := GetTickCount - st;
997         Writeln('Done.');
998         Writeln(IntToStr(rt) + ' ms');
999 {$ENDIF}
1000 end;
1001
1002 procedure THTMLCreate.CreateHTML3(var html: TStringList; ThreadItem: TThreadItem; var sTitle: string);
1003 var
1004         i: integer;
1005         No: string;
1006         //bufList : TStringList;
1007         ReadList: TStringList;
1008 //      SaveList: TStringList;
1009         CSSFileName: string;
1010         BBSID: string;
1011         FileName: string;
1012         Res: TResRec;
1013         boardPlugIn : TBoardPlugIn;
1014
1015         UserOptionalStyle: string;
1016         SkinHeader: string;
1017         SkinRes: string;
1018         tmp, tmp1: string;
1019         function LoadSkin( fileName: string ): string;
1020         begin
1021                 Result := LoadFromSkin( fileName, ThreadItem, ThreadItem.Size );
1022         end;
1023         function ReplaceRes( skin: string ): string;
1024         begin
1025                 Result := SkinedRes( skin, Res, No );
1026         end;
1027
1028 begin
1029         if ThreadItem <> nil then begin
1030                 CSSFileName := GikoSys.GetStyleSheetDir + GikoSys.Setting.CSSFileName;
1031                 html.Clear;
1032                 html.BeginUpdate;
1033                 //if ThreadItem.IsBoardPlugInAvailable then begin
1034                 if ThreadItem.ParentBoard.IsBoardPlugInAvailable then begin
1035                         //===== \83v\83\89\83O\83C\83\93\82É\82æ\82é\95\\8e¦
1036                         //boardPlugIn           := ThreadItem.BoardPlugIn;
1037                         boardPlugIn             := ThreadItem.ParentBoard.BoardPlugIn;
1038                         // \83t\83H\83\93\83g\82â\83T\83C\83Y\82Ì\90Ý\92è
1039                         UserOptionalStyle := GikoSys.SetUserOptionalStyle;
1040                         try
1041                                 // \95\8e\9a\83R\81[\83h\82Í\83v\83\89\83O\83C\83\93\82É\94C\82¹\82é
1042                                 // \83w\83b\83_
1043                                 tmp := boardPlugIn.GetHeader( DWORD( threadItem ),
1044                                         '<style type="text/css">body {' + UserOptionalStyle + '}</style>' );
1045                                 //\90â\91Î\8eQ\8fÆ\82©\82ç\91\8a\91Î\8eQ\8fÆ\82Ö
1046                                 if GikoSys.Setting.UseSkin then begin
1047                                         tmp1 := './' + GikoSys.Setting.CSSFileName;
1048                                         tmp1 := CustomStringReplace(tmp1, GikoSys.GetConfigDir, '');
1049                                         tmp1 := CustomStringReplace(tmp1, '\', '/');
1050                                         tmp := CustomStringReplace(tmp, ExtractFilePath(GikoSys.Setting.CSSFileName),  tmp1);
1051                                 end else if GikoSys.Setting.UseCSS then begin
1052                                         tmp1 := './' + CSSFileName;
1053                                         tmp1 := CustomStringReplace(tmp1, GikoSys.GetConfigDir, '');
1054                                         tmp1 := CustomStringReplace(tmp1, '\', '/');
1055                                         tmp := CustomStringReplace(tmp, CSSFileName,  tmp1);
1056                                 end;
1057                                 html.Append( tmp );
1058
1059                                 for i := 0 to threadItem.Count - 1 do begin
1060
1061                                         // \83\8c\83X
1062                                         html.Append( ConvertResAnchor(boardPlugIn.GetRes( DWORD( threadItem ), i + 1 )) );
1063
1064                                 end;
1065                                 // \83X\83L\83\93(\83t\83b\83^)
1066                                 html.Append( boardPlugIn.GetFooter( DWORD( threadItem ), '<a name="bottom"></a>' ) );
1067                         finally
1068                         end;
1069                         html.EndUpdate;
1070                         //Exit;
1071                 end else begin
1072                         ShortDayNames[1] := '\93ú';               ShortDayNames[2] := '\8c\8e';
1073                         ShortDayNames[3] := '\89Î';               ShortDayNames[4] := '\90\85';
1074                         ShortDayNames[5] := '\96Ø';               ShortDayNames[6] := '\8bà';
1075                         ShortDayNames[7] := '\93y';
1076                         BBSID := ThreadItem.ParentBoard.BBSID;
1077                         ReadList := TStringList.Create;
1078                         try
1079                                 if ThreadItem.IsLogFile then begin
1080                                         FileName := ThreadItem.GetThreadFileName;
1081                                         ReadList.LoadFromFile(FileName);
1082                                         GikoSys.FAbon.IndividualAbon(ReadList, ChangeFileExt(FileName,'.NG'));
1083                                         GikoSys.FAbon.Execute(ReadList);                //       \82 \82Ú\81`\82ñ\82µ\82Ä
1084                                         GikoSys.FSelectResFilter.Execute(ReadList); //\83\8c\83X\82Ì\83t\83B\83\8b\83^\83\8a\83\93\83O\82ð\82·\82é
1085                                         Res := DivideStrLine(ReadList[0]);
1086                                         //Res.FTitle := CustomStringReplace(Res.FTitle, '\81\97\81M', ',');
1087                                         sTitle := Res.FTitle;
1088                                 end else begin
1089                                         sTitle := CustomStringReplace(ThreadItem.Title, '\81\97\81M', ',');
1090                                 end;
1091                                 try
1092                                         // \83t\83H\83\93\83g\82â\83T\83C\83Y\82Ì\90Ý\92è
1093                                         UserOptionalStyle := GikoSys.SetUserOptionalStyle;
1094
1095                                         if GikoSys.Setting.UseSkin then begin
1096                                                 // \83X\83L\83\93\8eg\97p
1097                                                 // \83X\83L\83\93\82Ì\90Ý\92è
1098                                                 try
1099                                                         SkinHeader := LoadSkin( GikoSys.GetSkinHeaderFileName );
1100                                                         if Length( UserOptionalStyle ) > 0 then
1101                                                                 SkinHeader := CustomStringReplace( SkinHeader, '</head>',
1102                                                                         '<style type="text/css">body {' + UserOptionalStyle + '}</style></head>');
1103                                                         //\90â\91Î\8eQ\8fÆ\82©\82ç\91\8a\91Î\8eQ\8fÆ\82Ö
1104                                                         tmp1 := './' + GikoSys.Setting.CSSFileName;
1105                                                         tmp1 := CustomStringReplace(tmp1, GikoSys.GetConfigDir, '');
1106                                                         tmp1 := CustomStringReplace(tmp1, '\', '/');
1107                                                         SkinHeader := CustomStringReplace(SkinHeader, ExtractFilePath(GikoSys.Setting.CSSFileName),  tmp1);
1108                                                         html.Append( SkinHeader );
1109                                                 except
1110                                                 end;
1111                                                 try
1112                                                         SkinRes := LoadSkin( GikoSys.GetSkinResFileName );
1113                                                 except
1114                                                 end;
1115                                                 html.Append('<a name="top"></a>');
1116                                                 for i := 0 to ReadList.Count - 1 do begin
1117                                                         if (Trim(ReadList[i]) <> '') then begin
1118                                                                 No := IntToStr(i + 1);
1119
1120                                                                 Res := DivideStrLine(ReadList[i]);
1121                                                                 Res.FBody := AddAnchorTag(Res.FBody);
1122                                                                 Res.FBody := ConvertResAnchor(ConvRes(Res.FBody, ThreadItem.ParentBoard.BBSID, ChangeFileExt(ThreadItem.FileName, ''), 'bbs', 'key', 'st', 'to', 'nofirst', 'true', true));
1123
1124                                                                 try
1125                                                                         html.Append( ReplaceRes( SkinRes ) );
1126                                                                 except
1127                                                                 end;
1128                                                         end;
1129
1130                                                 end;
1131                                                 html.Append('<a name="bottom"></a>');
1132                                                 // \83X\83L\83\93(\83t\83b\83^)
1133                                                 try
1134                                                         html.Append( LoadSkin( GikoSys.GetSkinFooterFileName ) );
1135                                                 except
1136                                                 end;
1137                                         end else if GikoSys.Setting.UseCSS and FileExists(CSSFileName) then begin
1138                                                 //CSS\8eg\97p
1139                                                 //CSSFileName := GetAppDir + CSS_FILE_NAME;
1140                                                 html.Append('<html><head>');
1141                                                 html.Append('<meta http-equiv="Content-type" content="text/html; charset=Shift_JIS">');
1142                                                 html.Append('<title>' + sTitle + '</title>');
1143                                                 //\90â\91Î\8eQ\8fÆ\82©\82ç\91\8a\91Î\8eQ\8fÆ\82Ö
1144                                                 tmp1 := './' + CSSFileName;
1145                                                 tmp1 := CustomStringReplace(tmp1, GikoSys.GetConfigDir, '');
1146                                                 tmp1 := CustomStringReplace(tmp1, '\', '/');
1147
1148                                                 html.Append('<link rel="stylesheet" href="'+tmp1+'" type="text/css">');
1149                                                 if Length( UserOptionalStyle ) > 0 then
1150                                                         html.Append('<style type="text/css">body {' + UserOptionalStyle + '}</style>');
1151                                                 html.Append('</head>');
1152                                                 html.Append('<body>');
1153                                                 html.Append('<a name="top"></a>');
1154                                                 html.Append('<div class="title">' + sTitle + '</div>');
1155                                                 for i := 0 to ReadList.Count - 1 do begin
1156                                                         if (Trim(ReadList[i]) <> '') then begin
1157                                                                 No := IntToStr(i + 1);
1158                                                                 Res := DivideStrLine(ReadList[i]);
1159                                                                 Res.FBody := AddAnchorTag(Res.FBody);
1160                                                                 Res.FBody := ConvertResAnchor(ConvRes(Res.FBody, ThreadItem.ParentBoard.BBSID, ChangeFileExt(ThreadItem.FileName, ''), 'bbs', 'key', 'st', 'to', 'nofirst', 'true', true));
1161                                                                 if Res.FMailTo = '' then
1162                                                                         html.Append('<a name="' + No + '"></a>'
1163                                                                                                         + '<div class="header"><span class="no"><a href="menu:' + No + '">' + No + '</a></span> '
1164                                                                                                         + '<span class="name_label">\96¼\91O\81F</span> '
1165                                                                                                         + '<span class="name"><b>' + Res.FName + '</b></span> '
1166                                                                                                         + '<span class="date_label">\93\8a\8de\93ú\81F</span> '
1167                                                                                                         + '<span class="date">' + Res.FDateTime+ '</span></div>'
1168                                                                                                                                                                                                 + '<div class="mes">' + Res.FBody + ' </div>')
1169                                                                 else if GikoSys.Setting.ShowMail then
1170                                                                         html.Append('<a name="' + No + '"></a>'
1171                                                                                                         + '<div class="header"><span class="no"><a href="menu:' + No + '">' + No + '</a></span>'
1172                                                                                                                                                                                                 + '<span class="name_label"> \96¼\91O\81F </span>'
1173                                                                                                         + '<a class="name_mail" href="mailto:' + Res.FMailTo + '">'
1174                                                                                                         + '<b>' + Res.FName + '</b></a><span class="mail"> [' + Res.FMailTo + ']</span>'
1175                                                                                                         + '<span class="date_label"> \93\8a\8de\93ú\81F</span>'
1176                                                                                                         + '<span class="date"> ' + Res.FDateTime+ '</span></div>'
1177                                                                                                         + '<div class="mes">' + Res.FBody + ' </div>')
1178                                                                 else
1179                                                                         html.Append('<a name="' + No + '"></a>'
1180                                                                                                         + '<div class="header"><span class="no"><a href="menu:' + No + '">' + No + '</a></span>'
1181                                                                                                         + '<span class="name_label"> \96¼\91O\81F </span>'
1182                                                                                                         + '<a class="name_mail" href="mailto:' + Res.FMailTo + '">'
1183                                                                                                         + '<b>' + Res.FName + '</b></a>'
1184                                                                                                         + '<span class="date_label"> \93\8a\8de\93ú\81F</span>'
1185                                                                                                         + '<span class="date"> ' + Res.FDateTime+ '</span></div>'
1186                                                                                                                                                                                                 + '<div class="mes">' + Res.FBody + ' </div>');
1187                                                         end;
1188                                                 end;
1189                                                 html.Append('<a name="bottom"></a>');
1190                                                 html.Append('<a name="last"></a>');
1191                                                 html.Append('</body></html>');
1192                                         end else begin
1193                                                 //CSS\94ñ\8eg\97p
1194                                                 html.Append('<html><head>');
1195                                                 html.Append('<meta http-equiv="Content-type" content="text/html; charset=Shift_JIS">');
1196                                                 html.Append('<title>' + sTitle + '</title></head>');
1197                                                 html.Append('<body TEXT="#000000" BGCOLOR="#EFEFEF" link="#0000FF" alink="#FF0000" vlink="#660099">');
1198                                                 html.Append('<a name="top"></a>');
1199                                                 html.Append('<font size=+1 color="#FF0000">' + sTitle + '</font>');
1200                                                 html.Append('<dl>');
1201                                                 for i := 0 to ReadList.Count - 1 do begin
1202                                                         if (Trim(ReadList[i]) <> '') then begin
1203                                                                 No := IntToStr(i + 1);
1204                                                                 Res := DivideStrLine(ReadList[i]);
1205                                                                 Res.FBody := AddAnchorTag(Res.FBody);
1206                                                                 Res.FBody := ConvertResAnchor(ConvRes(Res.FBody, ThreadItem.ParentBoard.BBSID, ChangeFileExt(ThreadItem.FileName, ''), 'bbs', 'key', 'st', 'to', 'nofirst', 'true', true));
1207                                                                 if Res.FMailTo = '' then
1208                                                                         html.Append('<a name="' + No + '"></a><dt><a href="menu:' + No + '">' + No + '</a> \96¼\91O\81F<font color="forestgreen"><b> ' + Res.FName + ' </b></font> \93\8a\8de\93ú\81F ' + Res.FDateTime+ '<br><dd>' + Res.Fbody + ' <br><br><br>')
1209                                                                 else if GikoSys.Setting.ShowMail then
1210                                                                         html.Append('<a name="' + No + '"></a><dt><a href="menu:' + No + '">' + No + '</a> \96¼\91O\81F<a href="mailto:' + Res.FMailTo + '"><b> ' + Res.FName + ' </B></a> [' + Res.FMailTo + '] \93\8a\8de\93ú\81F ' + Res.FDateTime+ '<br><dd>' + Res.Fbody + ' <br><br><br>')
1211                                                                 else
1212                                                                         html.Append('<a name="' + No + '"></a><dt><a href="menu:' + No + '">' + No + '</a> \96¼\91O\81F<a href="mailto:' + Res.FMailTo + '"><b> ' + Res.FName + ' </B></a> \93\8a\8de\93ú\81F ' + Res.FDateTime+ '<br><dd>' + Res.Fbody + ' <br><br><br>');
1213                                                         end;
1214                                                 end;
1215                                                 html.Append('</dl>');
1216                                                 html.Append('<a name="bottom"></a>');
1217                                                 html.Append('</body></html>');
1218                                         end;
1219                                 finally
1220                                         html.EndUpdate;
1221                                 end;
1222                         finally
1223                                 ReadList.Free;
1224                         end;
1225                 end;
1226         end;
1227 end;
1228
1229 initialization
1230          HTMLCreater := THTMLCreate.Create;
1231
1232 finalization
1233         if HTMLCreater <> nil then begin
1234                 HTMLCreater.Free;
1235                 HTMLCreater := nil;
1236         end;
1237
1238 end.