はじめに
Delphi のソースファイルはデフォルト ANSI コードページが使われるので、海外の方が作ったアプリのソースファイルを開くとソースコードが破壊される事があります。
また、自身で書いたコードもデフォルトでは Shift_JIS (コードページ: 932) で保存されている事になります (日本語環境をお使いの場合)。
Delphi 2005 以降 (正確には Delphi 8 以降)、ソースファイルを UTF-8 で保存する事が可能です。
古い IDE とファイルを共有するのでもない限り、エンコーディングを Shift_JIS にする必然性はありません。
デフォルトのファイルエンコード
デフォルトのファイルエンコードを UTF-8 に変更するにはいくつか方法があります。
1. Delphi 10.4 Sydney 以降
[ツール | オプション...] でオプションダイアログを開き [ユーザーインターフェイス | エディタ] でデフォルトのファイルエンコードを指定する事ができます。
2. UTF8ize Plugin (Delphi 2010 ~ 10.3 Rio)
UTF8ize Plugin を導入すると、新規に作成したり開いたユニットのファイルエンコードが UTF-8 にセットされます。
- UTF8ize Plugin。(Swanman's Horizon)
- 自作プラグインの 10.3 Rio 対応状況。(Swanman's Horizon) - UTF8ize plugin Ver.0.0.5 があります。
先述の通り、10.4 Sydney 以降ではオプションダイアログでデフォルトのファイルエンコードを変更できますので、UTF8ize が必要になるのは Delphi 2010 ~ 10.3 Rio という事になるかと思います。
3. レジストリ
Delphi 8 以降のガリレオ IDE では、レジストリを変更する事によって、デフォルトのファイルエンコードを UTF-8 に変更できます。
Delphi | BDS バージョン | レジストリキー |
---|---|---|
Delphi 8, 2005, 2006, 2007 | 2.0, 3.0, 4.0, 5.0 | HKEY_CURRENT_USER\Software\Borland |
Delphi 2009, 2010 | 6.0, 7.0 | HKEY_CURRENT_USER\Software\CodeGear |
Delphi XE 以降 | 8.0 ~ | HKEY_CURRENT_USER\Software\Embarcadero |
いずれかの、BDS\xx.x\Editor
(xx.x は BDS バージョン) にある (なければ新規作成) DefaultFileFilter
(REG_SZ) の値を Borland.FileFilter.ANSI
から Borland.FileFilter.UTF8ToUTF8
に変更します。
例えば Delphi 2007 の場合、HKEY_CURRENT_USER\Software\Borland\BDS\5.0\Editor
に DefaultFileFilter
を新規作成してデータを Borland.FileFilter.UTF8ToUTF8
に設定します 1。
See also:
ANSI2UTF8
Delphi のソースコードのコードページを一括で UTF-8 に変換するツールを Delphi で書いてみます。
ソースコード
Delphi 10.3 Rio 以降でコンパイルできますが、インライン変数宣言を使わなければ Delphi XE とかでもコンパイルできると思います。
program ANSI2UTF8;
{$APPTYPE CONSOLE}
uses
System.SysUtils, System.Classes, System.IOUtils, System.StrUtils, System.WideStrUtils;
const
SearchOption: array [Boolean] of TSearchOption =
(TSearchOption.soTopDirectoryOnly, TSearchOption.soAllDirectories);
begin
var Dir := '';
var Enc: TEncoding := nil;
var ErrFlg := False;
var IsBackup := False;
var IsRecursive := False;
Writeln('ANSI to UTF-8 File Converter - Copyright (c) 2021 DEKO');
repeat
if ParamCount = 0 then
begin
ErrFlg := True;
Break;
end;
IsBackup := FindCmdLineSwitch('b', True);
IsRecursive := FindCmdLineSwitch('r', True);
var sCodePage := '';
var IsCodePage := FindCmdLineSwitch('c', sCodePage);
if IsCodePage then
begin
var CodePage := StrToIntDef(sCodePage, -1);
if CodePage = -1 then
begin
Writeln('Invalid Codepage.');
ErrFlg := True;
Break;
end
else
Enc := TEncoding.GetEncoding(CodePage);
end;
Dir := ExpandFileName(ParamStr(ParamCount));
if not TDirectory.Exists(Dir) then
begin
Writeln('Invalid Path.');
ErrFlg := True;
Break;
end;
until True;
if ErrFlg then
begin
Writeln(#$0D#$0A'Usage: ' + TPath.GetFileNameWithoutExtension(ParamStr(0)) + ' [-B] [-C CodePage] [-R] ProjectDir');
Writeln('');
Writeln(' -B'#$09#$09'Create Backup File');
Writeln(' -C CodePage'#$09'Set CodePage');
Writeln(' -R'#$09#$09'Recursive');
ExitCode := -1;
Exit;
end;
ExitCode := 1;
if Enc = nil then
Enc := TEncoding.GetEncoding(0);
var MS := TMemoryStream.Create;
var SL := TStringList.Create;
try
Writeln('');
for var FileName in TDirectory.GetFiles(Dir, '*.*', SearchOption[IsRecursive]) do
begin
var Ext := LowerCase(TPath.GetExtension(FileName));
if not MatchStr(Ext, ['.pas', '.inc', '.dpr', '.dpk']) then
Continue;
MS.LoadFromFile(FileName);
if not HasUTF8BOM(MS) then
begin
MS.Position := 0;
SL.LoadFromStream(MS, Enc);
SL.SaveToFile(FileName, TEncoding.UTF8);
if IsBackup then
begin
MS.Position := 0;
MS.SaveToFile(FileName + '.bak');
end;
Writeln(FileName);
end;
end;
finally
SL.Free;
MS.Free;
Enc.Free;
end;
ExitCode := 0;
end.
C++ Builder にも対応させたい場合には、MatchStr()
の所に、変換対象となるソースファイルの拡張子を追加してください。
if not MatchStr(Ext, ['.pas', '.inc', '.dpr', '.dpk',
'.c' , '.h' , '.cpp', '.hpp']) then
Continue;
何か漏れているような...?
使い方
ANSI2UTF8.EXE
にプロジェクトフォルダを指定して実行します。
ANSI to UTF-8 File Converter - Copyright (c) 2021 DEKO
Usage: ANSI2UTF8 [-B] [-C CodePage] [-R] ProjectDir
-B Create Backup File
-C CodePage Set CodePage
-R Recursive
フラグ | 意味 |
---|---|
-B | 変換前のファイルを .BAK として残します |
-C CodePage | 変換対象ファイルのコードページを指定します |
-R | サブフォルダ内のファイルも変換します |
普通の使い方は、
ANSI2UTF8 <ProjectDir>
です。
サブフォルダにもソースファイルがある場合には -R
を、海外の方が作られたプロジェクトファイルを日本語環境で変換する場合には -C 1252
等を指定してください 2。
See also:
おわりに
このツールは未公開だと思って Qiita に記事を書いたのですが、やっぱり公開してました。がっでむ。
折角なので、整理したソースコードを反映させておきました。