0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Markdown パーサをゼロから書いて GitHub / Qiita / Zenn の 3 テーマ切替を作った

0
Posted at

作ったもの

Markdown Livehttps://sen.ltd/portfolio/markdown-live/

スクリーンショット

  • Markdown パーサをゼロから実装(CommonMark サブセット)
  • 3 プレビューテーマ: GitHub / Qiita / Zenn
  • 分割ペイン、リサイズ可能
  • localStorage で自動保存
  • HTML ダウンロード / コピー
  • 文字数・単語数・行数カウント
  • ペイン間スクロール同期

vanilla JS、ゼロ依存、ビルド不要node --test で 61 ケース。

行ベースのブロックパーサ

ヘッダ・コードフェンス・リスト・引用はすべて行頭の文字で判定可能。行番号 i を各ハンドラが消費する形で進める。

インラインは順序付き regex 置換

// コードスパン最優先(中を保護)
result = result.replace(/`([^`]+)`/g, '<code>$1</code>');
// 画像 → リンク(! が失われないように)
result = result.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '<img alt="$1" src="$2">');
result = result.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>');
// ** を先、* を後
result = result.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>');
result = result.replace(/\*([^*]+)\*/g, '<em>$1</em>');

順序が命。完全な CommonMark は AST ベースで 1 万行級だが、99% の実用ケースはこれで足りる。

テーマ切替はインライン <style> 置換

3 テーマを CSS 文字列として持ち、<style id="theme-style">textContent を書き換えるだけ。外部 CSS の再ロードなし、ちらつきなし。

スクロール同期の無限ループ回避

両ペインの scroll イベントが互いに発火する無限ループを requestAnimationFrame + フラグで防ぐ。

シリーズ

100+ 公開ポートフォリオ シリーズの #55 です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?