私は生活のためにコンテンツを移行します, 10 年間WordPressサイトを実行している誰もが最終的に行うという意味で. 、私は古い投稿のバッチをページビルダーからMarkdownベースのドキュメントシステムに移動したとき, 私は何を発見しました " クリーンHTML" 本当に野生で意味します: <p> インライン スタイルのタグ、空 <span>sは単一の単語を包みます、 <div>s 段落の周りの深い3 つのレベル、そして単に閉じることはなかった時折のタグ それ Markdownフィールドに貼り付けると、文字通りの角括弧の壁が得られました コピーペースト レンダリング テキストにはリンク、見出し、リストがすべて失われていました。どちらのショートカットも機能せず、最終的には、それについて理解する前に、午後の記事を手作業でクリーニングすることになりました。
Getting sensible とは、HTML-to-Markdown を、コピーペーストではなく、明確なルールセットを持つ構造化変換というものとして扱うことを意味しました。 heading 要素は、a になります # 線。 bold なる **。 リンク なる [text](url).テーブルはパイプテーブルになる.それらのマッピングと,現実世界のマークアップを乗り切るのに十分な寛容なパーサーがあれば,変換は退屈で信頼性がある - それはまさにあなたが望むものである. [Toolz.dev] (/を構築し,ブラウザベースを置く. HTMLからMarkdownへのコンバーター ここではこれらのルールが適用されますが、このガイドはルール自体に関するものであるため、出力がどのようなものであるべきか、またその理由を理解できます。
tl;dr: HTMLをMarkdownに変換するには、ブロック要素をそれらのMarkdown相当物にマップします ()
<h2>→##、<ul><li>→-、<blockquote>→>、<pre><code>→ 柵で囲まれたブロック)、マップ インライン要素 ()<strong>→**、<em>→*、<a>→[text](href)、<img>→)、回しなさい<table>github フレーバー付き Markdown パイプ テーブルにデコードし、HTML エンティティを実際の文字にデコードしてドロップします<script>/<style>。閉じられていないタグに耐性のあるパーサーを使用し、コンテンツがアップロードされないようにブラウザで実行します。
なぜHTMLをMarkdownに変換するのでしょうか?
Markdownは、現代の開発者ウェブのポータブルフォーマットです。 READMEファイル、ドキュメントサイト、静的ブログ(Hugo、Jekyll、Astro、Next.jsコンテンツ)、ObsidianやBearなどのメモアプリ、GitHubの問題、そしてますますAIモデルにフィードするプロンプトとコンテキスト - それらのすべてがMarkdownを話します。 It' sプレーンテキスト、それはGitできれいに異なり、それはそれと一緒にプレゼンテーションマークアップの山をドラッグすることなく、あるシステムから別のシステムに移動されるのを生き残ります。
対照的に、HTML はあなたです 行き着く コンテンツがブラウザやWYSIWYGエディタを通過するたびに.Webページからセクションをコピー, CMSからエクスポート, APIから記事の本文を引き出す, またはリッチテキストフィールドからフォーマットされたテキストをつかむ, そして、あなたはHTMLを取得します - 通常は乱雑なHTML, あなたがするラッパー要素とインラインスタイルでいっぱい& #39; クリーンな文書で望まない. 変換は、 " プレゼンテーションマークアップに閉じ込められたコンテンツ" から " コンテンツへのブリッジです. " どこでもバージョン、編集、再公開できます
シナリオは気づいたら絶えず繰り返されます WordPress や Medium からブログを移行する 従来の HTML ヘルプ システムからドキュメントを引き出す スクラップされた記事を Markdown ノートに変換する メールマガジン & #39; s HTML を Markdown ドラフトに変換する Web ページ & #39; s コンテンツをトークンを無駄にする生の HTML ではなくクリーンなコンテキストとして LLM にフィードする <div> スープ.いずれの場合も、手動の代替手段 - 再入力、またはレンダリングされたテキストのコピーペーストと手作業による書式設定の再構築 - は遅く、損失も大きくなります。ルールベースのコンバーターもそうではありません。
HTMLはMarkdownにどのようにマップしますか?
マッピングは自然に、ブロックレベル構造とインライン書式の 2 つのレイヤーに分割されます。
ブロック要素 document' s スケルトンを定義し、それぞれに直接 Markdown 対応するものがあります:
<h1>– だよ<h6>なる#スルー######見出し行.<p>空白行で区切られた段落になります.<ul>/<li>なる-箇条書きのリスト;<ol>/<li>なる1.番号付きリストとネストされたリストは 2 つのスペースでインデントされます。<blockquote>各行の接頭辞には が付きます>。<hr>なる---。<pre><code>は三重バックティックを持つフェンスで囲まれたコードブロックになります。<table>github Flavored Markdown パイプテーブルになります。
インライン要素 それらのブロック内のテキストを飾る:
<strong>あんど<b>なる**bold**。<em>あんど<i>なる*italic*。<code>なる`inline code`。<a href="...">なる[link text](href)、 を維持しますtitle属性 時 存在.<img>なる。<del>あんど<s>なる~~strikethrough~~(github フレーバー付き Markdown 拡張機能)。<br>改行の手前で 2 つの後続スペースとなるハードラインブレイクになります。
HTMLの実ブロック上でそれらのルールを実行し 構造はそのまま残ります この入力を考えると:
<article>
<h1>Getting Started</h1>
<p>Convert <strong>HTML</strong> into clean <em>Markdown</em>.</p>
<ul>
<li>Paste from a CMS</li>
<li>Get portable output</li>
</ul>
<pre><code class="language-js">const md = convert(html)</code></pre>
</article>
あなたは得る:
# Getting Started
Convert **HTML** into clean *Markdown*.
- Paste from a CMS
- Get portable output
```js
const md = convert(html)
```
その出力内の2 つの詳細は、呼び出す価値があります。 まず、 <article> wrapper は、構造コンテナのようなものには何も貢献しませんでした <article>、 <section>、そして <div> 透明です; コンバータはそれらに再帰し、彼らの子供たちをブロックとしてレンダリングします 第二に、コードフェンスが拾いました js その言語として。 That' s because the <code> 運ばれた要素 class="language-js"、大会構文ハイライターが使用し、良いコンバータは、フェンスをラベルにするために、そのクラスを読み取る。 it& #39; sあなたのdocsサイトでハイライトするコードブロックとdoes& #39; tの1 つの違いを作る小さなこと。
コンバーターが現実世界の HTML を生き残る理由は何ですか?
上記のルールは簡単な部分です。 手巻きの正則コンバータが失敗する理由 - そして、I& #39; はカップルを書いて捨てました - それは、実際の HTML が仮定を絶えず破っているということです。 3つの問題が何度も出てきます。
閉じられていないタグ. ブラウザが寛容であることは有名です: <p>one<p>two a. のため、2 つの段落として表示されます <p> 別のブロック要素が開くと暗黙的に閉じます <li>a<li>b は同じ理由で二つのリスト項目です。 explicit 上の要素のみを閉じている素朴なパーサです </p> は、最初の段落の中に 2 番目の段落を入れ子にし、下流のすべてをマングルします。 robust コンバータは、HTML spec が定義するのと同じ implied-end-tag ルールを適用します: ブロックレベルの要素を開くと、開いた段落が閉じます; a を開く <li> 前のものを閉じます 私のコンバータはこれを行います、それが通常ずさんなCMS出力を貼り付けることが通常機能する理由です。
<script> あんど <style> ブロック. これらは、コンテンツではなくコードとCSSを含んでおり、その内容をそのままとらえる必要があります (a) < javascript の内部はタグではありません。そして完全にドロップします。それらを特別なケースに忘れてください。すると、JavaScript ソースが Markdown にブリードされます。
HTML エンティティ. Webコンテンツが散らばっています &、 ©、 —、 、およびのような数値参照 ’。 Markdown - プレーンテキストである - では、実際の文字が必要です: &、 ©、 —、そして実際のアポストロフィ。 named と numeric エンティティのデコードはオプションではありません; それをスキップして、クリーンな Markdown は view-source のように読みます。
これが私が find-and-replace で HTML を変換しようとするのをやめて、代わりに適切な寛容パーサーを構築した理由です。 HTML をツリーにトークン化します - コメントの処理、次のような要素を無効にします <br> あんど <img>、大文字のタグ名、および引用符で囲まれていない属性 - そして、マークダウンを放射するそのツリーを歩きます。特に、それは ' ブラウザに依存しません ' s DOM、つまり同じロジックがサーバー上でも実行されますが、実用的な見返りは簡単です。それは、実際の Web サイトを構成する乱雑なマークアップに投げることです。
コンバーターの使い方は?
オン Toolz.dev/tools/html-to-markdown、左側のペインにHTMLを貼り付け、入力すると右側にマークダウンが表示されます - there& #39; sアップロードなしと狩りのための変換ボタンなし サポートされているすべての構造を一括して表示したい場合は、サンプルをロードします。
いくつかのオプションは、共通の好みをカバーします。 (あなたの弾丸文字を選択します)-、 *、または +) プロジェクト& #39; s スタイルに一致する順序なしのリストの場合. keep GitHub Flavored Markdown on for tables and strikethrough, or off if your target only accepts CommonMark. Toggle "keep links" off when you want the prose but not the URLs - handy for turning a link-heavy article into clean reading text - and "keep images" off to strip images entirely.統計の行には、単語、見出し、リンク、画像、コードブロック、および推定読み取り時間が表示されます。これは、結果をどこかに貼り付ける前に、構造が発見されたことを迅速に正気度チェックします。
サイト上のすべてのものと同様に、変換は100% クライアント側です パーサーはブラウザで実行されているプレーンなJavaScriptであるため、貼り付けられたページ、内部ドキュメント、および未公開の下書きはどこにも送信されません That' s コンテンツ作業のための右のデフォルト - you should' t have to upload a draft to stranger' s server just to reformat it - and it means the tool keeps working offlowers-side processing matters in the データ プライバシー ツール ガイド。
HTML と Markdown: いつどれを使用するか
それらの間の変換は簡単です; あなたが望むものを知ることは本当の決断です。
| アスペクト | HTML を | マークダウン |
|---|---|---|
| 主な目的 | ブラウザでのレンダリング | テキストの書き込みと保存 |
| ソースとしての読みやすさ | 貧弱(タグが重い) | 優れた(プレーンテキストとして読む) |
| Git の差分 | うるさい | クリーン |
| システム間での移植性 | ロウ | 高い |
| 精密なレイアウト制御 | フル | デザインによる限定 |
| 住んでいる場所 | Web ページ、WYSIWYG 出力 | README、ドキュメント、メモ、静的サイト |
| 学習曲線 | 急 | 分 |
Markdownは、シンプルさのためにレイアウト制御を意図的に取引しているため、あなたが書いたコンテンツ、バージョン、動き回ったコンテンツには勝ち、ピクセルレベルのプレゼンテーションが必要な場合には負けとなります。 you' reキャプチャまたは移行時にHTMLをMarkdownに変換します 内容; & #39; を構築するときは HTML を保持します ページ。そして、逆の方向に進む必要がある場合 - CMS フィールドまたは電子メール テンプレートの HTML へのマークダウン - HTML への Markdown 変換 このツールの鏡像であり、同じ規則を共有しているため、共通の構造では 2 往復がきれいに行われます。
これがコンテンツ ワークフローに収まる場所
フォーマット変換は、まれに全体のジョブ; it& #39; s 1 つのステップです。 私はMarkdown I& #39; lに記事を変換した後、通常、aを介してテキストを実行します ワードカウンター ターゲットに対する長さをチェックするため、およびソースに他の宛先に対してエンコード バックが必要な HTML エンティティがある場合は、 HTML エンティティエンコーダ/デコーダ は逆を扱う。 I' m が変換前に手書きの HTML をクリーンアップするとき、 a HTML ミニファイア 最初にノイズを取り除きます。これらの小さなツールは、繰り返し可能なパイプラインにチェーン接続されます。これが、ブラウザベースのツールキットについて私が考える方法の背後にある全体的なアイデアです。私はその哲学を で説明しました Web 開発者ツールキット ガイド そしてより広い コーディング ツール ガイド。
よくある間違い HTML を Markdown に変換する
HTML を変換する代わりに、レンダリングされたテキストをコピーペーストします。 リンク、見出し、リストが失われます - すべての構造 実際のマークアップを変換します。
コード言語クラスを無視する. フェンスで囲まれたブロックが言語と don't ハイライトなしに出てきた場合、コンバーターは をドロップしました class="language-x" ヒント。 良い人はそれを読みます.
CommonMark と GFM が同じであると仮定します。 テーブルと取り消し線は、コア CommonMark ではなく、GitHub フレーバー Markdown 拡張機能です。宛先が厳密な CommonMark の場合、テーブルは勝ちます't レンダー - GFM オフで変換し、別の方法でテーブルを処理します。
コンテンツをアップロードするコンバーターを信頼します。 "free" の豊富なオンラインコンバーター サーバーにHTMLを投稿する 未公開または内部的なものについては、that' s a leak.クライアントサイドツールを使用します。
フェイク
HTML を Markdown に変換するにはどうすればよいですか?
HTMLをエディタに貼り付けると、すぐにMarkdownが表示されます - アップロードするファイルも、押す変換ボタンもありません 必要に応じて、弾丸スタイルまたはリンクの処理を調整してから、Markdownをコピーするか、.mdファイルとしてダウンロードします。
コンバーターはテーブルを処理しますか?
はい。 GitHub フレーバー付き Markdown を有効にすると、HTML が有効になります は Markdown パイプテーブルに変わります: 最初の行がヘッダーになり、ディバイダー行が挿入され、残りの行が本体になります。 cell 内のパイプ文字はエスケープされるため、テーブルが壊れることはありません。
リンクや画像はどうなるの?
アンカー なる [リンクテキスト](href) そしてイメージは になります 、存在するときタイトル属性を保持します。 "keep links" をオフにするとアンカーテキストは保持されるがURLはドロップされ、"keep images" をオフにすると画像は完全に削除されます - 散文だけが必要な場合に便利です。
コード ブロックとインライン コードは保持されますか?
はい。 A block becomes a fenced code block, and if the code element carries a class like "language-js" that language is added to the fence. Inline spans are wrapped in backticks, and the code text itself is never escaped or reformatted, so snippets stay exactly as written.
Will it work on messy HTML copied from a website?
That is what it is built for. The parser is tolerant of unclosed tags, uppercase element names, unquoted attributes and stray comments, and it strips
