Ho scritto Markdown ogni giorno lavorativo per anni - plugin README, changelogs, docs per Toolz.dev, note di rilascio per WP Adminify, metà dei miei messaggi di commit. E per la maggior parte del tempo ho trattato il passaggio del rendering come magico. Scrivi asterischi, GitHub mostra grassetto. bene. Vai avanti.
Quindi ho creato una sezione Documenti che ha eliminato Markdown dal database e l'ho reso in una pagina Next.js, e la magia si è trasformata in un elenco di decisioni molto specifiche che ho dovuto prendere. Una singola nuova riga diventa a <br>? (Github commenti dicono di sì. Le specifiche di Markdown dicono no.) operazione <div> nel rendering della fonte come div o come testo letterale? (Dipende chi sta chiedendo e se ti fidi dell'autore.) Quale classe va su un blocco di codice recintato in modo che l'evidenziatore lo raccolga? Perché un parser gira **bold**text in grassetto e un altro lo lascia in pace?
Niente di tutto ciò è esotico. È solo la roba che nessuno ti dice, perché Markdown sembra così semplice che la gente presume che non ci sia nulla sotto. c'è un bel po' di sotto. la Riduzione in HTML Converter su Toolz.dev espone quelle decisioni come interruttori piuttosto che nasconderli, che è la versione di questo strumento che volevo quando stavo debug perché le mie interruzioni di riga continuavano a scomparire.
tl; dr: Markdown è un formato di scrittura; HTML è il formato di visualizzazione Qualcosa deve compilare uno nell'altro Le regole che fanno inciampare le persone: le righe consecutive si uniscono in un paragrafo a meno che non si termini una riga con due spazi (o si attivi un'opzione & quot; breaks"), l'HTML grezzo viene passato o evaso a seconda delle impostazioni di fiducia di parser's e GitHub's dialect (GFM) aggiunge tabelle, elenchi di attività, strikethrough e collegamento automatico URL nudo sopra 02 linea di base. Il codice recintato viene compilato in
<pre><code class="language-js">, che è il prisma a gancio, highlight.js e shiki cercano. la Convertitore da markdown a HTML Fa tutto questo nel tuo browser, con ogni interruttore esposto.
Che cos'è Markdown e perché ha bisogno di essere convertito?
Markdown è una sintassi in testo semplice che John Gruber ha pubblicato nel 2004, con un obiettivo di progettazione dichiarato: un documento Markdown dovrebbe essere pubblicabile così com'è, leggibile come testo semplice, senza sembrare contrassegnato da tag. Ecco perché la sintassi prende in prestito dalle convenzioni che le persone già utilizzavano nella posta elettronica: asterischi attorno a una parola per enfatizzare, una riga di trattini sotto un'intestazione, un > per un preventivo.
La conseguenza è che Markdown non è un formato di rendering. Niente mostra il markdown. I browser visualizzano HTML e ogni luogo in cui hai visto Markdown renderizzato - GitHub, un sito statico, un portale di documenti, un'app di chat - ha eseguito prima un parser e ha messo HTML sullo schermo.
Quindi la conversione deve avvenire da qualche parte. Le tue opzioni sono all'incirca:
- Al momento della costruzione, in un generatore di siti statici o bundler. bene quando il contenuto vive nel tuo repository.
- Al momento della richiesta, su un server. Necessario quando il contenuto proviene da un database, costoso se lo fai su ogni richiesta senza memorizzare nella cache.
- nel browser, al momento ne hai bisogno. Che è quello che vuoi quando la risposta a "Ho solo bisogno dell'HTML per questa cosa" è una copia-incolla, non una pipeline di build.
Quel terzo caso è più comune di quanto sembri. Incollare le note di rilascio in un campo CMS che richiede solo HTML. Ottenere un readme in un modello di posta elettronica. Controllare come sarà un documento prima di impegnarlo. Convertire una bozza scritta in ossidiana in qualcosa che puoi consegnare a un designer. Nessuno di questi giustifica il cablaggio di un parser in un progetto.
Qual è la differenza tra CommonMark e Riduzione aromatizzata GitHub?
La specifica originale di Gruber era una pagina di prosa e uno script Perl, e ha lasciato abbastanza ambiguità che ogni implementazione non era d'accordo sui casi limite. 02 è la risposta a ciò: una specifica rigorosa e verificabile con una suite di conformità di centinaia di esempi, in modo che due parser conformi producano un output identico per lo stesso input Definisce la linea di base: intestazioni, paragrafi, enfasi, collegamenti, immagini, elenchi, citazioni di blocchi, blocchi di codice, interruzioni tematiche, escape di barra rovesciata, blocchi HTML.
Ritorno aromatizzato GitHub (GFM) è un superset formale di Commonmark, specificato da GitHub, che aggiunge le cose che le persone continuavano a chiedere:
| caratteristica | 02 | GFM | sintassi |
|---|---|---|---|
| tavoli | no | certo | | a | b | con un | --- | --- | riga delimitatore |
| Liste di attività | no | certo | - [x] done / - [ ] todo |
| barrato | no | certo | ~~gone~~ |
| URL nudi collegati automaticamente | no | certo | https://toolz.dev senza parentesi |
| note a piè di pagina | no | Sì (estensione GitHub) | [^1] |
| titoli, elenchi, codice, enfasi | certo | certo | identico |
Se il tuo markdown proveniva da un GitHub Readme, un GitLab Wiki, un'esportazione di nozioni o la maggior parte degli editor moderni, è GFM. Accendi GFM nel convertitore o le tue tabelle verranno visualizzate come tubi letterali, che è il numero uno "Il convertitore è rotto" Domanda di supporto Chiunque spedisce uno di questi strumenti riceve.
Perché la mia rottura di linea è scomparsa?
Poiché Markdown, seguendo le convenzioni dell'e-mail in testo normale, tratta le righe non vuote consecutive come un unico paragrafo. questo:
Line one
Line two
produce <p>Line one\nLine two</p>- un paragrafo, e la nuova riga crolla in uno spazio quando il browser lo esegue il rendering Non è un bug; è la specifica, ed esiste in modo da poter avvolgere con forza la tua prosa a 80 colonne in un editor di testo senza che l'avvolgimento trapeli nell'output.
Ci sono tre modi per ottenere una pausa reale:
- Una riga vuota avvia un nuovo paragrafo. Questo è ciò che desideri la maggior parte del tempo.
- Due spazi finali alla fine di una linea produrre una rottura dura -
<br />. Questo è il trucco standard ed è invisibile nel tuo editore, motivo per cui le persone lo trovano esasperante. - una barra rovesciata Alla fine della riga fa lo stesso in Commonmark ed è almeno visibile.
E poi c'è la quarta via, che è la fonte della confusione: Molte piattaforme attivano una modalità "pausa" Dove ogni singola nuova riga diventa a <br />. I commenti e i problemi di GitHub lo fanno. La maggior parte delle app di chat lo fa. File di lettura GitHub non fare. Quindi lo stesso testo viene visualizzato in modo diverso in un numero di GitHub e nel readme dello stesso repository, che è un pezzo di design davvero pessimo con cui ora siamo tutti bloccati.
Il convertitore lo espone come un interruttore. Se la tua fonte è stata scritta per un renderer in stile chat, attiva le interruzioni di riga. Se si tratta di un documento, lascialo spento e usa righe vuote come le specifiche intendono.
Come viene gestito il raw html?
Markdown consente HTML in linea - la specifica originale dice esplicitamente che qualsiasi HTML che scrivi passa direttamente. Questa è una funzionalità quando sei l'autore (vuoi il tuo <details> blocco, il tuo <img> Con un attributo larghezza, la tua ancora con a rel), ed è una responsabilità quando non lo sei.
Perché se esegui il rendering di markdown non attendibile con il pass-through HTML abilitato, hai una vulnerabilità XSS. <script>alert(document.cookie)</script> è un markdown valido. Così è <img src=x onerror="...">. Così è un <a href="javascript:...">. Una casella di commento, una biografia del profilo utente, un wiki pubblico - ovunque estranei scrivano Markdown che altre persone leggono - devono sfuggire all'HTML o disinfettare l'output con un vero disinfettante (DOMPurify è la risposta abituale, ed è un vero disinfettante proprio perché un regex non è sufficiente per un input ostile).
Questo convertitore è predefinito che scappa html grezzo: <div> nella tua fonte appare come il testo letterale <div> nell'output, esattamente come se avessi scritto <div>. Puoi attivare il pass-through quando la fonte è tua. E indipendentemente da quell'impostazione, l'anteprima dal vivo si spoglia <script>, <style>, in linea on* gestori di eventi e javascript: Gli URL prima del rendering: una difesa in profondità, quindi incollare qualcun altro's README nel riquadro di anteprima non può eseguire il loro codice. Si tratta di una misura di sicurezza in anteprima, non di un disinfettante per uso generale: se stai costruendo un prodotto che renderizza Markdown dell'utente, utilizza un disinfettante dedicato lato server e non fidarti di un regex, mio incluso.
Se hai bisogno di sfuggire a un personaggio a Markdown in modo che renderizzi letteralmente - un asterisco che dovrebbe rimanere un asterisco, un carattere di sottolineatura in un nome file - lo fa una barra rovesciata: \*not emphasis\*. E se stai litigando entità nell'altra direzione, il Entità HTML/Decoder è lo strumento per quel lavoro.
Quale HTML dovrebbe effettivamente emettere un buon convertitore?
HTML semantico, noioso e senza classi - con un'eccezione.
- le intestazioni diventano
<h1>–<h6>. Con gli ID di intestazione abilitati, ognuno ottiene anche un Slugifiedid, de-duplicato quando due intestazioni condividono un titolo (#setup,#setup-1). Questo è ciò che fa#anchorI collegamenti profondi funzionano ed è ciò che un generatore di sommario si blocca. - Un blocco recintato con una stringa di informazioni -
```js- diventa<pre><code class="language-js">. *questa è l'eccezione.* * il `lingua-` Classe è il prisma della convenzione, Highlight.js e Shiki cercano tutti, ed è per questo che il convertitore emette una classe. Il convertitore non colora il tuo codice; l'evidenziatore sulla tua pagina lo fa e ha bisogno di quel gancio. - Le liste diventano
<ul>/<ol>, e qui c'è una sottigliezza che vale la pena conoscere: a attillato LIST (nessuna riga vuota tra gli elementi) inserisce il testo direttamente all'interno<li>, mentre a slegato LIST (righe vuote tra gli elementi) racchiude il contenuto di ogni elemento<p>. Questo è il comportamento di Commonmark, non una stranezza, ed è per questo che la tua lista cresce improvvisamente distanziando la spaziatura verticale quando aggiungi una riga vuota tra due punti elenco. Il CSS non è rotto, l'HTML è veramente cambiato. - I tavoli diventano reali
<table>/<thead>/<tbody>markup, constyle="text-align:center"sulle celle quando la riga del delimitatore utilizza:---:. - Gli elenchi di attività diventano
<input type="checkbox" disabled>Dentro il<li>, che è esattamente ciò che GitHub emette.
Content-First, nessun div wrapper, nessuna classe di utilità. lo stili dall'esterno, con a .prose classe o le tue regole e il markup rimane portatile.
Come si usa il convertitore?
Passaggio 1: incolla il markdown
Fai un drop in un README, un changelog, note di rilascio, una bozza L'output si aggiorna mentre digiti - non c'è un pulsante di conversione, e non viene caricato nulla.
Passaggio 2: impostare gli interruttori
Aroma GitHub ON Se l'origine ha tabelle, elenchi di attività o barrato (probabilmente lo fa). ID di intestazione su se vuoi ancoraggi. Interruzioni di riga Attiva solo se la fonte è stata scritta per un renderer in stile chat. Consenti HTML grezzo acceso solo se la fonte è tua. Documento completo ON Se desideri una pagina HTML5 completa con DocType, CharSet, Viewport e a <title> Tratto dal tuo primo <h1>- utile quando si desidera aprire il risultato direttamente in un browser o rilasciarlo su un host statico.
Passaggio 3: controlla l'anteprima
Passa alla scheda di anteprima e conferma la struttura La riga delle statistiche ti dice parole, intestazioni, collegamenti, immagini, blocchi di codice e tempo di lettura - utile per controllare un post è la lunghezza che pensavi fosse prima di pubblicarlo Per un conteggio più approfondito, il Contatore di parole Fa la leggibilità e la densità delle parole chiave sullo stesso testo.
Passaggio 4: prendi l'output
Copia l'HTML, scaricalo come un .html file o copia l'indice generato: un elenco nidificato Markdown che si collega a ciascun ancoraggio dell'intestazione, pronto per essere incollato nella parte superiore del documento.
Se stai incollando il risultato in una pagina in cui i byte contano, eseguilo attraverso il Minifier HTML dopo. L'uscita del convertitore è rientrata per la leggibilità, non per il filo.
Casi d'uso comuni
Ottenere un readme su un sito web
Gli autori di plugin e pacchetti scrivono un buon readme, quindi hanno bisogno dello stesso contenuto su una pagina di destinazione. Il readme è GFM con tabelle e badge; la pagina di destinazione ha bisogno di HTML. Converti, incolla, stile con il tuo CSS esistente. Gli ID di intestazione ti danno un TOC della barra laterale gratuitamente.
Pubblicazione su un CMS che accetta solo HTML
Un sacco di campi CMS, piattaforme di posta elettronica e pannelli di amministrazione legacy prendono HTML e nient'altro Se si redige in Markdown - e la maggior parte delle persone che scrivono regolarmente lo fanno - questo è il ponte Converti con Documento completo Spento, così ottieni il frammento anziché un'intera pagina e incollalo nel campo.
Prototipazione di una pagina di documenti
Prima di eseguire il commit di contenuti in un sito Documenti, la conversione localmente ti mostra la gerarchia di intestazione effettiva e se le recinzioni del codice portano la lingua giusta. un' h3 quello avrebbe dovuto essere un h2 è ovvio nel TOC e invisibile nella fonte.
Verifica dei contenuti che qualcun altro ha scritto
Incolla un contributore's Markdown, guarda l'HTML emesso e puoi vedere immediatamente se hanno usato intestazioni reali o hanno dato in grassetto una riga per falsificarne una - un'abitudine che distrugge la struttura del documento e l'accessibilità Gli screen reader navigano per intestazione; **Big Text** non è un'intestazione, è un paragrafo in grassetto e il convertitore lo mostra in una riga di output.
Estrazione di un sommario
I documenti lunghi ne hanno bisogno e mantenerlo a mano garantisce che diventa stantio. Generalo dalle intestazioni, incollalo, rigenera ogni volta che le intestazioni cambiano.
Avanzato: cosa fa e non fa questo parser
È un parser scritto a mano, circa 400 righe, senza dipendenze - il che è deliberato, perché un parser Markdown che trascina una dipendenza di 200 KB in una pagina il cui punto è essere veloce è un cattivo commercio.
coperto: titoli ATX (# x) e intestazioni del settext (sottolineato con === / ---), paragrafi, enfasi e forti (*, _, **, __), codice in linea con corrispondenza backtick, codice recintato con stringhe informative, blocchi di codice rientrati, blocchi con prosecuzione pigra, liste annidate (ordinate e non ordinate, serrate e sciolte), interruzioni tematiche, collegamenti e immagini con titoli, collegamenti automatici di staffetta, collegamenti automatici, escape per barra e GFM set: tabelle con allineamento, elenchi di attività, barratura, autolink bare-url.
NON COPERTO: Collegamenti in stile di riferimento ([text][ref] con un [ref]: url definizione altrove), note a piè di pagina, elenchi di definizioni e alcuni casi d'angolo Commonmark davvero oscuri attorno a blocchi HTML che interrompono i paragrafi. Se stai utilizzando Commonmark Conformità Suite contro di essa, non otterrà un punteggio del 100%. Se stai convertendo un readme, un changelog o un post sul blog, non te ne accorgerai.
Questo è un commercio onesto, ed è il motivo per cui il convertitore si carica istantaneamente e funziona con la rete spenta. Per le pipeline di contenuto in cui è necessaria la conformità Commonmark bit esatta, utilizzare markdown-it, remark oppure cmark nella tua costruzione, ecco a cosa servono.
FAQ
Come faccio a convertire il markdown in HTML?
Incolla il tuo Markdown nell'editor e l'HTML appare immediatamente - non c'è un pulsante di conversione e nessun file da caricare Attiva GitHub Flavored Markdown se la tua fonte utilizza tabelle o elenchi di attività, quindi copia l'HTML o scaricalo come file 'html Tutto viene eseguito nel tuo browser, quindi le bozze non pubblicate e i documenti interni non lasciano mai il tuo dispositivo.
Cos'è il markdown al gusto di GitHub?
GitHub Flavored Markdown (GFM) è un superset formalmente specificato di CommonMark che aggiunge tabelle, caselle di controllo dell'elenco delle attività, barrato con doppie tilde e collegamento automatico di URL nudi. È il dialetto che GitHub utilizza per eseguire il rendering di file e problemi di Readme, ed è ciò che la maggior parte degli editor di Markdown emette oggi. È abilitato per impostazione predefinita in questo convertitore.
Perché la mia interruzione di riga singola è scomparsa?
Il markdown standard unisce le linee consecutive in un singolo paragrafo; un'interruzione di riga sopravvive solo se si termina la linea con due spazi, si utilizza una barra rovesciata finale o si lascia una riga vuota. Se vuoi che ogni nuova linea diventi a <br />, abilita l'opzione interruzioni di riga: questo è il comportamento utilizzato dai commenti GitHub e dalla maggior parte delle app di chat, ma non è ciò che fanno i file README.
Il convertitore evidenzia il mio codice?
Emette il markup di cui un evidenziatore ha bisogno ma non colora il codice stesso. un blocco di codice recintato contrassegnato con la lingua js diventa <pre><code class="language-js">, che è il prisma della convenzione di classe, Highlight.js e Shiki cercano tutti. Aggiungi una di quelle librerie alla pagina in cui incolla l'output e l'evidenziazione viene visualizzata automaticamente.
Il html grezzo all'interno del mio markdown è conservato?
Per impostazione predefinita è sfuggito, quindi <div> appare come testo letterale anziché come tag Attiva l'opzione consenti-raw-HTML per passare i tag direttamente, che è ciò che desideri quando il tuo Markdown si mescola deliberatamente in HTML - a <details> blocco o un'immagine con attributi. Abilitalo solo per la fonte di cui ti fidi, perché l'HTML grezzo di un autore non attendibile è un vettore XSS.
È sicuro incollare markdown che non ho scritto?
Sì. HTML è sfuggito per impostazione predefinita e l'anteprima live rimuove inoltre tag di script e stile, gestori di eventi in linea e javascript: URL prima del rendering Nulla di ciò che incolli viene trasmesso da nessuna parte Se stai costruendo un prodotto che renderizza Markdown da estranei, utilizza comunque un disinfettante dedicato come DOMPurify lato server: un filtro di anteprima non ne sostituisce uno.
Posso generare un sommario dalle mie intestazioni?
si. Con gli ID di intestazione abilitati, ogni intestazione ottiene un'ancora slugificata e deduplicata e lo strumento crea un sommario Markdown che si collega a ciascuno di essi. Copialo di nuovo nella parte superiore del documento e i link si risolvono rispetto agli ID generati. Rigeneralo ogni volta che le tue intestazioni cambiano piuttosto che mantenerlo a mano.
Questo convertitore implementa completamente Commonmark?
Implementa i costrutti che le persone effettivamente scrivono - intestazioni ATX e setext, paragrafi, enfasi, collegamenti, immagini, collegamenti automatici, citazioni in blocco, elenchi nidificati e sciolti, codice recintato e rientrato, interruzioni tematiche, escape di barra rovesciata - oltre alle estensioni GFM. I collegamenti in stile riferimento, le note a piè di pagina e alcuni rari casi limite del blocco HTML CommonMark non sono coperti Per la conformità bit-exact in una pipeline di compilazione, utilizzare markdown-it, remark o cmark.
Strumenti correlati: Riduzione in HTML · Entità HTML · Minifier HTML · Contatore di parole · generatore di lumache
Lettura correlata: Il toolkit dello sviluppatore web · Guida agli strumenti di testo



