https://zenn.dev/foxtail88/articles/1bbb3108db0b21
先日、こちらの記事を拝見して「おもしろい!」と感じました。
Twitterなんかで「𝙈𝙮 𝙣𝙚𝙬 𝙜𝙚𝙖𝙧...」という文字を見かけるたびに、これみんなどうやってタイプしてるんだろう?と気になっていたので、なるほど、こうしたツールやWebサイトを利用するのね、と得心しました。
上記記事ではCLIをリリースして下さっています。もっと幅広く使えるツールも作ってみたいな、ということで目をつけたのがGoのtransform.Transformer
の実装です。以下ではその詳細を述べていきます。
Goの持ち味の1つが、io.Reader
/io.Writer
による入出力の抽象化&ストリーム化です。それらのインタフェースを活用することで、幅広い入出力に効率良く処理をかませることができます。
その活用例の一つとして、ShiftJISでエンコーディングされたファイルの読み込みなどがあります。下記の記事でも解説されていますが、GoはUTF-8で文字列を扱うため、ShiftJISでエンコーディングされたコードを読み込むには、transform.NewReader(io.Reader, japanese.ShiftJIS.NewDecoder())
によってio.Reader
を作成し、これを所望のストリーム処理に繋げます。
transform.NewReader
の第2引数はtransform.Transformer
インタフェースであり、次のメソッドを持つ構造体であればオリジナルの変換処理を実装することができます。
type Transformer interface {
Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error)
Reset()
}
Transform
関数が肝で、src
から読み取ったバイト列に所望の変換を行い、dst
に書き込みます。入力のsrc
が何度かに分けられる場合を想定しマルチバイト文字の際は文字途中での分割に対する配慮が必要ですし、書き込みたいバイト列に対しdst
の長さが不足する際は余剰分を留保しておく必要があるなど、なかなか実装が面倒な子ではあります。しかしこれを実装することで様々な入出力の間に文字列の変換を入れることができるのは、大きな魅力ではないでしょうか。
ということで、Unicodeで表現できる範囲内で書体を変えるようなtransform.Transformer
の実装を作ってみます。
作成したパッケージは下記です。
a-z
, A-Z
, 0-9
の文字を所望の書体に変換します。これらの文字は1バイト文字なので、その分だけtransform.Transformer
の実装は簡単でした。
現状は次の書体に対応しています。