Spring til indhold

Markdown

almindelig tekst med få tegn der betyder formatering

Hvad det er

Markdown er en måde at skrive et dokument på som en almindelig tekstfil, hvor en håndfuld indtastede konventioner fortæller et konverteringsprogram, hvilken HTML det skal lave: stjerner om et ord for fremhævelse, en havelåge foran en overskrift, en bindestreg foran hvert punkt i en liste og firkantede parenteser efterfulgt af runde parenteser for et link. Navnet dækker både syntaksen og det program, den først kom som, filerne ender som regel på .md eller .markdown, og de dialekter, der er vokset ud af den, blandt dem CommonMark og GitHub Flavored Markdown (GFM), går alle under samme navn.

John Gruber udviklede den i 2004 i samarbejde med Aaron Swartz og skrev den første konverter i Perl; den sidste udgave, Markdown 1.0.1, er dateret 17. december 2004. Hans erklærede mål var læsbarhed frem for alt: et Markdown-dokument skulle kunne udgives, som det er, som ren tekst, uden at se ud, som om nogen havde mærket det op med tags eller formateringsinstruktioner. Den største enkelte inspiration til syntaksen var ifølge ham den måde, folk allerede formaterede e-mails i ren tekst på. Alt det, syntaksen ikke dækker, skrives som HTML midt i teksten, uden nogen kontakt eller afgrænsning, for i hans optik er Markdown et skriveformat og HTML udgivelsesformatet.

Et par linjer viser det meste:

Flytningen tog **én aften**, i tre trin:

- stop skrivningerne
- kopiér dataene med `pg_dump`
- peg [applikationen](https://example.com/app/) mod den nye vært

En konverter gør det til et afsnit med et strong-element, en liste med tre punkter, et kodeudsnit og et link, og kilden kan stadig læses som en note, nogen har tastet.

Hvorfor det betyder noget

Kilden er dokumentet, og ren tekst overlever alle værktøjerne omkring den. En Markdown-fil kan åbnes i enhver editor, sammenlignes linje for linje i versionsstyring og gennemgås uden besvær i en pull request. Ingen leverandør kan nedlægge formatet, og at flytte en mængde tekst fra ét system til et andet er et spørgsmål om at kopiere filer.

Prisen er tvetydighed. CommonMark-projektet siger det ligeud: Grubers beskrivelse fastlægger ikke syntaksen entydigt, og hans script havde fejl og blev sidst opdateret i december 2004, så i 2014 fandtes der dusinvis af implementeringer, der hver udfyldte hullerne på sin egen måde. Projektets eksempel er et dokument, der vises på én måde i en GitHub-wiki og på en anden, når Pandoc konverterer det til DocBook. Og fordi intet i Markdown regnes for en syntaksfejl, viser en afvigelse sig først, når nogen kigger på resultatet. Projektet henviser til Babelmark 3, som kører samme input gennem mere end tyve implementeringer for at se, om de er enige.

CommonMark, som blev sat i gang i 2014, svarer med en specifikation skrevet af John MacFarlane, der binder hver regel til eksempler på input og den præcise HTML, de skal give: 652 af dem i version 0.31.2, dateret 28. januar 2024. GitHub definerer sin egen dialekt, GFM, som et strengt supersæt af CommonMark og lægger tabeller, opgavelister, gennemstregning, udvidede autolinks og et filter, der uskadeliggør en kort liste af rå HTML-tags, oveni. Hugos Markdown-konverter, Goldmark, overholder CommonMark-specifikationen og er kompatibel med GFM.

Markdown har også et navn på nettet. Siden marts 2016 har RFC 7763 registreret text/markdown for hele familien af syntakser, med en krævet charset-parameter og en valgfri variant-parameter, der siger, hvilken dialekt en fil er skrevet i.

Sådan ser det ud i praksis

Dette sites håndskrevne sider er Markdown, sat op af Go-skabeloner. Kolofonen nævner begge blandt de værktøjer, siderne bliver til med, ved siden af Hugo, den statiske sitegenerator. Samme side nævner markdownlint blandt de lintere, der holder kilden ærlig, i en kvalitetsport, hvor enhver meddelelse fra et værktøj tæller som en fejl.

Siden om at være klar til AI-agenter vender formatet om: hver side her har en Markdown-tvilling på samme adresse, som man når ved at tilføje index.md eller ved at bede om text/markdown, og kvalitetsporten gennemgår hver tvilling for efterladt markup og stopper udgivelsen, hvis en af dem ikke holder. Tvillingen til netop den side er én forespørgsel væk:

curl -sL https://engineer.company/da/ai-ready/index.md

Omkring 50.000 ord softwaredokumentation blev skrevet i Markdown i GitHub, Craft og Confluence, en stor del af den i hånden. Den rummede arkitekturen, processerne og de praktiske vejledninger, folk ellers spurgte om igen og igen; den lå under versionsstyring og var nem at finde, og nye folk kom hurtigere i gang.

Hvor det går galt

Fed skrift vises som stjerner. En læser ser to stjerner på hver side af et ord, der skulle have været fed, og alle tjek forbliver grønne, fordi HTML’en er gyldig, og linkene stadig virker. CommonMark åbner kun fremhævelse på en venstreflankerende række af stjerner, og en række, der efterfølges af tegnsætning, som den firkantede parentes i et link, tæller kun, når der står mellemrum eller tegnsætning foran den. Et bogstav foran holder stjernerne bogstavelige, og det samme gør alt, hvad en skabelonmotor sætter der, før Markdown bliver parset: Hugo erstatter en shortcode med en pladsholder af bogstaver og cifre. Dette sites skabelon til Markdown-tvillingerne noterer, at da mellemrummet mellem en shortcode og den fede tekst ved siden af blev fjernet, gik den fede skrift i stykker på 60 punkter på tværs af tre sprog. Behold mellemrummet, og tjek den viste side frem for kilden; dette sites kvalitetsport har et tjek, der læser den byggede HTML for Markdown, som nåede frem til en læser som tegnsætning.

Den samme fil vises på to måder. En indlejret liste bliver flad i ét system og forbliver indlejret i et andet, eller en havelåge først på en linje giver en overskrift i én konverter og forbliver tekst i den næste, og intet melder det, fordi Markdown ikke har syntaksfejl at melde. Årsagen er en forskel i dialekt: to konvertere, der udfylder et af de oprindelige huller på hver sin måde. Navngiv den dialekt, et projekt skrives i, i de fleste tilfælde CommonMark eller GFM, brug en linter, der holder filerne til den, og kør tvivlsomt input gennem mere end én implementering, før du stoler på det.

Markdown-udgaven af en side indeholder HTML. En læser af tekstudgaven møder rå svg-elementer eller et telefonnummer, der begynder med en numerisk tegnreference, hvor plustegnet skulle have stået. En komponent, der skriver HTML til websiden, skriver den samme HTML ind i alle andre formater, medmindre den får besked på andet; Hugo slår en shortcodes skabelon op pr. outputformat og falder tilbage på HTML-skabelonen. Dette sites shortcode-skabeloner noterer begge tilfælde, 49 rå svg-elementer i Markdown-udgaven af kolofonen og kontaktsidens nummer escapet til HTML, og en shortcode, der skriver nogen form for markup, har nu sin egen skabelon til Markdown-outputtet. Kvalitetsporten tjekker også, at Markdown-tvillingerne er fri for rå HTML og HTML-entiteter, og springer kode over.

Rå HTML forsvinder fra siden. En blok HTML, der er skrevet ind i Markdown, mangler på den byggede side, og kilden ser fin ud. Grubers syntaks lader HTML stå hvor som helst i teksten, men en konverter må gerne afvise den: Hugos unsafe-indstilling for Goldmark er slået fra som standard, så rå HTML blandet ind i Markdown bliver ikke gengivet, og GFM escaper en kort liste af tags som script og iframe, så de vises som tekst. Brug i stedet det, generatoren tilbyder, i Hugo en shortcode eller en render hook, eller slå indstillingen til med vilje og accepter det, den lukker igennem.

Linteren godkender det, den blev bedt om at overse. En Markdown-fil med en defekt struktur slipper igennem gennemgangen, fordi markdownlint ikke melder noget. De regler, der ville have fanget det, var slået fra i konfigurationen, uden at nogen havde skrevet en begrundelse. Dette sites udviklingsregler noterer, at markdownlint engang lå i en JSON-fil med seks regler slået fra og ingen kommentarer, og at to af de seks skjulte rigtige fejl, da de blev målt. Skriv begrundelsen ved hver regel, der er slået fra, i et format, der kan rumme en kommentar, så den næste kan være uenig i den.

Læs mere

Ordliste