| 161 |
procedure GetFileList(Path: string; Mask: string; var List: TStringList; IsPathAdd: Boolean); overload;//サブフォルダは検索しない |
procedure GetFileList(Path: string; Mask: string; var List: TStringList; IsPathAdd: Boolean); overload;//サブフォルダは検索しない |
| 162 |
procedure GetDirectoryList(Path: string; Mask: string; List: TStringList; SubDir: Boolean); |
procedure GetDirectoryList(Path: string; Mask: string; List: TStringList; SubDir: Boolean); |
| 163 |
|
|
|
procedure CreateHTML2(doc: Variant; ThreadItem: TThreadItem; var sTitle: string); |
|
|
procedure CreateHTML3(var html: TStringList; ThreadItem: TThreadItem; var sTitle: string); |
|
|
function AddAnchorTag(s: string): string; |
|
|
|
|
| 164 |
function DivideSubject(Line: string): TSubjectRec; |
function DivideSubject(Line: string): TSubjectRec; |
| 165 |
function DivideStrLine(Line: string): TResRec; |
function DivideStrLine(Line: string): TResRec; |
| 166 |
|
|
| 190 |
function GetShortName(const LongName: string; ALength: integer): string; |
function GetShortName(const LongName: string; ALength: integer): string; |
| 191 |
function ConvRes(const Body, Bbs, Key, ParamBBS, ParamKey, ParamStart, ParamTo, ParamNoFirst, ParamTrue : string; DatToHTML: boolean = false): string; overload; |
function ConvRes(const Body, Bbs, Key, ParamBBS, ParamKey, ParamStart, ParamTo, ParamNoFirst, ParamTrue : string; DatToHTML: boolean = false): string; overload; |
| 192 |
function ConvRes(const Body, Bbs, Key, ParamBBS, ParamKey, ParamStart, ParamTo, ParamNoFirst, ParamTrue, FullURL : string): string; overload; |
function ConvRes(const Body, Bbs, Key, ParamBBS, ParamKey, ParamStart, ParamTo, ParamNoFirst, ParamTrue, FullURL : string): string; overload; |
|
function ConvertResAnchor(res: string): string; |
|
| 193 |
function BoolToInt(b: Boolean): Integer; |
function BoolToInt(b: Boolean): Integer; |
| 194 |
function IntToBool(i: Integer): Boolean; |
function IntToBool(i: Integer): Boolean; |
| 195 |
function GzipDecompress(ResStream: TStream; ContentEncoding: string): string; |
function GzipDecompress(ResStream: TStream; ContentEncoding: string): string; |
| 220 |
|
|
| 221 |
procedure GetPopupResNumber(URL : string; var stRes, endRes : Int64); |
procedure GetPopupResNumber(URL : string; var stRes, endRes : Int64); |
| 222 |
|
|
|
// スキンを読み込み、値を置換する |
|
|
function LoadFromSkin( fileName: string; ThreadItem: TThreadItem; SizeByte: Integer ): string; |
|
|
// レスの値を置換する |
|
|
function SkinedRes( skin: string; Res: TResRec; No: string ): string; |
|
|
|
|
| 223 |
//Samba24のファイルが存在するか。存在しない場合、defaultファイルをrenameする |
//Samba24のファイルが存在するか。存在しない場合、defaultファイルをrenameする |
| 224 |
procedure SambaFileExists(); |
procedure SambaFileExists(); |
| 225 |
|
|
| 1031 |
end; |
end; |
| 1032 |
end; |
end; |
| 1033 |
|
|
|
// スキンを読み込み、値を置換する |
|
|
function TGikoSys.LoadFromSkin( |
|
|
fileName: string; |
|
|
ThreadItem: TThreadItem; |
|
|
SizeByte: Integer |
|
|
): string; |
|
|
var |
|
|
Skin: TStringList; |
|
|
begin |
|
|
|
|
|
Skin := TStringList.Create; |
|
|
try |
|
|
if FileExists( fileName ) then begin |
|
|
Skin.LoadFromFile( fileName ); |
|
|
|
|
|
// やりかたが苦しいけど、オプションダイアログのプレビュー用 try |
|
|
try |
|
|
if ThreadItem.ParentBoard <> nil then |
|
|
if ThreadItem.ParentBoard.ParentCategory <> nil then |
|
|
CustomStringReplace( Skin, '<BBSNAME/>', ThreadItem.ParentBoard.ParentCategory.ParenTBBS.Title); |
|
|
CustomStringReplace( Skin, '<THREADURL/>', ThreadItem.URL); |
|
|
except end; |
|
|
CustomStringReplace( Skin, '<BOARDNAME/>', ThreadItem.ParentBoard.Title); |
|
|
CustomStringReplace( Skin, '<BOARDURL/>', ThreadItem.ParentBoard.URL); |
|
|
CustomStringReplace( Skin, '<THREADNAME/>', ThreadItem.Title); |
|
|
CustomStringReplace( Skin, '<SKINPATH/>', Setting.CSSFileName); |
|
|
CustomStringReplace( Skin, '<GETRESCOUNT/>', IntToStr( ThreadItem.Count - ThreadItem.NewResCount )); |
|
|
CustomStringReplace( Skin, '<NEWRESCOUNT/>', IntToStr( ThreadItem.NewResCount )); |
|
|
CustomStringReplace( Skin, '<ALLRESCOUNT/>', IntToStr( ThreadItem.Count )); |
|
|
|
|
|
CustomStringReplace( Skin, '<NEWDATE/>',FormatDateTime('yyyy/mm/dd(ddd) hh:mm', ThreadItem.RoundDate)); |
|
|
CustomStringReplace( Skin, '<SIZEKB/>', IntToStr( Floor( SizeByte / 1024 ) )); |
|
|
CustomStringReplace( Skin, '<SIZE/>', IntToStr( SizeByte )); |
|
|
|
|
|
//----- とりあえずかちゅ〜しゃ互換用。コメントアウトしてもよし |
|
|
// やりかたが苦しいけど、オプションダイアログのプレビュー用 try |
|
|
try |
|
|
if ThreadItem.ParentBoard <> nil then |
|
|
if ThreadItem.ParentBoard.ParentCategory <> nil then |
|
|
CustomStringReplace( Skin, '&BBSNAME', ThreadItem.ParentBoard.ParentCategory.ParenTBBS.Title); |
|
|
CustomStringReplace( Skin, '&THREADURL', ThreadItem.URL); |
|
|
except end; |
|
|
CustomStringReplace( Skin, '&BOARDNAME', ThreadItem.ParentBoard.Title); |
|
|
CustomStringReplace( Skin, '&BOARDURL', ThreadItem.ParentBoard.URL); |
|
|
CustomStringReplace( Skin, '&THREADNAME', ThreadItem.Title); |
|
|
CustomStringReplace( Skin, '&SKINPATH', Setting.CSSFileName); |
|
|
CustomStringReplace( Skin, '&GETRESCOUNT', IntToStr( ThreadItem.NewReceive - 1 )); |
|
|
CustomStringReplace( Skin, '&NEWRESCOUNT', IntToStr( ThreadItem.NewResCount )); |
|
|
CustomStringReplace( Skin, '&ALLRESCOUNT', IntToStr( ThreadItem.AllResCount )); |
|
|
|
|
|
CustomStringReplace( Skin, '&NEWDATE', FormatDateTime('yyyy/mm/dd(ddd) hh:mm', ThreadItem.RoundDate)); |
|
|
CustomStringReplace( Skin, '&SIZEKB', IntToStr( Floor( SizeByte / 1024 ) )); |
|
|
CustomStringReplace( Skin, '&SIZE', IntToStr( SizeByte )); |
|
|
//----- ここまで |
|
|
end; |
|
|
Result := Skin.Text; |
|
|
finally |
|
|
Skin.Free; |
|
|
end; |
|
|
end; |
|
|
|
|
|
// レスの値を置換する |
|
|
function TGikoSys.SkinedRes( |
|
|
skin: string; |
|
|
Res: TResRec; |
|
|
No: string |
|
|
): string; |
|
|
var |
|
|
spamminess : Extended; |
|
|
wordCount : TWordCount; |
|
|
begin |
|
|
|
|
|
wordCount := TWordCount.Create; |
|
|
try |
|
|
spamminess := Floor( SpamParse( |
|
|
Res.FName + '<>' + Res.FMailTo + '<>' + Res.FBody, wordCount ) * 100 ); |
|
|
|
|
|
Skin := CustomStringReplace( Skin, '<NUMBER/>', |
|
|
'<a href="menu:' + No + '" name="' + No + '">' + No + '</a>'); |
|
|
Skin := CustomStringReplace( Skin, '<PLAINNUMBER/>', No); |
|
|
Skin := CustomStringReplace( Skin, '<NAME/>', '<b>' + Res.FName + '</b>'); |
|
|
Skin := CustomStringReplace( Skin, '<MAILNAME/>', |
|
|
'<a href="mailto:' + Res.FMailTo + '"><b>' + Res.FName + '</b></a>'); |
|
|
Skin := CustomStringReplace( Skin, '<MAIL/>', Res.FMailTo); |
|
|
Skin := CustomStringReplace( Skin, '<DATE/>', Res.FDateTime); |
|
|
Skin := CustomStringReplace( Skin, '<MESSAGE/>', Res.FBody); |
|
|
Skin := CustomStringReplace( Skin, '<SPAMMINESS/>', FloatToStr( spamminess ) ); |
|
|
Skin := CustomStringReplace( Skin, '<NONSPAMMINESS/>', FloatToStr( 100 - spamminess ) ); |
|
|
|
|
|
//----- かちゅ〜しゃ互換用。コメントアウトしてもよし |
|
|
Skin := CustomStringReplace( Skin, '&NUMBER', |
|
|
'<a href="menu:' + No + '" name="' + No + '">' + No + '</a>'); |
|
|
Skin := CustomStringReplace( Skin, '&PLAINNUMBER', No); |
|
|
Skin := CustomStringReplace( Skin, '&NAME', '<b>' + Res.FName + '</b>'); |
|
|
Skin := CustomStringReplace( Skin, '&MAILNAME', |
|
|
'<a href="mailto:' + Res.FMailTo + '"><b>' + Res.FName + '</b></a>'); |
|
|
Skin := CustomStringReplace( Skin, '&MAIL', Res.FMailTo); |
|
|
Skin := CustomStringReplace( Skin, '&DATE', Res.FDateTime); |
|
|
Skin := CustomStringReplace( Skin, '&MESSAGE', Res.FBody); |
|
|
Skin := CustomStringReplace( Skin, '&SPAMMINESS', FloatToStr( spamminess ) ); |
|
|
Skin := CustomStringReplace( Skin, '&NONSPAMMINESS', FloatToStr( 100 - spamminess ) ); |
|
|
//----- ここまで |
|
|
|
|
|
Result := Skin; |
|
|
finally |
|
|
wordCount.Free; |
|
|
end; |
|
|
|
|
|
end; |
|
|
|
|
|
procedure TGikoSys.CreateHTML2(doc: Variant; ThreadItem: TThreadItem; var sTitle: string); |
|
|
var |
|
|
i: integer; |
|
|
No: string; |
|
|
//bufList : TStringList; |
|
|
ReadList: TStringList; |
|
|
SaveList: TStringList; |
|
|
CSSFileName: string; |
|
|
BBSID: string; |
|
|
FileName: string; |
|
|
NewReceiveNo: Integer; |
|
|
Res: TResRec; |
|
|
boardPlugIn : TBoardPlugIn; |
|
|
|
|
|
UserOptionalStyle: string; |
|
|
SkinHeader: string; |
|
|
SkinNewRes: string; |
|
|
SkinRes: string; |
|
|
|
|
|
strTmp : string; |
|
|
// threadURL : string; |
|
|
function LoadSkin( fileName: string ): string; |
|
|
begin |
|
|
Result := LoadFromSkin( fileName, ThreadItem, ThreadItem.Size ); |
|
|
end; |
|
|
function ReplaceRes( skin: string ): string; |
|
|
begin |
|
|
Result := SkinedRes( skin, Res, No ); |
|
|
end; |
|
|
begin |
|
|
if ThreadItem <> nil then begin |
|
|
//if ThreadItem.IsBoardPlugInAvailable then begin |
|
|
if ThreadItem.ParentBoard.IsBoardPlugInAvailable then begin |
|
|
//===== プラグインによる表示 |
|
|
//boardPlugIn := ThreadItem.BoardPlugIn; |
|
|
boardPlugIn := ThreadItem.ParentBoard.BoardPlugIn; |
|
|
NewReceiveNo := ThreadItem.NewReceive; |
|
|
// フォントやサイズの設定 |
|
|
UserOptionalStyle := SetUserOptionalStyle; |
|
|
SaveList := TStringList.Create; |
|
|
try |
|
|
doc.open; |
|
|
// 文字コードはプラグインに任せる |
|
|
// doc.charset := 'Shift_JIS'; |
|
|
|
|
|
// ヘッダ |
|
|
SaveList.Add( boardPlugIn.GetHeader( DWORD( threadItem ), |
|
|
'<style type="text/css">body {' + UserOptionalStyle + '}</style>' ) ); |
|
|
|
|
|
SaveList.Add('<p id="idSearch"></p>'); |
|
|
for i := 0 to threadItem.Count - 1 do begin |
|
|
// 1 は必ず表示 |
|
|
if i <> 0 then begin |
|
|
// 表示範囲を限定 |
|
|
case ResRange of |
|
|
Ord( grrKoko ): |
|
|
if ThreadItem.Kokomade > (i + 1) then |
|
|
Continue; |
|
|
Ord( grrNew ): |
|
|
if NewReceiveNo > (i + 1) then |
|
|
Continue; |
|
|
10..65535: |
|
|
if (threadItem.Count - i) > ResRange then |
|
|
Continue; |
|
|
end; |
|
|
end; |
|
|
|
|
|
// 新着マーク |
|
|
if (NewReceiveNo = (i + 1)) or ((NewReceiveNo = 0) and (i = 0)) then begin |
|
|
try |
|
|
if GikoSys.Setting.UseSkin then begin |
|
|
if FileExists( GetSkinNewmarkFileName ) then |
|
|
SaveList.Add( LoadSkin( GetSkinNewmarkFileName ) ) |
|
|
else |
|
|
SaveList.Add( '<a name="new"></a>' ); |
|
|
end else if GikoSys.Setting.UseCSS then begin |
|
|
SaveList.Add('<a name="new"></a><div class="new">新着レス <span class="newdate">' + FormatDateTime('yyyy/mm/dd(ddd) hh:mm', ThreadItem.RoundDate) + '</span></div>'); |
|
|
end else begin |
|
|
SaveList.Add('</dl>'); |
|
|
SaveList.Add('<a name="new"></a>'); |
|
|
SaveList.Add('<table width="100%" bgcolor="#3333CC" cellpadding="0" cellspacing="1"><tr><td align="center" bgcolor="#6666FF" valign="middle"><font size="-1" color="#ffffff"><b>新着レス ' + FormatDateTime('yyyy/mm/dd(ddd) hh:mm', ThreadItem.RoundDate) + '</b></font></td></tr></table>'); |
|
|
SaveList.Add('<dl>'); |
|
|
end; |
|
|
except |
|
|
SaveList.Add( '<a name="new"></a>' ); |
|
|
end; |
|
|
end; |
|
|
|
|
|
// レス |
|
|
SaveList.Add( boardPlugIn.GetRes( DWORD( threadItem ), i + 1 ) ); |
|
|
|
|
|
if ThreadItem.Kokomade = (i + 1) then begin |
|
|
// ここまで読んだ |
|
|
try |
|
|
if GikoSys.Setting.UseSkin then begin |
|
|
if FileExists( GetSkinBookmarkFileName ) then |
|
|
SaveList.Add( LoadSkin( GetSkinBookmarkFileName ) ) |
|
|
else |
|
|
SaveList.Add( '<a name="koko"></a>' ); |
|
|
end else if GikoSys.Setting.UseCSS then begin |
|
|
SaveList.Add('<a name="koko"></a><div class="koko">ココまで読んだ</div>'); |
|
|
end else begin |
|
|
SaveList.Add('</dl>'); |
|
|
SaveList.Add('<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>ココまで読んだ</b></font></td></tr></table>'); |
|
|
SaveList.Add('<dl>'); |
|
|
end; |
|
|
except |
|
|
SaveList.Add( '<a name="koko"></a>' ); |
|
|
end; |
|
|
end; |
|
|
|
|
|
doc.Write(SaveList.Text); |
|
|
SaveList.Clear; |
|
|
end; |
|
|
|
|
|
|
|
|
// スキン(フッタ) |
|
|
SaveList.Add( boardPlugIn.GetFooter( DWORD( threadItem ), '<a name="bottom"></a>' ) ); |
|
|
doc.Write(SaveList.Text); |
|
|
finally |
|
|
SaveList.Free; |
|
|
doc.Close; |
|
|
end; |
|
|
|
|
|
// Exit; |
|
|
//end; |
|
|
end else begin |
|
|
ShortDayNames[1] := '日'; ShortDayNames[2] := '月'; |
|
|
ShortDayNames[3] := '火'; ShortDayNames[4] := '水'; |
|
|
ShortDayNames[5] := '木'; ShortDayNames[6] := '金'; |
|
|
ShortDayNames[7] := '土'; |
|
|
BBSID := ThreadItem.ParentBoard.BBSID; |
|
|
NewReceiveNo := ThreadItem.NewReceive; |
|
|
ReadList := TStringList.Create; |
|
|
|
|
|
try |
|
|
if ThreadItem.IsLogFile then begin |
|
|
FileName := ThreadItem.GetThreadFileName; |
|
|
ReadList.LoadFromFile(FileName); |
|
|
FAbon.IndividualAbon(ReadList, ChangeFileExt(FileName,'.NG')); |
|
|
FAbon.Execute(ReadList); // あぼ〜んして |
|
|
FSelectResFilter.Execute(ReadList); //レスのフィルタリングをする |
|
|
if ThreadItem.Title = '' then begin |
|
|
Res := DivideStrLine(ReadList[0]); |
|
|
sTitle := Res.FTitle; |
|
|
end else |
|
|
sTitle := ThreadItem.Title |
|
|
end else begin |
|
|
sTitle := CustomStringReplace(ThreadItem.Title, '@`', ','); |
|
|
end; |
|
|
SaveList := TStringList.Create; |
|
|
//threadURL := CustomStringReplace(ThreadItem.URL, 'l50', ''); |
|
|
try |
|
|
doc.open; |
|
|
doc.charset := 'Shift_JIS'; |
|
|
|
|
|
// フォントやサイズの設定 |
|
|
UserOptionalStyle := SetUserOptionalStyle; |
|
|
CSSFileName := GetStyleSheetDir + Setting.CSSFileName; |
|
|
if GikoSys.Setting.UseSkin then begin |
|
|
// スキン使用 |
|
|
// スキンの設定 |
|
|
try |
|
|
SkinHeader := LoadSkin( GetSkinHeaderFileName ); |
|
|
if Length( UserOptionalStyle ) > 0 then |
|
|
SkinHeader := CustomStringReplace( SkinHeader, '</head>', |
|
|
'<style type="text/css">body {' + UserOptionalStyle + '}</style></head>'); |
|
|
SaveList.Add( SkinHeader ); |
|
|
except |
|
|
end; |
|
|
try |
|
|
SkinNewRes := LoadSkin( GetSkinNewResFileName ); |
|
|
except |
|
|
end; |
|
|
try |
|
|
SkinRes := LoadSkin( GetSkinResFileName ); |
|
|
except |
|
|
end; |
|
|
SaveList.Add('<p id="idSearch"></p>'); |
|
|
SaveList.Add('<a name="top"></a>'); |
|
|
|
|
|
for i := 0 to ReadList.Count - 1 do begin |
|
|
// 1 は必ず表示 |
|
|
if i <> 0 then begin |
|
|
// 表示範囲を限定 |
|
|
case ResRange of |
|
|
Ord( grrKoko ): |
|
|
if ThreadItem.Kokomade > (i + 1) then |
|
|
Continue; |
|
|
Ord( grrNew ): |
|
|
if NewReceiveNo > (i + 1) then |
|
|
Continue; |
|
|
10..65535: |
|
|
if (threadItem.Count - i) > ResRange then |
|
|
Continue; |
|
|
end; |
|
|
end; |
|
|
|
|
|
// 新着マーク |
|
|
if (NewReceiveNo = i + 1) or ((NewReceiveNo = 0) and (i = 0)) then begin |
|
|
try |
|
|
if FileExists( GetSkinNewmarkFileName ) then |
|
|
SaveList.Add( LoadSkin( GetSkinNewmarkFileName ) ) |
|
|
else |
|
|
SaveList.Add( '<a name="new"></a>' ); |
|
|
except |
|
|
SaveList.Add( '<a name="new"></a>' ); |
|
|
end; |
|
|
end; |
|
|
if (Trim(ReadList[i]) <> '') then begin |
|
|
No := IntToStr(i + 1); |
|
|
|
|
|
Res := DivideStrLine(ReadList[i]); |
|
|
Res.FBody := ConvRes(AddAnchorTag(Res.FBody), ThreadItem.ParentBoard.BBSID, ChangeFileExt(ThreadItem.FileName, ''), 'bbs', 'key', 'st', 'to', 'nofirst', 'true'); |
|
|
Res.FDateTime := AddBeProfileLink(Res.FDateTime, i + 1); |
|
|
try |
|
|
if NewReceiveNo <= (i + 1) then |
|
|
// 新着レス |
|
|
strTmp := ReplaceRes( SkinNewRes ) |
|
|
else |
|
|
// 通常のレス |
|
|
strTmp := ReplaceRes( SkinRes ); |
|
|
|
|
|
SaveList.Add( strTmp ); |
|
|
except |
|
|
end; |
|
|
end; |
|
|
|
|
|
if ThreadItem.Kokomade = (i + 1) then begin |
|
|
// ここまで読んだ |
|
|
try |
|
|
if FileExists( GetSkinBookmarkFileName ) then |
|
|
SaveList.Add( LoadSkin( GetSkinBookmarkFileName ) ) |
|
|
else |
|
|
SaveList.Add( '<a name="koko"></a>' ); |
|
|
except |
|
|
SaveList.Add( '<a name="koko"></a>' ); |
|
|
end; |
|
|
end; |
|
|
doc.Write(SaveList.Text); |
|
|
SaveList.Clear; |
|
|
end; |
|
|
SaveList.Add('<a name="bottom"></a>'); |
|
|
// スキン(フッタ) |
|
|
try |
|
|
SaveList.Add( LoadSkin( GetSkinFooterFileName ) ); |
|
|
except |
|
|
end; |
|
|
doc.Write(SaveList.Text); |
|
|
end else if GikoSys.Setting.UseCSS and FileExists(CSSFileName) then begin |
|
|
//CSS使用 |
|
|
//CSSFileName := GetAppDir + CSS_FILE_NAME; |
|
|
// SaveList.Add('<html lang="ja"><head>'); |
|
|
SaveList.Add('<html><head>'); |
|
|
SaveList.Add('<meta http-equiv="Content-type" content="text/html; charset=Shift_JIS">'); |
|
|
SaveList.Add('<title>' + sTitle + '</title>'); |
|
|
SaveList.Add('<link rel="stylesheet" href="'+CSSFileName+'" type="text/css">'); |
|
|
if Length( UserOptionalStyle ) > 0 then |
|
|
SaveList.Add('<style type="text/css">body {' + UserOptionalStyle + '}</style>'); |
|
|
SaveList.Add('</head>'); |
|
|
SaveList.Add('<body>'); |
|
|
SaveList.Add('<a name="top"></a>'); |
|
|
SaveList.Add('<p id="idSearch"></p>'); |
|
|
SaveList.Add('<div class="title">' + sTitle + '</div>'); |
|
|
doc.Write(SaveList.Text); |
|
|
SaveList.Clear; |
|
|
//Application.ProcessMessages; |
|
|
for i := 0 to ReadList.Count - 1 do begin |
|
|
// 1 は必ず表示 |
|
|
if i <> 0 then begin |
|
|
// 表示範囲を限定 |
|
|
case ResRange of |
|
|
Ord( grrKoko ): |
|
|
if ThreadItem.Kokomade > (i + 1) then |
|
|
Continue; |
|
|
Ord( grrNew ): |
|
|
if NewReceiveNo > (i + 1) then |
|
|
Continue; |
|
|
10..65535: |
|
|
if (threadItem.Count - i) > ResRange then |
|
|
Continue; |
|
|
end; |
|
|
end; |
|
|
|
|
|
if (NewReceiveNo = (i + 1)) or ((NewReceiveNo = 0) and (i = 0)) then begin |
|
|
SaveList.Add('<a name="new"></a><div class="new">新着レス <span class="newdate">' + FormatDateTime('yyyy/mm/dd(ddd) hh:mm', ThreadItem.RoundDate) + '</span></div>'); |
|
|
end; |
|
|
if (Trim(ReadList[i]) <> '') then begin |
|
|
No := IntToStr(i + 1); |
|
|
Res := DivideStrLine(ReadList[i]); |
|
|
Res.FBody := ConvRes(AddAnchorTag(Res.FBody), ThreadItem.ParentBoard.BBSID, ChangeFileExt(ThreadItem.FileName, ''), 'bbs', 'key', 'st', 'to', 'nofirst', 'true'); |
|
|
Res.FDateTime := AddBeProfileLink(Res.FDateTime, i + 1); |
|
|
if Res.FMailTo = '' then |
|
|
SaveList.Add('<a name="' + No + '"></a>' |
|
|
+ '<div class="header"><span class="no"><a href="menu:' + No + '">' + No + '</a></span> ' |
|
|
+ '<span class="name_label">名前:</span> ' |
|
|
+ '<span class="name"><b>' + Res.FName + '</b></span> ' |
|
|
+ '<span class="date_label">投稿日:</span> ' |
|
|
+ '<span class="date">' + Res.FDateTime+ '</span></div>' |
|
|
+ '<div class="mes">' + Res.FBody + ' </div>') |
|
|
else if GikoSys.Setting.ShowMail then |
|
|
SaveList.Add('<a name="' + No + '"></a>' |
|
|
+ '<div class="header"><span class="no"><a href="menu:' + No + '">' + No + '</a></span>' |
|
|
+ '<span class="name_label"> 名前: </span>' |
|
|
+ '<a class="name_mail" href="mailto:' + Res.FMailTo + '">' |
|
|
+ '<b>' + Res.FName + '</b></a><span class="mail"> [' + Res.FMailTo + ']</span>' |
|
|
+ '<span class="date_label"> 投稿日:</span>' |
|
|
+ '<span class="date"> ' + Res.FDateTime+ '</span></div>' |
|
|
+ '<div class="mes">' + Res.FBody + ' </div>') |
|
|
else |
|
|
SaveList.Add('<a name="' + No + '"></a>' |
|
|
+ '<div class="header"><span class="no"><a href="menu:' + No + '">' + No + '</a></span>' |
|
|
+ '<span class="name_label"> 名前: </span>' |
|
|
+ '<a class="name_mail" href="mailto:' + Res.FMailTo + '">' |
|
|
+ '<b>' + Res.FName + '</b></a>' |
|
|
+ '<span class="date_label"> 投稿日:</span>' |
|
|
+ '<span class="date"> ' + Res.FDateTime+ '</span></div>' |
|
|
+ '<div class="mes">' + Res.FBody + ' </div>'); |
|
|
end; |
|
|
if ThreadItem.Kokomade = (i + 1) then begin |
|
|
SaveList.Add('<a name="koko"></a><div class="koko">ココまで読んだ</div>'); |
|
|
end; |
|
|
|
|
|
doc.Write(SaveList.Text); |
|
|
SaveList.Clear; |
|
|
end; |
|
|
SaveList.Add('<a name="bottom"></a>'); |
|
|
//SaveList.Add('</body></html>'); |
|
|
SaveList.Add('<a name="last"></a>'); |
|
|
SaveList.Add('</body></html>'); |
|
|
doc.Write(SaveList.Text); |
|
|
end else begin |
|
|
//CSS非使用 |
|
|
// SaveList.Add('<html lang="ja"><head>'); |
|
|
SaveList.Add('<html><head>'); |
|
|
SaveList.Add('<meta http-equiv="Content-type" content="text/html; charset=Shift_JIS">'); |
|
|
SaveList.Add('<title>' + sTitle + '</title></head>'); |
|
|
SaveList.Add('<body TEXT="#000000" BGCOLOR="#EFEFEF" link="#0000FF" alink="#FF0000" vlink="#660099">'); |
|
|
SaveList.Add('<a name="top"></a>'); |
|
|
SaveList.Add('<font size=+1 color="#FF0000">' + sTitle + '</font>'); |
|
|
SaveList.Add('<dl>'); |
|
|
SaveList.Add('<p id="idSearch"></p>'); |
|
|
doc.Write(SaveList.Text); |
|
|
SaveList.Clear; |
|
|
//Application.ProcessMessages; |
|
|
for i := 0 to ReadList.Count - 1 do begin |
|
|
// 1 は必ず表示 |
|
|
if i <> 0 then begin |
|
|
// 表示範囲を限定 |
|
|
case ResRange of |
|
|
Ord( grrKoko ): |
|
|
if ThreadItem.Kokomade > (i + 1) then |
|
|
Continue; |
|
|
Ord( grrNew ): |
|
|
if NewReceiveNo > (i + 1) then |
|
|
Continue; |
|
|
10..65535: |
|
|
if (threadItem.Count - i) > ResRange then |
|
|
Continue; |
|
|
end; |
|
|
end; |
|
|
|
|
|
if (NewReceiveNo = (i + 1)) or ((NewReceiveNo = 0) and (i = 0)) then begin |
|
|
SaveList.Add('</dl>'); |
|
|
SaveList.Add('<a name="new"></a>'); |
|
|
SaveList.Add('<table width="100%" bgcolor="#3333CC" cellpadding="0" cellspacing="1"><tr><td align="center" bgcolor="#6666FF" valign="middle"><font size="-1" color="#ffffff"><b>新着レス ' + FormatDateTime('yyyy/mm/dd(ddd) hh:mm', ThreadItem.RoundDate) + '</b></font></td></tr></table>'); |
|
|
SaveList.Add('<dl>'); |
|
|
end; |
|
|
if (Trim(ReadList[i]) <> '') then begin |
|
|
No := IntToStr(i + 1); |
|
|
Res := DivideStrLine(ReadList[i]); |
|
|
Res.FBody := ConvRes(AddAnchorTag(Res.FBody), ThreadItem.ParentBoard.BBSID, ChangeFileExt(ThreadItem.FileName, ''), 'bbs', 'key', 'st', 'to', 'nofirst', 'true'); |
|
|
Res.FDateTime := AddBeProfileLink(Res.FDateTime, i + 1); |
|
|
if Res.FMailTo = '' then |
|
|
SaveList.Add('<a name="' + No + '"></a><dt><a href="menu:' + No + '">' + No + '</a> 名前:<font color="forestgreen"><b> ' + Res.FName + ' </b></font> 投稿日: <span class="date">' + Res.FDateTime+ '</span><br><dd>' + Res.Fbody + ' <br><br><br>') |
|
|
else if GikoSys.Setting.ShowMail then |
|
|
SaveList.Add('<a name="' + No + '"></a><dt><a href="menu:' + No + '">' + No + '</a> 名前:<a href="mailto:' + Res.FMailTo + '"><b> ' + Res.FName + ' </B></a> [' + Res.FMailTo + '] 投稿日: <span class="date">' + Res.FDateTime+ '</span><br><dd>' + Res.Fbody + ' <br><br><br>') |
|
|
else |
|
|
SaveList.Add('<a name="' + No + '"></a><dt><a href="menu:' + No + '">' + No + '</a> 名前:<a href="mailto:' + Res.FMailTo + '"><b> ' + Res.FName + ' </B></a> 投稿日: <span class="date">' + Res.FDateTime+ '</span><br><dd>' + Res.Fbody + ' <br><br><br>'); |
|
|
end; |
|
|
if ThreadItem.Kokomade = (i + 1) then begin |
|
|
SaveList.Add('</dl>'); |
|
|
SaveList.Add('<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>ココまで読んだ</b></font></td></tr></table>'); |
|
|
SaveList.Add('<dl>'); |
|
|
end; |
|
|
doc.Write(SaveList.Text); |
|
|
SaveList.Clear; |
|
|
end; |
|
|
SaveList.Add('</dl>'); |
|
|
SaveList.Add('<a name="bottom"></a>'); |
|
|
SaveList.Add('</body></html>'); |
|
|
doc.Write(SaveList.Text); |
|
|
end; |
|
|
finally |
|
|
SaveList.Free; |
|
|
doc.Close; |
|
|
end; |
|
|
finally |
|
|
ReadList.Free; |
|
|
end; |
|
|
end; |
|
|
end; |
|
|
end; |
|
|
procedure TGikoSys.CreateHTML3(var html: TStringList; ThreadItem: TThreadItem; var sTitle: string); |
|
|
var |
|
|
i: integer; |
|
|
No: string; |
|
|
//bufList : TStringList; |
|
|
ReadList: TStringList; |
|
|
// SaveList: TStringList; |
|
|
CSSFileName: string; |
|
|
BBSID: string; |
|
|
FileName: string; |
|
|
Res: TResRec; |
|
|
boardPlugIn : TBoardPlugIn; |
|
|
|
|
|
UserOptionalStyle: string; |
|
|
SkinHeader: string; |
|
|
SkinRes: string; |
|
|
tmp, tmp1: string; |
|
|
function LoadSkin( fileName: string ): string; |
|
|
begin |
|
|
Result := LoadFromSkin( fileName, ThreadItem, ThreadItem.Size ); |
|
|
end; |
|
|
function ReplaceRes( skin: string ): string; |
|
|
begin |
|
|
Result := SkinedRes( skin, Res, No ); |
|
|
end; |
|
|
|
|
|
begin |
|
|
if ThreadItem <> nil then begin |
|
|
CSSFileName := GetStyleSheetDir + Setting.CSSFileName; |
|
|
html.Clear; |
|
|
html.BeginUpdate; |
|
|
//if ThreadItem.IsBoardPlugInAvailable then begin |
|
|
if ThreadItem.ParentBoard.IsBoardPlugInAvailable then begin |
|
|
//===== プラグインによる表示 |
|
|
//boardPlugIn := ThreadItem.BoardPlugIn; |
|
|
boardPlugIn := ThreadItem.ParentBoard.BoardPlugIn; |
|
|
// フォントやサイズの設定 |
|
|
UserOptionalStyle := SetUserOptionalStyle; |
|
|
try |
|
|
// 文字コードはプラグインに任せる |
|
|
// ヘッダ |
|
|
tmp := boardPlugIn.GetHeader( DWORD( threadItem ), |
|
|
'<style type="text/css">body {' + UserOptionalStyle + '}</style>' ); |
|
|
//絶対参照から相対参照へ |
|
|
if Setting.UseSkin then begin |
|
|
tmp1 := './' +Setting.CSSFileName; |
|
|
tmp1 := CustomStringReplace(tmp1, GetConfigDir, ''); |
|
|
tmp1 := CustomStringReplace(tmp1, '\', '/'); |
|
|
tmp := CustomStringReplace(tmp, ExtractFilePath(Setting.CSSFileName), tmp1); |
|
|
end else if Setting.UseCSS then begin |
|
|
tmp1 := './' + CSSFileName; |
|
|
tmp1 := CustomStringReplace(tmp1, GetConfigDir, ''); |
|
|
tmp1 := CustomStringReplace(tmp1, '\', '/'); |
|
|
tmp := CustomStringReplace(tmp, CSSFileName, tmp1); |
|
|
end; |
|
|
html.Append( tmp ); |
|
|
|
|
|
for i := 0 to threadItem.Count - 1 do begin |
|
|
|
|
|
// レス |
|
|
html.Append( ConvertResAnchor(boardPlugIn.GetRes( DWORD( threadItem ), i + 1 )) ); |
|
|
|
|
|
end; |
|
|
// スキン(フッタ) |
|
|
html.Append( boardPlugIn.GetFooter( DWORD( threadItem ), '<a name="bottom"></a>' ) ); |
|
|
finally |
|
|
end; |
|
|
html.EndUpdate; |
|
|
//Exit; |
|
|
end else begin |
|
|
ShortDayNames[1] := '日'; ShortDayNames[2] := '月'; |
|
|
ShortDayNames[3] := '火'; ShortDayNames[4] := '水'; |
|
|
ShortDayNames[5] := '木'; ShortDayNames[6] := '金'; |
|
|
ShortDayNames[7] := '土'; |
|
|
BBSID := ThreadItem.ParentBoard.BBSID; |
|
|
ReadList := TStringList.Create; |
|
|
try |
|
|
if ThreadItem.IsLogFile then begin |
|
|
FileName := ThreadItem.GetThreadFileName; |
|
|
ReadList.LoadFromFile(FileName); |
|
|
FAbon.IndividualAbon(ReadList, ChangeFileExt(FileName,'.NG')); |
|
|
FAbon.Execute(ReadList); // あぼ〜んして |
|
|
FSelectResFilter.Execute(ReadList); //レスのフィルタリングをする |
|
|
Res := DivideStrLine(ReadList[0]); |
|
|
//Res.FTitle := CustomStringReplace(Res.FTitle, '@`', ','); |
|
|
sTitle := Res.FTitle; |
|
|
end else begin |
|
|
sTitle := CustomStringReplace(ThreadItem.Title, '@`', ','); |
|
|
end; |
|
|
try |
|
|
// フォントやサイズの設定 |
|
|
UserOptionalStyle := SetUserOptionalStyle; |
|
|
|
|
|
if GikoSys.Setting.UseSkin then begin |
|
|
// スキン使用 |
|
|
// スキンの設定 |
|
|
try |
|
|
SkinHeader := LoadSkin( GetSkinHeaderFileName ); |
|
|
if Length( UserOptionalStyle ) > 0 then |
|
|
SkinHeader := CustomStringReplace( SkinHeader, '</head>', |
|
|
'<style type="text/css">body {' + UserOptionalStyle + '}</style></head>'); |
|
|
//絶対参照から相対参照へ |
|
|
tmp1 := './' +Setting.CSSFileName; |
|
|
tmp1 := CustomStringReplace(tmp1, GetConfigDir, ''); |
|
|
tmp1 := CustomStringReplace(tmp1, '\', '/'); |
|
|
SkinHeader := CustomStringReplace(SkinHeader, ExtractFilePath(Setting.CSSFileName), tmp1); |
|
|
html.Append( SkinHeader ); |
|
|
except |
|
|
end; |
|
|
try |
|
|
SkinRes := LoadSkin( GetSkinResFileName ); |
|
|
except |
|
|
end; |
|
|
html.Append('<a name="top"></a>'); |
|
|
for i := 0 to ReadList.Count - 1 do begin |
|
|
if (Trim(ReadList[i]) <> '') then begin |
|
|
No := IntToStr(i + 1); |
|
|
|
|
|
Res := DivideStrLine(ReadList[i]); |
|
|
Res.FBody := AddAnchorTag(Res.FBody); |
|
|
Res.FBody := ConvertResAnchor(ConvRes(Res.FBody, ThreadItem.ParentBoard.BBSID, ChangeFileExt(ThreadItem.FileName, ''), 'bbs', 'key', 'st', 'to', 'nofirst', 'true', true)); |
|
|
|
|
|
try |
|
|
html.Append( ReplaceRes( SkinRes ) ); |
|
|
except |
|
|
end; |
|
|
end; |
|
|
|
|
|
end; |
|
|
html.Append('<a name="bottom"></a>'); |
|
|
// スキン(フッタ) |
|
|
try |
|
|
html.Append( LoadSkin( GetSkinFooterFileName ) ); |
|
|
except |
|
|
end; |
|
|
end else if GikoSys.Setting.UseCSS and FileExists(CSSFileName) then begin |
|
|
//CSS使用 |
|
|
//CSSFileName := GetAppDir + CSS_FILE_NAME; |
|
|
html.Append('<html><head>'); |
|
|
html.Append('<meta http-equiv="Content-type" content="text/html; charset=Shift_JIS">'); |
|
|
html.Append('<title>' + sTitle + '</title>'); |
|
|
//絶対参照から相対参照へ |
|
|
tmp1 := './' + CSSFileName; |
|
|
tmp1 := CustomStringReplace(tmp1, GetConfigDir, ''); |
|
|
tmp1 := CustomStringReplace(tmp1, '\', '/'); |
|
|
|
|
|
html.Append('<link rel="stylesheet" href="'+tmp1+'" type="text/css">'); |
|
|
if Length( UserOptionalStyle ) > 0 then |
|
|
html.Append('<style type="text/css">body {' + UserOptionalStyle + '}</style>'); |
|
|
html.Append('</head>'); |
|
|
html.Append('<body>'); |
|
|
html.Append('<a name="top"></a>'); |
|
|
html.Append('<div class="title">' + sTitle + '</div>'); |
|
|
for i := 0 to ReadList.Count - 1 do begin |
|
|
if (Trim(ReadList[i]) <> '') then begin |
|
|
No := IntToStr(i + 1); |
|
|
Res := DivideStrLine(ReadList[i]); |
|
|
Res.FBody := AddAnchorTag(Res.FBody); |
|
|
Res.FBody := ConvertResAnchor(ConvRes(Res.FBody, ThreadItem.ParentBoard.BBSID, ChangeFileExt(ThreadItem.FileName, ''), 'bbs', 'key', 'st', 'to', 'nofirst', 'true', true)); |
|
|
if Res.FMailTo = '' then |
|
|
html.Append('<a name="' + No + '"></a>' |
|
|
+ '<div class="header"><span class="no"><a href="menu:' + No + '">' + No + '</a></span> ' |
|
|
+ '<span class="name_label">名前:</span> ' |
|
|
+ '<span class="name"><b>' + Res.FName + '</b></span> ' |
|
|
+ '<span class="date_label">投稿日:</span> ' |
|
|
+ '<span class="date">' + Res.FDateTime+ '</span></div>' |
|
|
+ '<div class="mes">' + Res.FBody + ' </div>') |
|
|
else if GikoSys.Setting.ShowMail then |
|
|
html.Append('<a name="' + No + '"></a>' |
|
|
+ '<div class="header"><span class="no"><a href="menu:' + No + '">' + No + '</a></span>' |
|
|
+ '<span class="name_label"> 名前: </span>' |
|
|
+ '<a class="name_mail" href="mailto:' + Res.FMailTo + '">' |
|
|
+ '<b>' + Res.FName + '</b></a><span class="mail"> [' + Res.FMailTo + ']</span>' |
|
|
+ '<span class="date_label"> 投稿日:</span>' |
|
|
+ '<span class="date"> ' + Res.FDateTime+ '</span></div>' |
|
|
+ '<div class="mes">' + Res.FBody + ' </div>') |
|
|
else |
|
|
html.Append('<a name="' + No + '"></a>' |
|
|
+ '<div class="header"><span class="no"><a href="menu:' + No + '">' + No + '</a></span>' |
|
|
+ '<span class="name_label"> 名前: </span>' |
|
|
+ '<a class="name_mail" href="mailto:' + Res.FMailTo + '">' |
|
|
+ '<b>' + Res.FName + '</b></a>' |
|
|
+ '<span class="date_label"> 投稿日:</span>' |
|
|
+ '<span class="date"> ' + Res.FDateTime+ '</span></div>' |
|
|
+ '<div class="mes">' + Res.FBody + ' </div>'); |
|
|
end; |
|
|
end; |
|
|
html.Append('<a name="bottom"></a>'); |
|
|
html.Append('<a name="last"></a>'); |
|
|
html.Append('</body></html>'); |
|
|
end else begin |
|
|
//CSS非使用 |
|
|
html.Append('<html><head>'); |
|
|
html.Append('<meta http-equiv="Content-type" content="text/html; charset=Shift_JIS">'); |
|
|
html.Append('<title>' + sTitle + '</title></head>'); |
|
|
html.Append('<body TEXT="#000000" BGCOLOR="#EFEFEF" link="#0000FF" alink="#FF0000" vlink="#660099">'); |
|
|
html.Append('<a name="top"></a>'); |
|
|
html.Append('<font size=+1 color="#FF0000">' + sTitle + '</font>'); |
|
|
html.Append('<dl>'); |
|
|
for i := 0 to ReadList.Count - 1 do begin |
|
|
if (Trim(ReadList[i]) <> '') then begin |
|
|
No := IntToStr(i + 1); |
|
|
Res := DivideStrLine(ReadList[i]); |
|
|
Res.FBody := AddAnchorTag(Res.FBody); |
|
|
Res.FBody := ConvertResAnchor(ConvRes(Res.FBody, ThreadItem.ParentBoard.BBSID, ChangeFileExt(ThreadItem.FileName, ''), 'bbs', 'key', 'st', 'to', 'nofirst', 'true', true)); |
|
|
if Res.FMailTo = '' then |
|
|
html.Append('<a name="' + No + '"></a><dt><a href="menu:' + No + '">' + No + '</a> 名前:<font color="forestgreen"><b> ' + Res.FName + ' </b></font> 投稿日: ' + Res.FDateTime+ '<br><dd>' + Res.Fbody + ' <br><br><br>') |
|
|
else if GikoSys.Setting.ShowMail then |
|
|
html.Append('<a name="' + No + '"></a><dt><a href="menu:' + No + '">' + No + '</a> 名前:<a href="mailto:' + Res.FMailTo + '"><b> ' + Res.FName + ' </B></a> [' + Res.FMailTo + '] 投稿日: ' + Res.FDateTime+ '<br><dd>' + Res.Fbody + ' <br><br><br>') |
|
|
else |
|
|
html.Append('<a name="' + No + '"></a><dt><a href="menu:' + No + '">' + No + '</a> 名前:<a href="mailto:' + Res.FMailTo + '"><b> ' + Res.FName + ' </B></a> 投稿日: ' + Res.FDateTime+ '<br><dd>' + Res.Fbody + ' <br><br><br>'); |
|
|
end; |
|
|
end; |
|
|
html.Append('</dl>'); |
|
|
html.Append('<a name="bottom"></a>'); |
|
|
html.Append('</body></html>'); |
|
|
end; |
|
|
finally |
|
|
html.EndUpdate; |
|
|
end; |
|
|
finally |
|
|
ReadList.Free; |
|
|
end; |
|
|
end; |
|
|
end; |
|
|
end; |
|
|
function TGikoSys.ConvertResAnchor(res: string): string; |
|
|
const |
|
|
_HEAD : string = '<a href="../'; |
|
|
_TAIL : string = ' target="_blank">'; |
|
|
_ST: string = '&st='; |
|
|
_TO: string = '&to='; |
|
|
_STA: string = '&START='; |
|
|
_END: string = '&END='; |
|
|
var |
|
|
i, j, k: Integer; |
|
|
tmp: string; |
|
|
begin |
|
|
Result := ''; |
|
|
i := AnsiPos(_HEAD, res); |
|
|
while i <> 0 do begin |
|
|
Result := Result + Copy(res, 1, i -1); |
|
|
Delete(res, 1, i - 1); |
|
|
j := AnsiPos(_TAIL, res); |
|
|
if j = 0 then begin |
|
|
Result := Result + res; |
|
|
Exit; |
|
|
end; |
|
|
tmp := Copy(res, 1, j - 1); |
|
|
Delete(res, 1, j + 16); |
|
|
if (AnsiPos(_ST, tmp) <> 0) and (AnsiPos(_TO, tmp) <> 0) then begin |
|
|
Delete(tmp, 1, AnsiPos(_ST, tmp) + 3); |
|
|
Delete(tmp, AnsiPos(_TO, tmp), Length(tmp)); |
|
|
Result := Result + '<a href="#' + tmp + '">'; |
|
|
end else if (AnsiPos(_STA, tmp) <> 0) and (AnsiPos(_END, tmp) <> 0) then begin |
|
|
Delete(tmp, 1, AnsiPos(_STA, tmp) + 6); |
|
|
Delete(tmp, AnsiPos(_END, tmp), Length(tmp)); |
|
|
Result := Result + '<a href="#' + tmp + '">'; |
|
|
end else begin |
|
|
k := LastDelimiter('/', tmp); |
|
|
Delete(tmp, 1, k); |
|
|
if AnsiPos('-', tmp) < AnsiPos('"', tmp) then |
|
|
Delete(tmp, AnsiPos('-', tmp), Length(tmp)) |
|
|
else |
|
|
Delete(tmp, AnsiPos('"', tmp), Length(tmp)); |
|
|
|
|
|
Result := Result + '<a href="#' + tmp + '">'; |
|
|
end; |
|
|
i := AnsiPos(_HEAD, res); |
|
|
end; |
|
|
Result := Result + res; |
|
|
|
|
|
end; |
|
|
|
|
|
(************************************************************************* |
|
|
*http://の文字列をanchorタグ付きにする。 |
|
|
*************************************************************************) |
|
|
function TGikoSys.AddAnchorTag(s: string): string; |
|
|
const |
|
|
URL_CHAR: string = '0123456789' |
|
|
+ 'abcdefghijklmnopqrstuvwxyz' |
|
|
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
|
|
+ '#$%&()*+,-./:;=?@[]^_`{|}~!''\'; |
|
|
ANCHOR_REF = 'href='; |
|
|
RES_REF = '>>'; |
|
|
REF_MARK: array[0..9] of string = ('http://', 'ttp://', 'tp://', |
|
|
'ms-help://','p://', 'https://', |
|
|
'www.', 'ftp://','news://','rtsp://'); |
|
|
|
|
|
var |
|
|
// wkIdx: array[0..9] of Integer; |
|
|
url: string; |
|
|
href: string; |
|
|
i, j, b: Integer; |
|
|
tmp: Integer; |
|
|
idx, idx2: Integer; |
|
|
anchorLen : Integer; |
|
|
pp, pe : PChar; |
|
|
pURLCHARs : PChar; |
|
|
pURLCHARe : PChar; |
|
|
begin |
|
|
Result := ''; |
|
|
// + 3 は 'href="' ('"'つき)などのバリエーションに余裕を持たせるため |
|
|
anchorLen := Length( ANCHOR_REF ) + 3; |
|
|
pURLCHARs := PChar(URL_CHAR); |
|
|
pURLCHARe := pURLCHARs + Length(URL_CHAR); |
|
|
while True do begin |
|
|
idx := MaxInt; |
|
|
idx2 := MaxInt; |
|
|
for j := 0 to 9 do begin |
|
|
tmp := AnsiPos(REF_MARK[j], s); |
|
|
if tmp <> 0 then idx := Min(tmp, idx); |
|
|
if idx = tmp then idx2 := j; //どのマークで引っかかったかを保存 |
|
|
end; |
|
|
if idx = MaxInt then begin |
|
|
//リンクが無いよ。 |
|
|
Result := Result + s; |
|
|
Break; |
|
|
end; |
|
|
|
|
|
if (idx > 1) and |
|
|
(Pos( ANCHOR_REF, Copy(s, idx - anchorLen, anchorLen ) ) > 0) then begin |
|
|
//既にリンクタグがついているっぽいときはムシ |
|
|
href := Copy( s, idx, Length( s ) ); |
|
|
Result := Result + Copy( s, 1, idx + Pos( '</a>', href ) + Length( '</a>' ) - 2 ); |
|
|
s := href; |
|
|
s := Copy( s, Pos( '</a>', s ) + Length( '</a>' ), Length( s ) ); |
|
|
|
|
|
Continue; |
|
|
end; |
|
|
|
|
|
Result := Result + Copy(s, 1, idx - 1); |
|
|
|
|
|
Delete(s, 1, idx - 1); |
|
|
b := Length( s ) + 1; |
|
|
pp := PChar(s); |
|
|
for i := 1 to b do begin |
|
|
pe := AnsiStrPosEx(pURLCHARs, pURLCHARe, pp, pp + 1); |
|
|
|
|
|
if pe = nil then begin |
|
|
//URLじゃない文字発見!とか、文字がなくなった。 |
|
|
url := Copy(s, 1, i - 1); |
|
|
case idx2 of |
|
|
1 : href := 'h' + url; |
|
|
2 : href := 'ht' + url; |
|
|
4 : href := 'htt' + url; |
|
|
6 : href := 'http://' + url; |
|
|
else |
|
|
href := url; |
|
|
end; |
|
|
|
|
|
Result := Result + '<a href="' + href + '" target="_blank">' + url + '</a>'; |
|
|
Delete(s, 1, i - 1); |
|
|
Break; |
|
|
end; |
|
|
//一文字進める。 |
|
|
Inc(pp); |
|
|
end; |
|
|
end; |
|
|
end; |
|
| 1034 |
|
|
| 1035 |
(************************************************************************* |
(************************************************************************* |
| 1036 |
*サブジェクト一行を分割 |
*サブジェクト一行を分割 |