うちには、自分の書いた古いテキストが大量にあるのだけど、これらのテキストには決まった規則性を持たせてある。要はタイトルとか作者名とかを機械変換する事を前提に書いてあるのね。
で、これらをその時代のニーズにあわせて変換してきた。たとえば*.texに変換してpLaTeX経由でPDF化したりね。
そんな中、ルビの取扱いがある。
これは歴史的経緯で「 [[本文][ルビ]] 」形式と「 [本文<ルビ>] 」形式の二つがあるのだけど、後者の処理はEmacsMuseで処理したHTMLに食わせる感じで使っている事が多い。
で、これを処理するのを C# で書いたものがあるんだけど……。
ちょっと表現が古めかしいので、今の自分の環境にあわせてみた。
まず、モジュール部。
namespace rubyon
{
struct filex
{
public string data;
public bool exp;
}
class Rubyon
{
static filex getNewFilex()
{
filex r = new filex();
r.data = "";
r.exp = false;
return (r);
}
/// <summary>
/// データ形式 [テキスト<ルビ>]をXHTML1.1仕様のルビに書き換える。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
static string rubyFilter(string str)
{
string str2 = Regex.Replace(str, @"\[([^\[<>\]]+)<([^\[<>\]]+)>\]", "<ruby><rb>$1</rb><rp>(</rp><rt>$2</rt><rp>)</rp></ruby>");
return str2;
}
/// <summary>
/// ファイルを行単位で読み込みつつ、ルビの処理を行う。
/// </summary>
/// <param name="fn">ファイル名</param>
/// <returns>処理したテキスト(string)</returns>
static filex fileRead(string fn)
{
filex rr = getNewFilex();
// ファイルからテキストを読み出し。
using (StreamReader r = new StreamReader(@fn))
{
string line;
while ((line = r.ReadLine()) != null)
{
if (Regex.IsMatch(line, @">]", RegexOptions.IgnoreCase) == true)
{
rr.exp = true;
rr.data = rr.data + rubyFilter(line) + "\n";
}
else
{
rr.data = rr.data + line + "\n";
}
}
}
return(rr);
}
static void fileWrite(string fn, string str)
{
// ファイルにテキストを書き出し。
using (StreamWriter w = new StreamWriter(@fn))
{
w.Write(str);
}
}
/// <summary>
/// 指定HTMLファイルを読み込み〔熟語〈ルビ〉〕形式をRubyタグに書き換える。
/// </summary>
/// <param name="fn">ファイル名</param>
/// <returns></returns>
public filex FilterTegRuby(string fn)
{
filex r = getNewFilex();
if (File.Exists(fn) == true)
{
r = fileRead(fn);
if (r.exp == true)
{ // 変更があったと思われる。
fileWrite(fn, r.data);
}
}
return (r);
}
}
}んで、本体。
namespace rubyon
{
class Program
{
/// <summary>
/// 今いるディレクトリをスキャンして、そこにあるHTMLファイルのルビを処理する。
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
Console.WriteLine("ディレクトリ情報です。");
DirectoryInfo dir = new DirectoryInfo(".");
Rubyon ron = new Rubyon();
foreach (FileInfo f in dir.GetFiles())
{
if (Regex.IsMatch(f.Name, ".html$", RegexOptions.IgnoreCase))
{
string name = f.Name;
string ext = f.Extension;
DateTime t = f.CreationTime;
filex r = ron.FilterTegRuby(f.Name);
if (r.exp == true)
{
Console.WriteLine("{0}を処理しました。({1}/{2})", name, ext, t.ToString("hh:mm:ss"));
}
}
}
}
}
}うむ。
ほとんど元のままだけど、処理の必要ないファイルまでわざわざ保存していた昔の処理を改善してみた。
いやー、あの頃はC#超初心者だったからなぁ ^^;
今も似たようなもんだが。