{------------------------------- WideStrRecListの処理についてまとめたユニットです 2009/01/07 ・InsertLineHeadStr→Strを削除 2009/01/09 ・LineMaxLength/TabToSpaceLine/AddStringPreLineBreak /LineRightFillSpace/LineRightFillTab をIndentChangeから移動 リファクタリングしてInsertQuoteで使用する --------------------------------} unit WideStrRecListUnit; interface uses SysUtils, //+EmptyStr WideStringRecordList, ConstUnit, StringUnit, Math, uses_end; function InsertLineHead(const S, InsertStr: WideString): WideString; function TabToSpaceLine(const S: WideString): WideString; type TLineMaxLength = record Index: Integer; Length: Integer; end; {↑行の中の最大長とその位置を返すrecord} function LineMaxLength(StrList: TWideStringRecordList; TabCount: Integer): TLineMaxLength; function AddStringPreLineBreak(const LineStr, AddStr: WideString): WideString; function LineRightFillSpace(const S: WideString; TabCount, MaxLength: Integer): WideString; function LineRightFillTab(const S: WideString; TabCount, MaxLength: Integer): WideString; implementation function InsertLineHead(const S, InsertStr: WideString): WideString; var StrList: TWideStringRecordList; i: Integer; begin if S = EmptyStr then begin Result := InsertStr; end else begin StrList := TWideStringRecordList.Create; try StrList.Text := S; for i:=0 to StrList.Count-1 do begin StrList.Items[i] := InsertStr + StrList.Items[i]; end; Result := StrList.Text; finally StrList.Free; end; end; end; //WideString版 //タブをスペースに置き換える処理 //これもSには行文字列限定とする。 function TabToSpaceLine(const S: WideString): WideString; var ReadIndex: Integer; OutputIndex: Integer; SourceLen: Integer; TabReplaceSpaceCount: Integer; i: Integer; const TabToSpaceOptionCount = 4; begin Result := ''; if S = '' then Exit; SourceLen := Length(S); SetLength(Result, SourceLen * 4); ReadIndex := 1; OutputIndex := 1; while (ReadIndex <= SourceLen) do begin if (S[ReadIndex] = TAB) then begin TabReplaceSpaceCount := TabToSpaceOptionCount - ( CharToByteLen(Result, (OutputIndex-1)) mod TabToSpaceOptionCount ); for i:=0 to TabReplaceSpaceCount-1 do begin Result[OutputIndex+i] := ' '; end; Inc(OutputIndex, TabReplaceSpaceCount); Inc(ReadIndex); end else begin Result[OutputIndex] := S[ReadIndex]; Inc(OutputIndex); Inc(ReadIndex); end; end; //while SetLength(Result, OutputIndex-1); end; //終端改行コードの前に文字列を挿入する関数 function AddStringPreLineBreak(const LineStr, AddStr: WideString): WideString; var LineBreak: String; LineText: WideString; i: Integer; WriteIndex: Integer; begin {↓改行コード文字を調べる} LineBreak := LineBreakString(LastLineBreakStyle(LineStr)); {↓改行コードのない文字列に対しても正しく動作する} SetLength(Result, Length(LineStr)+Length(AddStr)); WriteIndex := 1; for i:=1 to Length(LineStr)-Length(LineBreak) do begin Result[WriteIndex] := LineStr[i]; Inc(WriteIndex); end; for i:=1 to Length(AddStr) do begin Result[WriteIndex] := AddStr[i]; Inc(WriteIndex); end; for i:=1 to Length(LineBreak) do begin Result[WriteIndex] := WideChar(LineBreak[i]); Inc(WriteIndex); end; end; {------------------------------- // 複数行の中から一番長い行の文字Byte数を返す関数 機能: 改行コードは含まない文字列長を返す RecordListの内容が一行もなければ Index=-1,Length=0を返す 備考: 実装上、リストの1行に [ABC\r\nCDF]等が入っている場合は対応不可能 [ABC\r\n]や[ABC]だけが入っているものに限り動作する 履歴: 2009/01/09(金) 00:58 //--▼----------------------▽--} function LineMaxLength(StrList: TWideStringRecordList; TabCount: Integer): TLineMaxLength; var i, j: Integer; LineLength: Integer; LineAnsiStr: String; begin Result.Index := -1; Result.Length := 0; for i := 0 to StrList.Count-1 do begin LineLength := 0; LineAnsiStr := TabToSpaceLine(StrList.Items[i]); {↑タブの文字数計算はスペースに変換しておくから大丈夫} j := 1; while j <= Length(LineAnsiStr) do begin if LineAnsiStr[j] in [CR, LF] then begin break; end else begin Inc(LineLength); end; Inc(j) end; if Result.Length < LineLength then begin Result.Index := i; Result.Length := LineLength; end; end; end; //--△----------------------▲-- {------------------------------- // 行文字列の右側を空白で埋める 備考: Sには行文字列、つまり [ABC\r\n]というような文字列がくるとする。 履歴: 2009/01/09(金) 00:58 //--▼----------------------▽--} function LineRightFillSpace(const S: WideString; TabCount, MaxLength: Integer): WideString; var IncrementCount: Integer; begin Result := S; ExcludeLineBreakProc(Result); IncrementCount := MaxLength - Length(AnsiString(TabToSpaceLine(Result))); Result := AddStringPreLineBreak(S, StringOfChar(' ', IncrementCount) ); end; //切り上げ除算 function PlusDiv(A, B: Integer): Integer; begin Result := A div B; if (A mod B)<>0 then Inc(Result); end; function LineRightFillTab(const S: WideString; TabCount, MaxLength: Integer): WideString; var IncrementCount: Integer; begin Result := S; ExcludeLineBreakProc(Result); IncrementCount := PlusDiv( (MaxLength - Length(AnsiString(TabToSpaceLine(Result)))), TabCount ); Result := AddStringPreLineBreak(S, StringOfChar(TAB, IncrementCount) ); end; //--△----------------------▲-- end.