MarkdownAIで遊ぼう【AI機能でプログラミング言語翻訳アプリを作ってみた】

# はじめに
みなさん、MarkdownAIというサービスを知っていますか？
Markdownを書くだけでWebサイトを作れたり、AIツールを作ることができるサービスです。
今回はMarkdownAIのAI機能でできることを紹介したいと思います。

# 導入
MarkdownAIのアカウントを作ってみましょう。
[こちらのページ](https://mdown.ai/)を開いてください。
Googleアカウントでログインすることができます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/c3e11ed8-4884-e988-b1c6-195ca3857c01.png)

# 使ってみる
ログインするとこのような画面が現れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/cb8a5285-19f8-9561-f6b9-ae886d1f0d80.png)

中央のエディタにこんな感じでMarkdownを書くと簡単に記事を作れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/94220d05-5cc2-50c8-0538-bdf786a35c8b.png)

Viewというところを押すと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/44fc36aa-2382-3cff-7639-7f1cc350b6f1.png)
きちんとMarkdownが反映されていることが分かります。

SaveするとURLというところをクリックできるようになり、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/ac094296-2ae6-fa9f-9467-61ce7a6bcd97.png)

https://mdown.ai/content/1cb17a9a-eb7c-4ad4-a697-4513caf28169

こんな風に簡単に公開することができます。

# AIを使ってみる
MarkdownAIという名にもある通り、AIを使えるところがこのサービスの魅力です。
それではAIを使ってみましょう。
左上にあるロボットのボタンを押します。

するとこのような画面が出るのでいろいろ入力して保存します。ここで自分だけのオリジナルなAIを作ることができます。今回はだじゃれを言わせるようにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/37d98f30-0674-5a8e-686d-7f5bca930cb6.png)


もとの画面に戻ってきて、``Insert -> Insert a sample script that uses Server AI. ``を選択すると、以下のようなテンプレートが生成されます。
このコードで、AIと対話するアプリを作ることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/fbe108ac-14e1-3e3d-96a6-c2f7f91e6e58.png)

Viewで見てみると、以下のように表示されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/ba483723-786e-4115-665f-bf7de97a06d6.png)

ここで「今日はどんな天気ですか。」と聞いてみると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/4e06da7d-da56-36ae-c23a-e14c80402f95.png)
まあ意味はよくわかりませんが、Promptの内容にあったAIモデルが生成されていそうな感じがしますね。


# 何か作ってみよう
せっかくなので何か使えそうなアプリをサクっと作ってみましょう。

今回は競技プログラミングで使えるプログラミング言語の翻訳アプリを作ってみたいと思います。
AtCoderの[このルール](https://info.atcoder.jp/entry/llm-rules-ja)を参考にして作ってみます。

::: note warn
このツールを使用したことによる不利益等については一切責任を負いません。特に、コンテスト中にこのツールを使う場合には各コンテストの規約等をよくご確認ください。
:::

まずは特にプロンプト等を指定せずにモデルを作ります。

次にInsertからテンプレートを作成します。
今回は、翻訳前の言語、翻訳先の言語、そして翻訳するプログラムを入力し、ボタンを押すと翻訳されたプログラムが表示されるようにしてみます。
基本的なシステムの部分を書いた後、デザインをChatGPTと一緒に作ったらこんなサイトが完成しました。

https://mdown.ai/content/a6dd113f-3f1e-41d0-8f15-1a163c7abcfb


<details><summary>コードはこちらになります</summary>

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Code Translator</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/codemirror.min.css">
  <style>
    body {
      font-family: Arial, sans-serif;
      background-color: #f4f4f9;
      margin: 0;
      padding: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      
    }

    .container {
      background: #fff;
      border-radius: 10px;
      box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
      padding: 20px;
      width: 100%;
      max-width: 1200px; /* Further increased max width */
      overflow-y: auto;
      max-height: 90vh;
    }

    .form-group {
      margin-bottom: 20px;
    }

    label {
      font-weight: bold;
      display: block;
      margin-bottom: 10px;
      font-size: 16px;
    }

    .CodeMirror {
      border: 1px solid #ccc;
      border-radius: 5px;
      height: 400px; /* Increased height */
    }

    input[type="text"] {
      width: 100%;
      padding: 15px;
      font-size: 16px;
      border: 1px solid #ccc;
      border-radius: 5px;
      box-sizing: border-box;
    }

    button {
      background-color: #007bff;
      color: #fff;
      border: none;
      padding: 15px 20px;
      font-size: 18px;
      border-radius: 5px;
      cursor: pointer;
    }

    button:disabled {
      background-color: #cccccc;
      cursor: not-allowed;
    }

    #translated-code {
      margin-top: 20px;
      padding: 15px;
      background-color: #f9f9f9;
      border: 1px solid #ccc;
      border-radius: 5px;
      white-space: pre-wrap;
      font-family: monospace;
      font-size: 16px;
      overflow-x: auto;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="form-group">
      <label for="input-code">Input your code</label>
      <textarea id="input-code" name="story" rows="10" placeholder="Input your code..."></textarea>
    </div>

    <div class="form-group">
      <label for="beforelang">Original Language</label>
      <input type="text" id="beforelang" value="Python">
    </div>

    <div class="form-group">
      <label for="afterlang">Target Language</label>
      <input type="text" id="afterlang" value="C++">
    </div>

    <button type="button" id="button-ok">Translate</button>

    <div id="translated-code" class="form-group"></div>
  </div>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/codemirror.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/mode/python/python.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/mode/clike/clike.min.js"></script>
  <script>
    const codeInput = document.getElementById('input-code');

    // Prevent creating multiple editors
    if (!codeInput.CodeMirrorInstance) {
      // Initialize CodeMirror editor
      const editor = CodeMirror.fromTextArea(codeInput, {
        lineNumbers: true,
        mode: "python", // Default language mode
        theme: "default"
      });

      codeInput.CodeMirrorInstance = editor;

      document.getElementById('beforelang').addEventListener('change', event => {
        const lang = event.target.value.toLowerCase();
        const mode = lang === 'python' ? 'python' : 'text/x-c++src';
        editor.setOption('mode', mode);
      });

      const button = document.getElementById('button-ok');
      button.addEventListener('click', async () => {
        button.disabled = true;

        const message = "The following code is what I wrote to solve a problem in an AtCoder contest. When using generative AI to translate programming languages during an ongoing AtCoder contest, there are the following restrictions: \"It is absolutely necessary to include the original code at the beginning of the submission as a comment or similar.\" \"Only translations that do not alter the algorithm are permitted. In particular, any changes that would affect the time complexity are strictly prohibited.\" For any parts that cannot be directly translated, please mark them as \"FAILED\" and leave them unconverted. Following these strict AtCoder rules, please translate the following code from " + document.getElementById('beforelang').value + " to " + document.getElementById('afterlang').value + ".\n------------------------------\n" + editor.getValue();
        const serverAi = new ServerAI();
        const answer = await serverAi.getAnswerText('nkX3FFoXH1SCBXPDiUeyiZ', '', message);

        document.getElementById('translated-code').innerText = answer;
        button.disabled = false;
      });
    }
  </script>
</body>
</html>

```
</details>

# さいごに
というわけで、無料でAIを使ったツールが簡単に作れてしまいました！とっても便利で楽しいのでぜひみなさんMarkdownAIを使いましょう！

ご質問・ご指摘等ございましたらコメントにおねがいします。