投稿記事

PowerShellの記事 (2)

いらにか 2023/07/19 22:49

【Mes】チャット風テキスト生成について【書き忘れ小話】

まえおき

Mesにはチャットスタイル形式のHTMLを出力する機能があります。
これは現在のシンプルエディタ(SMWE)でもお試し感覚で使えます。

https://smwe.iranika.info/

ボタンを押すと下記のようなテキストがクリップボードにコピーされます。

<span style="color: #8D9147">いら:</span>どうも、いらにかの半身の"いら"です。
<span style="color: #9E09CA">にか:</span>どうも、もう半分の"にか"です。ってこれは一体なんですか?
<span style="color: #8D9147">いら:</span>今回は対談風テキストをブログに書き起こすときに便利なツールを作ってみたので、それの話をしようかなと。
<span style="color: #9E09CA">にか:</span>なるほど。それで実際にこんなテキストを書いてるのですね。
<span style="color: #8D9147">いら:</span>対談風テキストを書くときって大抵"〈名前〉:〈セリフ〉だよね。
<span style="color: #9E09CA">にか:</span>コロン《:》の代わりに余白とかのケースもありますね。
<span style="color: #8D9147">いら:</span>で、大抵のブログってHTML直書き or WYSIWYGって呼ばれる仕組みを採用してるんだけど、
名前のところを色つけたりとかボールド表示したりとか、いちいちブログのエディタで操作するの面倒くさいんだよね。
<span style="color: #9E09CA">にか:</span>あー、以前”よくわかる道草屋”を作ったときにも苦しめられてましたね
※”よくわかる道草屋”は某サービスの評価試験目的で作られたサイト。スマホじゃないとレイアウトが崩れるのであまり紹介したくない黒歴史。
<span style="color: #8D9147">いら:</span>無駄に思える繰り返し作業が本当にストレスなんだよね。
パソコンに出来ることならパソコンにやらせるべきだし。
あと、シエル学園シリーズは対談系テキストも書く予定だから、いっそのことツール作っちゃおうってことで作りました。

これをCi-enにそのまま貼り付けるとこんな感じ。


いら:どうも、いらにかの半身の"いら"です。
にか:どうも、もう半分の"にか"です。ってこれは一体なんですか?
いら:今回は対談風テキストをブログに書き起こすときに便利なツールを作ってみたので、それの話をしようかなと。
にか:なるほど。それで実際にこんなテキストを書いてるのですね。
いら:対談風テキストを書くときって大抵"〈名前〉:〈セリフ〉だよね。
にか:コロン《:》の代わりに余白とかのケースもありますね。
いら:で、大抵のブログってHTML直書き or WYSIWYGって呼ばれる仕組みを採用してるんだけど、
名前のところを色つけたりとかボールド表示したりとか、いちいちブログのエディタで操作するの面倒くさいんだよね。
にか:あー、以前”よくわかる道草屋”を作ったときにも苦しめられてましたね
※”よくわかる道草屋”は某サービスの評価試験目的で作られたサイト。スマホじゃないとレイアウトが崩れるのであまり紹介したくない黒歴史。
いら:無駄に思える繰り返し作業が本当にストレスなんだよね。
パソコンに出来ることならパソコンにやらせるべきだし。
あと、シエル学園シリーズは対談系テキストも書く予定だから、いっそのことツール作っちゃおうってことで作りました。



この機能は「Mesが脚本特化なら、ブログ向けの対談風テキストとか生成できたら便利なのでは?」 という思いつきで作りました。

地味にキャラごとの色分けが自動化されてたり、個人的に頑張った機能なんですが、シンプルエディタだとサンプルがショボいテキスト生成なので、いまいち便利さが伝わらない感もあったりします。

本題

最近、Ci-enにやってきた川上稔氏がキャラアイコン付きの対談形式っぽい感じで記事を投稿していて、「やっぱり対談形式ならではの面白さってあるなぁ」 と改めて思いました。
※カクヨムで無料公開されている境界線上のホライゾン NEXT BOXもアイコン付きだったのを思い出しました
※参考記事 https://ci-en.dlsite.com/creator/17061/article/914079
※注釈:川上稔氏はR18で活動してるので他記事はえっちなやつが多いです。
 我は大人だぞ?という人はフォローしてヨシ!
 未成年は境界線上のホライゾンを今すぐ買えば、読み終わる頃には大人だと思います(ここ笑うとこ)



さてさて。
シンプルエディタのチャットスタイル形式ではアイコンではなく、色付きテキストの生成になっているので何が関係あるんだという感じですが、実はMesライブラリでチャットスタイル生成を担当しているToChatStyleHTMLメソッドは引数でテンプレート関数を渡せば、好きなテンプレートでテキスト生成ができる仕様になっています。


つまり、ライブラリの利用側が独自のテンプレート関数を作ってメソッドに渡せば自由に変更ができます。



「おい待て、C#で作られたライブラリのメソッド使うにはC#で書かなきゃいけないのでは?サクッと使いたい時に不便じゃねぇか!」

というツッコミをした人に朗報なんですが、11月以降の.NET8対応に向けてリファクタリング中のMesでは強化されたPowerShell用のモジュールも公開される予定です。前の記事でそのことに触れるのを忘れていました。
※ちなみにクラスライブラリは.NET言語ならC#以外でも使えます。あなたもPowerShellに目覚めるのです…(パワーシェル イズ パワー)


まぁ難しいことを多少抜いて話すと、↓こんな感じでPowerShellで独自に作ったテンプレート関数を渡して画像付きチャットスタイルが生成できるようになります。

コンパイラ要らずの動的言語(というかシェル言語)でも拡張しやすくてやったね!

ちなみに、上記は整理前の安定バージョンのライブラリを使っているので、少し冗長なメソッド呼び出しになっています。これはいずれ$mes.ToChatStyleHTML($fn)みたいな感じで簡単に呼び出せるようになります。
MesではC#とPowerShellでの利用を前提に開発を進めているので、ガッツリプログラミングにもサクッとスクリプティングにも耐えられるような設計で進めています。
(まぁ僕が便利なように作ってるだけなのですが)


ただ、この機能をWebエディタに組み込むとなると少し話が変わってきて、色々と難しい感じになるのでそこは今後の課題になっています。
(関数ではなくテンプレートテキストで渡すような仕組みになるので、テンプレートエンジンを組み込んだりetc...な感じで少し厄介なのです)


とまぁ、これを書き忘れていたので今回記事にしました。
まだみなさんが上記の機能を簡単に使える状況にはないですが、使えるようにする予定があるよというご報告でした。


前の記事にも書きましたが、Mesは11月まで開発を凍結してリファクタリングに集中しています。そこから.NET8への移植があるので、年内と年始くらいまではほぼ新たな動きは無いと思ってください。

ぶっちゃけ、ユーザーファーストに開発を考えるならWebエディタの機能拡張に注力して「リファクタしてる暇があったら機能拡張しつづけろ」というのがビジネス的には正解で最適解です。これが仕事ならエディタ開発に注力してる。
ただ、Mesは僕にとって砂場なので、現状はユーザーファーストで動いていません。
Mesは記述言語としてもまだまだ未熟なので、時間をかけて熟成させる必要があると思っています。
エディタに利用しているMAUIも発展途上中ですし、エディタの開発はいま急いでも良くない気がしています。覚えたことが無価値になったり、負の遺産になったりするのが継続的にGUIアプリ開発するときの怖いところです。MAUIの噂を聞いたとき、Xamarinで作り始めなくてほんと良かった……
(Xamarinは.NETに多大な貢献をした素晴らしい技術です)


では、また。


余談 : チャットスタイル形式のテキスト生成のコードの抜粋

ここからは少し高度(?)なプログラミングの話です。
わかる人向けに書くので日本語少なめ。

リファクタリング中のチャットスタイルテキスト生成のコードはインターフェースのデフォルト実装で拡張メソッドが参照されるようになっています。
要はミックスインみたいな感じで、インターフェースを継承するだけでデフォルト実装がクラスに実装される仕組みです。
開発中のMesでは、データ加工処理をクラスの外(外部ファイル)に切り出して、Mesクラスではインターフェースを継承するだけのミックスイン実装を採用しています。
拡張メソッドと違ってMesクラスに実装されるので、PowerShellや他言語からも呼び出しができるのがポイントです。
モックのテストをパスしたミックスイン(インターフェース)だけをMesクラスに継承させていくことで、機能追加が安全かつ安定してできるようになります。
データ加工処理を追加したい外部の開発者は、新しいファイルにミックスインを実装→プルリク送る→OKなら僕がMesクラスに継承させて機能追加→リリースみたいな流れになると思います。
編集するファイルが分離されているので不用意な変更が起こりにくくなり、安全性も高くなるのが個人的に嬉しいです。


下記は開発途中のコードですが参考にどうぞ(参考になるか分かりませんが)

//ChatStyleExtension.cs
using Mes.Core;
using System.Drawing;
using System.Text;
using System.Security.Cryptography;


namespace Mes.Core.Extension;

public interface IChatStyleExtention
{
    public IEnumerable<MesPiece> GetMesPieces();
    public IEnumerable<string> ToChatStyleHTML() => ChatStyleExtension.ToChatStyleHTML(this, ChatStyleExtension.DefaultTemplate);

    public IEnumerable<string> ToChatStyleHTML(Func<MesPiece, string> TextTemplate) => ChatStyleExtension.ToChatStyleHTML(this, TextTemplate);
}

internal static class ChatStyleExtension
{
    internal static IEnumerable<string> ToChatStyleHTML(this IChatStyleExtention mes)
    {
        return mes.ToChatStyleHTML(DefaultTemplate);
    }

    internal static IEnumerable<string> ToChatStyleHTML(this IChatStyleExtention mes, Func<MesPiece, string> TextTemplate)
    {
        foreach (var piece in mes.GetMesPieces())
        {
            yield return TextTemplate(piece);
        }
    }

    internal static string DefaultTemplate(MesPiece piece)
    {
        return $"<span style=\"color: #{CharactorNameToColorCode(piece.charactor)}\">{piece.charactor}:</span>{piece.dialogue}";
    }
    private static string CharactorNameToColorCode(string charactorName)
    {
        using (var sha1 = new SHA1Managed())
        {
            byte[] hashBytes = sha1.ComputeHash(Encoding.UTF8.GetBytes(charactorName));
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < 3; i++) // 3バイト分のハッシュ値を使用して6桁の16進数表記に変換する
            {
                sb.Append(hashBytes[i].ToString("X2"));
            }
            return sb.ToString();
        }
    }
}

この記事が良かったらチップを贈って支援しましょう!

チップを贈るにはユーザー登録が必要です。チップについてはこちら

いらにか 2022/04/25 12:31

【楽ちん】ブログで対談風テキストを楽に作るためのツール【PowerShell】

オープニングトーク

いら:どうも、いらにかの半身の「いら」です。

にか:どうも、もう半分の「にか」です。ってこれは一体なんですか?

いら:今回は対談風テキストをブログに書き起こすときに便利なツールを作ってみたので、それの話をしようかなと。

にか:なるほど。それで実際にこんなテキストを書いてるのですね。

いら:対談風テキストを書くときって大抵「<名前>:<セリフ>」だよね。

にか:コロン《:》の代わりに余白とかのケースもありますね。

いら:で、大抵のブログってHTML直書き or WYSIWYGって呼ばれる仕組みを採用してるんだけど、名前のところを色つけたりとかボールド表示したりとか、いちいちブログのエディタで操作するの面倒くさいんだよね。

にか:あー、以前「よくわかる道草屋」を作ったときにも苦しめられてましたね
※「よくわかる道草屋」は某サービスの評価試験目的で作られたサイト。スマホじゃないとレイアウトが崩れるのであまり紹介したくない黒歴史。

いら:無駄に思える繰り返し作業が本当にストレスなんだよね。パソコンに出来ることならパソコンにやらせるべきだし。あと、シエル学園シリーズは対談系テキストも書く予定だから、いっそのことツール作っちゃおうってことで作りました。

にか:「作りました」ってすでに過去形なのか(笑)


というわけで始まった今回のブログのネタは、対談風テキストの置換支援ツールのお話です。


ソースコード

基礎ロジックを先に考えるのがめんどくさかったので、先にPowerShellでプロトタイプを組みました。以下、プロトタイプのソースコードです。

Replace-Chacolor.ps1

function Replace-Chacolor {
    param(
        $FilePath,
        [PSCustomObject]$Templates,
        $JsonTemplateFile = ""
    )    
    #TODO: tempalte validationを追加する

    $text = (Get-Content $FilePath -Raw)
    $result = $text

    if ($JsonTemplateFile -ne ""){
        $Templates = Get-Content -Raw $JsonTemplateFile | ConvertFrom-Json
        Write-Debug $Templates[0].Text
    }

    
    $Templates | % {
        $tmp = $_
        $result = $result -replace $tmp.Text,$tmp.ReplaceText
    }

    $result

}

今のところ、ルール(テンプレート)に書かれているTextをReplaceTextに置換するだけの簡易実装です。
本当はルール自体に置換処理のスクリプトを書けるようにもできるんですが、過剰すぎるし、ルール記述が複雑になりそうなので機能を除外しました。

ちなみに、僕はモジュール化してもう少し便利に使っています。


使ってみた様子(デモ)


まずは、テキストを用意します。

text.txt

いら:そういえばテスト設計どう?

にか:うーん、コスト大きいですね。

いら:じゃあ設計後回しでホワイトボックステストにしちゃおう

にか:了解です。ちなみに、この機能ってどれくらいで作れそうです?

いら:うーん、ちょっと10分くらい待ってもらっていい?

~10分後~

いら:だいたい8分くらいかな

にか:わかりました。工数表に記入しときますね。

いら:ついでにDoneって記載しておいて

にか:えっ?

いら:もう作っちゃったから


見積もりよりも先にモノを作ってしまうのが、良くも悪くもいらの性分《タチ》だった・

そしたら、ルールファイル(テンプレート)を作ります。

template.json

[
    {
        "Text" : "いら:",
        "ReplaceText":"<span style=\"color: #ef5350\">いら:</span>"
    },
    {
        "Text":"にか:",
        "ReplaceText":"<span style=\"color: #42a5f5\">にか:</span>"
    }
]

ちなみに、上記はJSONで書いていますがスクリプトにはPSObjectでも渡せるので、好きなコンフィグ形式で設定してPowerShellでPSObjectに変換してから渡しても動きます。

つまり、Replace-Chacolor -FilePath .\text.txt -Template $(someScriptConfig.ps1)みたいにPSObjectのコンフィグを返すPowerShellスクリプトでルールファイルを書いておくことも出来ます。
※ルールファイルをスクリプトで書く黒魔術の便利さはPython使いならよく知ってるはず(多分


ちょっと話が逸れましたが、これをこんな感じで使います。


PS [NIKA-DESKTOP]> Replace-Chacolor -FilePath .\text.txt -JsonTemplateFile ..\template.json       

するとこんな感じに出力が得られます。

<span style="color: #ef5350"><span style="color: #42a5f5">いら:</span></span>そういえばテスト設計どう?

にか:うーん、コスト大きいですね。

<span style="color: #ef5350"><span style="color: #42a5f5">いら:</span></span>じゃあ設計後回しでホワイトボックステストにしちゃおう

にか:了解です。ちなみに、この機能ってどれくらいで作れそうです?

<span style="color: #ef5350"><span style="color: #42a5f5">いら:</span></span>うーん、ちょっと10分くらい待ってもらっていい?

~10分後~

<span style="color: #ef5350"><span style="color: #42a5f5">いら:</span></span>だいたい8分くらいかな

にか:わかりました。工数表に記入しときますね。

<span style="color: #ef5350"><span style="color: #42a5f5">いら:</span></span>ついでにDoneって記載しておいて

にか:えっ?

<span style="color: #ef5350"><span style="color: #42a5f5">いら:</span></span>もう作っちゃったから


見積もりよりも先にモノを作ってしまうのが、良くも悪くもいらの性分《タチ》だった・

あとはコピペするなり保存するなりすればOK。

デモでは名前をカラー表示しているだけですが、アイコンとかに置換するのも出来ます。
意図して作ったわけではないですが、特定の固有名詞を毎回強調表示したりするのにも使えます。

PowerShellなんて使いこなせないよ‼(キレ気味)

需要があればMimiCaにWebアプリとして組み込みます。
(ぼくはもう満足してるからぼくの需要とモチベはない)

WebアプリはUIデザインとか面倒な工数がかかるので、需要が無いと無駄感が強すぎて腰が上がらない……

余談

別にテキストエディタの置換機能で置き換えても大差ないですが、この置換ルールを設定ファイルに記述しておけるのが一番の魅力です。何度も繰り返し使うケースや置換ルールが膨大なケースって、手でそれらをやるのは死にたくなります(ストレスフル)。

置換ルールを読み込ませて、テキストを一括処理する。
置換の際にはルールのロジックを考えなくて良い気楽さがあります。
(ストレスの緩和)

あと、ブログシステムによってHTMLだったりマークダウン記法だったり独自記法だったりするので、「Ci-enならこのルール、はてなブログはこのルール」みたいに管理できるのも非常に便利です。

あとスクリプトになっていれば、「テキストを保存したら置換後のテキストを自動で出力ファイルに生成」みたいなことが簡単に組めるので楽です。


ちなみに、ツールを作りはじめてから記事書き終わるまで3時間30分くらいでした。
(予約投稿なので、別日に書いてます)

この記事が良かったらチップを贈って支援しましょう!

チップを贈るにはユーザー登録が必要です。チップについてはこちら

月別アーカイブ

記事を検索