AI と会話しない日がなくなって久しいです。彼(彼女?)は時々間違えることもあるけれど、その間違いを見抜く力さえあれば、Google 先生とあわせて活用することで、調べものにかかる時間と手間を大いに軽減できて、すーぱー Goooooooooooooooooooooood!!← アボガドロ数的感情表現のつもり。
ただ、その会話内容をコピペして印刷しようとすると問題になるのが、チャットのコピーに含まれているマークダウン表記。気にしなければイイという考えも、もちろんあるかと思いますが、私は『どうしてもプレーンテキスト( 平文 )が欲しい!』派です。
そこで自分専用に作ったのがコレ。

(左右のテキストを見比べていただければおわかりになるかと思いますが)
そうです。マークダウン表記の混じったテキストを平文(プレーンテキスト)化するプログラムです。
時々、思った通りに動作しないこともありますが、そこは手動修正。これは自信を持って言えますが、何と言っても、この私が書いた(自分専用の)プログラムですから、まともに動くわけがありません! と、開き直るわけではないのですが、自分的には、十分、活用できています。下のリンク先からダウンロードできますので、バグあり・サポート一切なし・完全自己責任でよろしければお試しください。
【重要な情報提供】
私のようなド素人が書いた、バグ満載の、信頼性に乏しく、状況に応じて名前まで変わるような、ヘンなプログラムでなく、Markdown、HTML、LaTeX、Word、PDF など多様な形式に対応した Pandoc という文書フォーマットを相互に変換できる、きちんとした変換ツールが公開されていることを申し添えます(オープンソースの Pandoc は、もちろん無料で利用できます)。
以下、バグ満載ではないかと、書いた本人も心配しつつ、書いた本人が使ってみた範囲では、時々期待を裏切りながらも、それなりに使えてる気がする、My Original Application の使い方です。
(1)削除対象文字を指定


削除対象文字には、マークダウン表記に使用される記号の他、任意の文字を追加可能です。AI が好んで?用いる絵文字は(ユーザーが指定すれば)プログラム側で見つけて処理するようにしました(ただ、今後 Unicode が更新されて新しい絵文字等が追加され、プログラム側で処理しきれなくなる可能性があります。その場合でも、ここに文字を追加すればなんとかなるかな・・・ ならないかな やっぱり)。
正直に白状しますと、設計当初は削除対象文字に絵文字もいちいち指定しておりましたので、削除対象文字の入力用 VCL コントロールは、単一行テキスト入力専用の TEdit ではなく、複数行入力が可能な TRichEdit を使っています。
動作テストを重ねるうちに、削除対象文字としてこの TRichEdit に指定した絵文字の数が激増し、それでも(おかしいなー!)と思いつつ都度『新発見絵文字』を気持ち半分喜びながら毎日追加しておりましたが、日々増え行く絵文字列が2行目の折り返しを間近に控えた頃、ようやく『 AI が使用する絵文字の種類は限定されてるに違いない』という自身の強い思い込みが『完全な誤り』であることに気づき(かつ、TRichEdit は絵文字に完全対応ではないみたいな話を AI から聞いたこともあり)、個別にいちいち指定する方式から一括削除する方式に仕様を変更したという、微笑ましくもどこか悲しい、ごく私らしい個人的なエピソードもあります。
ちなみに、私が現在削除対象文字に指定しているのは「*-`$#|」だけです。(万一、プログラムをダウンロードして使用される場合、削除対象とする文字を指定する際に、文字と文字の間にスペースを入れたり、カンマ区切りにしたりすると、それも「削除対象文字」になりますので、くれぐれもご注意ください)
また、削除対象文字として入力した内容は、プログラムの終了時に、特に何も指示等しなくても自動的に C:\Users\(ユーザー名)\AppData\Roaming\MarkdownRemover フォルダ内にある settings.ini に保存され、次回起動時に、前回終了時の状態が自動的に復元されます。
(2)平文化したい AI との会話内容をコピーして、変換プログラムを起動し、
Ctrl + V → R → C
一言で言えば、上の通りですが、手順をきちんと説明すると・・・
まず、プログラムを起動して、実行したい処理をチェックします。

【重要】
✅マークダウン表記を平文にするをチェックした場合、削除対象文字に指定した文字でも状況により、削除対象から自動的に外して(=削除しないで)処理することがあります(例:処理対象のテキスト内に数式があり、その数式内でアスタリスク * などが使用されている場合、数式内のアスタリスク * は削除しないようにプログラミングしたつもりです・・・が、状況によってはうまく動作しないことがあり得ると思います)。
実行したい処理をチェックしたら、Ctrlキーを押し、そのまま、V → R → C の順にキーを押し(下げ)ます。
Ctrl + V で、画面左側の TMemo に貼り付け
Ctrl + R で、画面右側の TMemo にプレーンテキストに変換して表示
Ctrl + C で、プレーンテキストをクリップボードへ送信
ちなみに2回目以降は、
Ctrl + D → V → R → C
Ctrl キーは押し下げたまま、D → V → R → C の順にキーを押し下げます。
Ctrl + D で、画面左側の TMemo を初期化(表示内容を消去)
Ctrl + V で、画面左側の TMemo に貼り付け
Ctrl + R で、画面右側の TMemo にプレーンテキストに変換して表示
Ctrl + C で、プレーンテキストをクリップボードへ送信
で、他のアプリ(エディタ等)への貼り付けは、アプリを切り替えて Ctrl+V。
【重要】
前回貼り付け分にさらに新しいテキストを「追加」する場合は、Ctrl+D は行わないでください。左側の Memo をクリックしてアクティブにし、改行を2つ程度入れて、次のテキストを入力してください。
基本的な使い方はこれだけです。
あっ! これだけはお断りしておいた方がいいかな? と思うことが3つありました。
【注意】このプログラムには、テキストを保存する機能はありません。
【注意】意図した通りに動作しない可能性が多いにあります!!!
【注意】重要な情報(記号・符号)が部分的に消えてしまう可能性も0ではありません。
テキストを保存する機能がないのは、事故防止のためです(貼り付け元としたオリジナルテキストを操作しません)。このプログラムはあくまでもテキスト整形のための中継器のように使用することを前提に作成しました。また、改行や空白(全角・半角いずれも対応)の削除も可能ですので、用途に応じて必要な機能のみを利用することもできます。
「マークダウン表記を平文にする」をチェックした場合は、Form のキャプション(タイトル)が『MarkdownRemover』と表示されますが、チェックを外すと Form のキャプション(タイトル)が『CharSweeper』と変化するのは、用途に応じた必要な機能の提供という部分へのこだわりをタイトル的に表現したものです。名前が変わるプログラムなんて私は見たことがありませんが・・・
それでもよろしければ完全自己責任の下でお試しください。(ダウンロードとご使用にあたっては、免責事項及び使用条件への同意が必要です。免責事項及び使用条件の詳細は付属の License.txt をご覧ください)
以下は、余程の事がない限り・・・
お読みいただく価値のない文言の羅列です
・・・ ので、もしお時間を無駄になさってもよろしければ、このプログラムの私的仕様の詳細なるものをご確認ください。
【もくじ】
1.きっかけ
2.表示フォントの指定方法
3.チェックしても何も起きない? CheckBox
4.そのうちに消せない絵文字も出てくるカモ?です。
5.プログラム終了時に Beep 音?
6.お願いとお断り
本プログラムの私的仕様の詳細です!
1.きっかけ
AI とチャットした際、その会話内容は AI の方で勝手に保存してくれますが(ただ、過去のチャットの「特定部分」を探すのがエライ面倒なことも多々あり、やはり、自分にとって『走召!』重要な情報は別に保存しておきたいなー!みたいな気が・・・私はしますし)、会話の特定部分を資料的に印刷等して活用したい場合は、どうしてもプレーンテキストでないと困る場合が・・・自分的には・・・ほとんどですと言うか、はっきり言って全部です。
もちろん、Pandoc などの変換ツールを自由自在に使いこなせる方なら、何の問題もないと思いますが・・・。わたくしの能力では、Pandoc の Lua フィルターを使いこなし、中間AST(抽象構文木)を操作して、出力フォーマットをカスタマイズするのは至難の技というか・・・、妻の命でもかかっていれば話は別ですが、仕事で疲れて帰宅した夜にハイボールを呷りながらやりたい作業ではありません・・・。
それより何より、Pandoc はライセンスが GPLv2 or later ですので、法的な問題をきちんとクリアしないと Pandoc を利用したアプリケーションはもちろん公開できません。これが最大の理由で、Pandoc の利用を今回はあきらめることにしました。(個人的には試用してみました。デフォルト設定のまま動かしてみたのですが、コードブロックの変換部分で、インデントの処理に独自ルールが適用されるようで、変換結果のプログラミングコードをコピペする際にちょっと困るかもと思いましたが、その他は期待通りに動作しました)
自分的には、できるだけ制約の「ない」状態で、アプリケーションを公開したい・・・というのがほんとうの気持ちですので、ある制約の中に自分自身がが組み込まれてしまうことに、どうしても抵抗を感じてしまうのです。ただ、それは私個人の思いであって、GPLv2の目指すところはもちろん尊重しますし、その規約に賛同する方々の思いに水を差すようなこともしたくありません。
ですので、My プログラムのマークダウン表記の平文化処理のアルゴリズムは完全オリジナルで作成しました。これが(使って下さる方が万一いて下さったと仮定した場合)、私の想定外のシーンでは、期待に反する平文化処理を実行してしまう可能性を十分に秘めているアルゴリズムだと思う所以です。
ともあれ、このプログラムを書きたいと思った『きっかけ』は AI とのチャット記録の保存です。自分的な理想形でそれを実現したいと思ったとき、初めてマークダウン表記のプレーンテキスト化という目的が私の中に生まれました。
ほんとうに、「きっかけ」とは不思議なものです。ものごとの始まりには必ず何らかの「きっかけ」があって、すべての物語はその「きっかけ」から始まります。もし、AI との会話を「プレーンテキスト化して記録したい」と思わなければ、このプログラムは生まれませんでした。私はいつでも、その「きっかけ」を探し続けているのように思えてなりません。ドキドキ・わくわくするような、まだ世界のどこにもないプログラムが書きたくなる、私だけの『きっかけ』を・・・。*(^_^)*♪
話が横道にそれました。もとへ。
目的の実現にあたり、マークダウン表記に使用される記号を文章中から取り除くのはもちろんですが、そうした結果生まれた空白や改行の処理も問題となり・・・つまり、プログラム文ではない行については、行頭にスペースがあれば削除しますが、それがプログラム文である場合、コードブロック部分のインデントはそのまま残したい・・・と思ったり。
最初はあれやこれやと 無駄な抵抗 無駄に工夫(=無駄な苦労 )して、各種プログラムの予約語があればそこはイジらない・・・みたいな楽しい ♪ ことをしてたんですが、やがてコードブロック表記を利用すれば、この問題は「さらっとクリア」できることに気づきます。
さんざん3 くらい まわり道してから気づくのが、私の王道パターンですので、今回は さんざん2 のまわり道くらいで気づいたので、まぁよしとして・・・
次に、問題になったのは、「数式」や「普通文」の中に削除対象として指定した文字がある場合です。例えば、次のように削除対象文字を指定した場合ですが・・・
*-`$#|
処理の対象とする行に「数式があるか/ないか or 数式を含むか/含まないか」をプログラム的に見分けなければいけません。で、その判定結果が True (=数式がある)であればイジらない、False であればイジる(=削除対象文字を探して削除する)ことにしました。
で、数式の存在を確認する方法を調べて見ると、マークダウン表記では、$...$ (インラインで文中に数式を挿入)や $$...$$ (独立した行にブロック形式で数式を表示)するようなので、まずは文章中のドル記号( $ )で囲まれた部分を数式と見なし、そこに削除対象文字があっても無視するよう設定。
さらにドル記号( $ )の前後がバッククォート(`)で囲まれたインラインコード※形式になっていたり、数式をドル記号( $ )で囲まず、単にバッククォート(`)のみで囲まれていることも実際にあるようなので、バッククォート(`)もフラグとして利用することにしました。
※インラインコード:プログラムのコードやコマンド、記号などを文章中でそのまま表示させたい場合に用いる。表示上は、等幅フォント(monospace)でレンダリングされ、強調や整形の影響を受けなくなる。
さらにさらに、ドル記号やバッククォートで『囲まれていない数式』があった場合(それが実際にあるのかどうかは未確認ですが)困ったことになりますので、次のように任意の行内に数式が含まれるか、どうかを判定する関数を作成・・・
//行内に数式が含まれるか、どうかを判定
//関数名は ContainsMathLikePattern とした方がイイかな・・・とも。
function ContainsMathExpression(const S: string): Boolean;
const
//数式らしいパターンを探す
Pattern = '(\d+\s*[\+\-\*/\^=]\s*\d+)|([a-zA-Z]+\s*\([\d\w\s\+\-\*/\^=]*\))|([\+\-\*/\^=]{1,})';
begin
Result := TRegEx.IsMatch(S, Pattern);
end;
実際にテストしてみました!

結果ですが(あくまでも私がテストした範囲に限っての話ですが)なんとか期待通りに動作しているようです。
でも、本当に数式中の演算子が消えずにちゃんと残るか? 今でも心配です。万一、このプログラムをダウンロードしてお使いになる場合は、完全自己責任でお願いします。「数式中の演算子が絶対に消えません」という保証は一切できませんので、変換後の結果を必ず確認する必要があることにくれぐれもご留意いただけますよう、お願い申し上げます m(__)m
数式に限らず、このプログラムを用いて重要な文言を含むテキストを変換する場合は、変換後のテキストの内容をすみずみまで十分ご確認いただけますよう、伏してお願い申し上げます。
2.表示フォントの指定方法
好きなフォントを指定できます。個人的には「プログラムコードが読みやすい」Consolas がおすすめです!

フォント名、スタイル、サイズ等を指定できます。指定したら OK ボタンをクリックしてください。

上の条件で設定した、実際の画面です。

3.チェックしても何も起きない? CheckBox
この記事の冒頭で「私的仕様」と書きましたが、例えば、次の CheckBox チェック時の扱いがその一例です。「日付を挿入」にチェックを入れても、表示されている平文のどこにも日付は入りませんし、同様に「空行を詰める」をチェックしても、やはり表示されている平文化テキストの改行箇所は一切変更されません。

このような仕様にした理由は2つあります。
1つめは、処理前のテキストと処理後のテキストを見比べて比較する場合、「✅スクロールの同期」の CheckBox にチェックが入っていれば、Memo の上下・左右のスクロールが連動します。処理後のプレーンテキストの改行部分を削除すると、左右の Memo の内容の比較が(改行位置が異なりますので)大変面倒なことになります。
2つめは、プレーンテキスト化したテキストを他のエディター等に貼り付けた際に、(私的に不要と感じる)改行が自動的に削除されていて欲しいことと、これまた極めて私的な理由で、プレーンテキストの末尾に1行改行して(西暦年月日)を自動的に挿入(追加)したかったからです。
ちなみに私は愛用の階層化テキストエディター(←この言い方が好きなので、こう書きますが、世間一般には「アウトラインプロセッサー」と呼称するようです)にノード分類して、次のように、その時々で実際に役立った Delphi のコードを記録・保存し、必要に応じて参照しています。
~~~階層化テキストエディターのとあるノード~~~
実際に使用したコード(=最終的に使ったコード)
以下、参考資料——————————————————
Web 上の情報源や、AI との会話内容等
(西暦年月日)
その実際の画面が、こちら

この階層化テキストエディターに、プレーンテキストをコピペした後の処理が必要最小限になるよう、「日付を挿入」&「改行を詰める」処理をクリップボードへのデータ送信時に行いたかったわけです。
ちなみに「改行を詰める」を✅した場合ですが、1行改行はそのまま、2行連続して改行があった場合は1行のみの改行へ変換、3行以上連続して改行が続いた場合は2行連続した改行に変換する仕様としてあります(ユーザーによる設定の変更はできません)。
日付は最終行に次のように挿入されます。

私の、この玉石混合状態(玉が3割程度か?)のプログラミング Tips は、もう 20 年近く書き溜めていますので、気づけば膨大な量となりました。その時々で仕事上の課題を解決するためのプログラムを主に作成してきましたので、ある意味では、これまでの生き方の記録と言っても過言ではありません。最近は AI に訊けば些細なことから、超絶!難しいことまで、懇切丁寧な解答が得られるので参照する機会はずいぶんと減りましたが、日付を見ると( あぁ、あの頃はこんなことやってたんだ・・・ )みたいな記憶がよみがえって、うれしいと言うか、なつかしいと言うか、よく生きてきたなー!みたいな感じがして・・・。年月日という、わずか1行にも満たない記録ですが、遠い未来で見返した際にそれがあることによって生まれる、何とも言えない懐かしい感覚が好きなのです。
2017年頃からは、いろいろ事情があって Python に触れる(= Python でプログラムを書く)機会がずいぶんと多くなりましたので、Python 用のプログラミング Tips もあることはあるのですが、こちらはなぜか、単なる記録集で、Delphi のそれとは異なり、過去の記録を参照して今日に役立てることはほとんどありません。
どちらかと言えば、Python でプログラムを書く場合は、その時々の課題解決専用のものを書くことがほとんどだからでしょうか・・・
4.そのうちに消せない絵文字も出てくるカモ?です。
Unicode Consortium は毎年新しい絵文字を提案・承認しているそうで、2025年末には Emoji 17.0 に167種類が追加予定とのこと。さらに Apple の「Genmoji」など、生成AIによる絵文字生成も登場し、標準外の絵文字が個人レベルで作れる時代に突入しているようです。
プログラムでは、削除対象として検索する絵文字の範囲を次のように指定していますので、将来的には自動削除の対象にならない絵文字が出現する可能性があるように思います。気がつけばもちろんバージョンアップしますが、最悪の場合、削除対象文字列に『消えない絵文字をコピペ』すれば、確実に消せます。
//削除対象として検索する絵文字の範囲
if not (
(code >= $1F600) and (code <= $1F64F) or // 顔文字
(code >= $1F300) and (code <= $1F5FF) or // 天気・場所・物
(code >= $1F680) and (code <= $1F6FF) or // 乗り物・地図
(code >= $2600) and (code <= $26FF) or // 記号
(code >= $2700) and (code <= $27BF) or // その他記号
(code >= $FE00) and (code <= $FE0F) or // 表示スタイル
(code >= $1F900) and (code <= $1F9FF) or // 拡張絵文字
(code >= $1FA70) and (code <= $1FAFF) // Emoji 13以降
) then
2025年10月末現在での確認事項となりますが、「 絵文字を除去 」のチェックボックスをチェックすることで(特に個別に指定しなくても)上記アルゴリズムが適用される範囲内の絵文字は一括除去が可能です。

5.プログラム終了時に Beep 音?
原因の解明ができていないのですが、このプログラムの終了時に「ポーン」という Beep 音※が鳴ることがあります(私の PC では時々発生します)。
※ 正しくは「システム通知音」(System Notification Sound)と言うようです。
このプログラムでは、開始時に音量設定が0でなければ自動消音し、終了時に開始時の音量設定を復元しています。なぜ、そのようにしたかというと、周囲に人がいるような環境では Beep 音が鳴らない方がよいと思ったからです。「入力ミス」などがあった際にユーザーに対して注意喚起するような目的で使われるこの音ですが、一人で PC を使用していてもメッセージが表示された際などに鳴ると結構(私は)気になります。
ですので、プログラムを公開する前に、プログラム終了時になぜBeep 音が「鳴ることがある」のか、しっかり解明しようと思っていたのですが、それが出来ませんでした。
これには、実は深い事情がありまして、この問題(?)に気づきました当日の午前4時頃、プログラムを様々に操作してみて、いったい何をどうすると音が鳴るのか? それを確認しよう!と、思っていた矢先のことでありました。
クー クー 眠っていると思っていた、いっしょに暮らしている、すーぱー たのしい 女性 が、いきなり目覚めて騒ぎはじめ、『 わたしの Word の仕事文書の罫線枠を直せ 』と。仰りまして・・・
なんでも、「10分間も苦労したのに思い通りにならない」とのことで。
( それはアンタが、Word の正しい使い方を知らないだけ )で、と、心底、海より深く、思いつつも。
世界全人類の平和と、彼女の心の平安は『イコール』であると☆信じて疑わない☆私的には
元より断る理由など、露ほどもございませんので。
・・・と、言うか、断ったりしたら、それはもう、ほんとに たいへんな コト に・・・ 。
最愛の彼女に心からご満足いただけますよう、(表面的仕草としては)心を込めたふりを装いつつ、
『 うん、この罫線指定ねー。奥にあるから。ほんと、わかりにくいよねー 』
『 うん。まるで、わかんない 』
( ソレハ アンタ ガ ムチャ で 気が短い カラ☆ でしょ? )・・・ と、思いつつ
『 でもね、今は AI に丁寧に訊けば、すごくやさしく教えてくれるよー!!』って。
そう、言いながら、彼女の PC の Word 文書の罫線を ちゃちゃっと修正したのですが・・・
当の、彼女は・・・
『 うん、もちろん、そう、思ったんだけど。』
『 うちには、解説だけじゃなくってー。全部やってくれる AI がいる からー☆ 』って。
とー とー オレ、AI に なっちまった( もしかして、格上げ?)。
たしか、つい、この前までは・・・
『 クルマ、いつもキレイねーって、職場で言われるの。』
( それは、よかったねー! )
『 ドロんこになったクルマ キレイに洗ってくれる 洗ヒグマが うちに・・・』と、確か。
オレ、クマだったはずなんだけど・・・ ってか、オレ、AI じゃない んだけど、みたいな。
それで、心が、折れまして・・・
もぉ 朝だし、まぁ いいかー☆ みたいな。
しかし、いったい、どこをどう走ると『あんなに』クルマを汚せるのか?
それは未だに 謎 ですが・・・
彼女曰く『 駐車場に吹く風が犯人 』とのことで・・・
見ればクルマの後部ガラスは、細かな塵や埃で今日も真っ白に・・・
彼女のクルマが『 洗ってー☆ 』と、
私に語り掛けてくる気が・・・ してならない朝でございます。
このプログラム、もっと良くしたいのは山々ですが。
やっぱり、今、私にも出来る
いちばんよいことをしようと思いました!
彼女のクルマ、
洗ってきまーす☆
6.お願いとお断り
このサイトの内容を利用される場合は、自己責任でお願いします。記載した内容(プログラムを含む)を利用した結果、利用者および第三者に損害が発生したとしても、このサイトの管理者は一切責任を負えません。予め、ご了承ください。
Delphi のコードだけは、インデント等がきちんと維持されるか/どうか等検証する変換テストを(私に出来る範囲で)実行しましたが、その他のプログラミング言語については未検証のまま、プログラムを公開しておりますことを申し添えます。