ローカルの下書き保存とダウンロードに対応した Markdown 執筆アプリを作る

RichTextEditor で構築された、実際に利用できる執筆アプリ RichMarkdown

ブラウザー上で視覚的に文章を編集し、Markdown の下書きをローカルに保存して、.md ファイルをダウンロードできるアプリを作成します。ドキュメントの下書き、README ファイル、個人用メモに使えるワークフローです。

実際に動作する完全な例は、RichMarkdownで確認できます。RichTextEditor を使用し、ローカルのノート、調査資料のクリップ、各種エクスポート機能を備えています。この製品は無料で利用できます。独自のアプリでエディターを使うためのライセンスは、別途検討する必要があります。

動作するエディターを用意する

エディターをダウンロードし、サイトから richtexteditor フォルダーを配信します。file: URL で直接開くのではなく、ローカルの Web サーバーでページを実行してください。インスタンスを作成する前に、コアとプラグインを読み込みます。フレームワークごとの設定は、クイックスタートで説明しています。

下書き保存とダウンロードの操作を追加する

以下の完全なページは、editor というエディター、id="download" のボタン、id="save-status" の状態表示を作成します。文書ごとに異なる固定キーを使ってください。

<link rel="stylesheet" href="/richtexteditor/rte_theme_default.css">
<script src="/richtexteditor/rte.js"></script>
<script src="/richtexteditor/plugins/all_plugins.js"></script>
<div id="editor"></div>
<button id="download" type="button">Download .md</button>
<p id="save-status" role="status"></p>
<script>
const editor = new RichTextEditor("#editor");
const status = document.getElementById("save-status");
const key = "my-markdown-draft";
let saved = "";
try { saved = localStorage.getItem(key) || ""; }
catch { status.textContent = "Browser storage is unavailable. Download a copy."; }
editor.fromMarkdown(saved || "# Untitled\n\nStart writing.");

function saveDraft() {
  try {
    localStorage.setItem(key, editor.toMarkdown());
    status.textContent = "Saved in this browser.";
  } catch {
    status.textContent = "Draft could not be saved. Download a copy.";
  }
}
let timer;
editor.attachEvent("change", function () {
  clearTimeout(timer);
  timer = setTimeout(saveDraft, 300);
});
window.addEventListener("pagehide", saveDraft);

document.getElementById("download").addEventListener("click", function () {
  const blob = new Blob([editor.toMarkdown()], {
    type: "text/markdown;charset=utf-8"
  });
  const url = URL.createObjectURL(blob);
  const link = document.createElement("a");
  link.href = url;
  link.download = "document.md";
  document.body.appendChild(link);
  link.click();
  link.remove();
  setTimeout(() => URL.revokeObjectURL(url), 1000);
});
</script>

Markdown で保持する内容を決める

保存形式を Markdown だけに決める前に、実際のドキュメントでテストしてください。見出し、リスト、リンク、引用、フェンス付きコードブロックは Markdown で表現できます。結合した表のセル、コメント、任意のフォント装飾は、通常の Markdown では正確に表現できません。これらの詳細が重要な場合は、HTML や構造化した JSON も保存してください。

コードブロックの言語ラベルは内容を示すもので、コードを実行、コンパイル、検証するものではありません。JavaScript、TypeScript、PHP、C# の例は、ドキュメント内のテキストとして保持してください。

ローカルの下書き保存は補助機能です

  • localStorage は、このブラウザーとオリジンに属します。バックアップ、暗号化ストレージ、デバイス間同期ではありません。
  • サイトデータを消去すると下書きも削除されます。ダウンロード操作を用意し、エディターの近くにこの点を説明してください。
  • 複数のドキュメントを扱う場合は、個別のキーとドキュメント一覧を使用します。件数が多い場合は IndexedDB が必要になることがあります。
  • チームで使う場合は、認証を伴うサーバーストレージを使用し、編集の競合を解決してください。ローカルのキーを共有するだけでは共同編集にはなりません。

顧客のドキュメントを扱う前に

サーバー側の読み取りと書き込みは、毎回認可を確認してください。送信された Markdown は信頼できない入力として扱います。サーバーで HTML に変換する場合は、その HTML の表示先に適した Markdown レンダラーと HTML サニタイズポリシーを使用してください。ブラウザーでのプレビューは、サーバー側の検証の代わりにはなりません。

画像ファイルは別に保持し、安定した URL を保存します。Markdown ファイルには、参照する画像が自動的に含まれるわけではありません。画像を含むリッチテキストの保存を参照してください。

ワークフローを確認する

  1. 見出しとリストを入力し、保存済みのメッセージが表示されるまで待ちます。
  2. 再読み込みして、下書きが復元されることを確認します。
  3. コードブロックを追加し、ファイルをダウンロードして Markdown リーダーで開きます。
  4. 言語ラベル、インデント、リンク、画像を確認します。
  5. ブラウザーストレージを無効にしても、ダウンロードが利用できることを確認します。

続いて、Word と Google Docs から Markdown への変換、インタラクティブな Markdown デモ、必須コンテンツの検証を参照してください。

次に読む