前回で作成したOpenAIチャットのデモはいろいろと改善点が盛りだくさんです。その1つは、OpenAIからのレスはテキストなのですがMarkdownの形式で来ます。今回はこの表示をHTMLに変換します。
OpenAIからのレス
OpenAIからのレスは以下のようなテキストできます。
2023年10月4日以降の日本の祝日は以下の通りです: - 体育の日(スポーツの日):10月9日 - 文化の日:11月3日 - 勤労感謝の日:11月23日 12月から年末までの祭日はありません。
MarkdownのWikiを参照すると、
上で使用されているハイフン(‐)は、順序無しリストのアイテム、HTMLでは<ul>の<li>の使用ということになります。
しかし、これを無視すると以下のような表示(前回)となります。
無視しないでHTMLに変換して、
のように表示したいです。
ソースコード
今回の機能を追加したソースコードは、前回のOpenAIチャットをもとにして違うgitブランチ(chat-openai-markdown)としました。
レポジトリはこちらですが、すでにデモのソースコードをインストールしているなら、以下でスイッチできます。
$ git fetch $ git checkout chat-openai-markdown
を実行してブランチをゲットできます。
前回のブランチのchat-openaiとの差分は以下です。
$ git diff chat-openai --name-status M package-lock.json M package.json M resources/js/components/ChatMessages.vue
MarkdownのテキストからHTMLの変換のために、今回はmarkdown-itのパッケージが必要です。それゆえに以下の実行が必要です。
$ npm install
最後に、前回と同様に以下のコマンドを実行すると、ブラウザでテストが可能です。
$ npm run build $ php artisan serve
markdown-itをChatMessages.vueに取り込む
差分で見たように、今回コードの変更はChatmessages.vueのみです。サーバー側ではなくフロントエンドでHTML変換です。
以下のコードで変更の部分にコメントしました。非常に簡単です。
<script setup>
import MarkdownIt from 'markdown-it'; // MarkdownからHTMLへの変換のパッケージ
const markdown = new MarkdownIt(); // 初期化
defineProps({
  messages: Array,
  user: Object
});
</script>
<template>
  <ul style="list-style:none">
    <li v-for="message in messages"
      :key="message.id"
      :class="message.user.id === user.id ? 'text-end' : 'text-start'">
      <div class="header">
        <strong>
          <span v-if="message.user.id === user.id">私</span>
          <span v-else>{{ message.user.name }}さん</span>
        </strong>
      </div>
      <p v-if="message.user.id === user.id">{{ message.message }}</p>
      <p v-else v-html="markdown.render(message.message)"></p> // ここでHTMLに変換
    </li>
  </ul>
</template>
// 以下は変換後のスタイル設定
<style>
ul {
  list-style-type: square;
}
pre, code {
  background-color:pink;
  padding: 4px;
}
</style>
以下は、コードのMarkdownをHTML変換した例です。
メルマガ購読の申し込みはこちらから。


