【C#】横書き -> 縦書き変換
はじめに
某Twitterにてちょっと話題になった、テキストを縦書きで投稿するためのメモです。
今回はテキストを固定にしていますが、Unity、WPFなどで入力元、出力先を指定してやれば動的に生成したり、
Twitterなどにそのまま投稿することもできます。
縦に書く
TextViewなどの機能を使う場合は別ですが、
文字列を縦に並べるには単純に文字列を一文字ずつに区切って、それを縦に並ぶよう置き換えるのが良さそうです。
なお列の区切りは改行文字とします。
まずは一文字ずつに区切り、ついでに全角・半角文字が混ざると位置がずれてしまうので、半角文字の場合はスペースを追加することにします。
// 元のテキスト. const string sampleText = "Hello\nworld\nおはようございます!\n"; // 改行文字で区切る. var splittedSamples = sampleText.Split('\n'); // ToCharArray()で一文字ずつ切り出し -> charからstringに戻す -> 半角文字にスペース追加. var results = splittedSamples.ToList() .Select(samples => samples.ToCharArray() .Select(sample => sample.ToString()) .Select(sample => Regex.Replace(sample, @"[a-zA-Z0-9|\.\-\\\,]", " " + sample)) .ToList()).ToList();
これで一文字ずつ切り出して、一行ずつにまとめた List< List< string>> の値となります。
なお、長音の縦横置き換えなどは行っていないため、必要に応じて追加してください。
あとはこれを頭から並べていきます。
const string sampleText = "Hello\nworld\naaa\nbbb\n"; var splittedSamples = sampleText.Split('\n'); var results = splittedSamples.ToList() .Select(samples => samples.ToCharArray() .Select(sample => sample.ToString()) .Select(sample => Regex.Replace(sample, @"[a-zA-Z0-9|\.\-\\\,]", " " + sample)) .ToList()).ToList(); var resultMaxCount = results.Select(samples => samples.Count).Max(); var resultText = "\n"; for (var i = 0; i < resultMaxCount; i++) { for (var j = results.Count - 1; j >= 0; j--) { // 列の間に全角スペースをはさむ. resultText += " "; // その列に文字がなかった場合は全角スペースに置き換え. resultText += (results[j].Count - 1 >= i) ? results[j][i] : " "; } resultText += "\n"; }
せっかくなのでこちらも Linq で解決したいところでしたが、
良い方法が思いつかなかったのでfor文を使うことにしました。
また、Twitterに投稿する場合に、一行目の最初の文字より前に入っているスペースが取り除かれてしまうようです。
それを防ぐため、頭に改行を挟んでいます。