# Markdown

## Hva det er

Markdown er et dokumentformat i ren tekst. Stjerner rundt et ord gir uthevet tekst, `#`
først på en linje gir en overskrift, `-` starter et listepunkt, og en lenke skrives som
klammer og parenteser: `[tekst](adresse)`. Navnet brukes både om selve syntaksen og om
det opprinnelige programmet som gjør teksten om til HTML. Filene får som regel endelsen
`.md` eller `.markdown`, og i dag skriver de fleste i én av to dialekter: CommonMark
eller GitHub Flavored Markdown, forkortet GFM.

John Gruber utviklet formatet i 2004 sammen med Aaron Swartz og skrev konverteren i
Perl. Den siste utgaven av den, 1.0.1, er datert 17. desember 2004. Designmålet var
lesbarhet: et Markdown-dokument skal kunne publiseres som det står, som ren tekst, uten
å se ut som om noen har strødd tagger og formateringskoder utover det. Gruber oppgir at
den største inspirasjonen var måten folk allerede formaterte e-post i ren tekst på.

Markdown erstatter ikke HTML. Der syntaksen ikke rekker, skriver du HTML rett inn i
teksten, uten noen egen markering rundt. Grubers begrunnelse er at Markdown er et format
å skrive i, mens HTML er et format å publisere i, så det ene kan bo inni det andre.

Slik ser en liten bit ut:

```markdown
The move took **one evening**, in three steps:

- stop the writes
- copy the data with `pg_dump`
- point the [application](https://example.com/app/) at the new host
```

Konverteren lager av dette et avsnitt med et `strong`-element, en liste med tre punkter,
et kodespenn og en lenke. Men teksten kan leses like godt før den er konvertert, og det
er hele idéen.

## Hvorfor det er viktig

Ren tekst lever lenger enn verktøyene rundt den. En Markdown-fil kan sammenlignes linje
for linje i versjonskontroll, gjennomgås i en pull request og åpnes i hvilken som helst
editor, og ingen leverandør kan legge ned formatet under deg. Dokumentasjon som ligger i
samme repo som koden, blir dermed endret i samme arbeidsflyt som koden og gjennomgått av
de samme folkene.

Prisen er tvetydighet. CommonMark-prosjektet skriver rett ut at Grubers beskrivelse av
syntaksen ikke er entydig, og at referanseskriptet hadde feil og sist ble oppdatert i
desember 2004. Hver ny implementasjon måtte derfor fylle hullene på egen hånd, og i 2014
fantes det dusinvis av dem. Spesifikasjonen viser et eksempel der ett og samme dokument
gjengis på én måte i en GitHub-wiki og på en annen i Pandocs DocBook-utdata. Markdown
kjenner ingen syntaksfeil, alt er gyldig input, så en forskjell viser seg først i
resultatet. Verktøyet Babelmark 3 sender samme tekst gjennom mer enn 20
implementasjoner, slik at du ser hvor de spriker.

Svaret på tvetydigheten kom i 2014, da CommonMark startet med en spesifikasjon skrevet
av John MacFarlane. Den knytter hver regel til eksempler på input og den HTML-en som
skal komme ut, og versjon 0.31.2, datert 28. januar 2024, har 652 slike eksempler.
Dermed kan en implementasjon testes, ikke bare beskrives.

GFM er et strengt supersett av CommonMark. GitHub legger til tabeller, oppgavelister
(task list items), gjennomstreking, utvidede autolenker og et filter som uskadeliggjør
en kort liste med rå HTML-tagger, og hver utvidelse er merket i spesifikasjonen. Hugo,
den statiske nettstedsgeneratoren, bruker Goldmark, som følger CommonMark og er
kompatibel med GFM.

Formatet har også sin egen medietype. RFC 7763 fra mars 2016 registrerer
`text/markdown`, med en obligatorisk `charset`-parameter og en valgfri `variant` som kan
si hvilken dialekt teksten er skrevet i.

## Slik ser det ut i praksis

De håndskrevne sidene på dette nettstedet er skrevet i Markdown og lagt ut med Go-maler,
og [kolofonen](/nb/credits/) nevner begge blant verktøyene sidene er laget med, ved
siden av Hugo. Den samme siden nevner markdownlint blant linterne som holder kildekoden
ærlig, i en kvalitetsport der hver eneste melding regnes som en feil.

[Siden om å være klar for AI-agenter](/nb/ai-ready/) snur formatet rundt. Hver side her
har en Markdown-tvilling på samme adresse: legg til `index.md`, eller be om
`text/markdown`. Bygget går gjennom hver tvilling på jakt etter rester av markup og
nekter å publisere når én av dem er feil. Tvillingen til den engelske utgaven av siden
er én forespørsel unna:

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

Den norske tvillingen ligger på samme sti med `/nb` foran.

I rollen som produkteier og prosjektutviklingsleder ble
[rundt 50 000 ord programvaredokumentasjon](/nb/portfolio/wrote-50-000-words-of-comprehensive-software-documentation-30/)
skrevet i Markdown, fordelt på GitHub, Craft og Confluence etter hvor hver del hørte
hjemme, og mye av det for hånd. Dokumentasjonen dekket arkitekturen, prosessene og det
praktiske veiledningsstoffet folk stadig spurte om. Den lå under versjonskontroll, var
lett å finne, og nye folk kom raskere i gang.

## Hvor det går galt

**Fet skrift kommer ut som stjerner.** Leseren ser to stjerner på hver side av et ord
som skulle vært fett, og alle kontroller er grønne, fordi HTML-en er gyldig og lenkene
virker. CommonMark åpner uthevet tekst bare på en venstreflankerende stjernerekke, og
står rekken foran et skilletegn, f.eks. klammen i en lenke, teller den bare når det står
mellomrom eller et annet skilletegn foran den. En bokstav foran gjør stjernene til
vanlige tegn, og det gjør også alt en malmotor setter inn før Markdown-teksten tolkes:
Hugo bytter ut en shortcode med en plassholder av bokstaver og sifre. Malen for
Markdown-tvillingene på dette nettstedet har en merknad om at mellomrommet mellom en
shortcode og den fete teksten ved siden av en gang ble fjernet, og at fet skrift da
sluttet å virke i 60 listepunkter fordelt på tre språk. Behold mellomrommet, og sjekk
den ferdige siden og ikke kilden. Kvalitetsporten her har en kontroll som leser den
bygde HTML-en etter Markdown som nådde leseren som tegnsetting.

**Den samme filen gjengis på to måter.** En nøstet liste blir flat i ett system og
nøstet i et annet, eller en `#` først på en linje blir en overskrift i én konverter og
blir stående som tekst i den neste. Ingenting melder fra, fordi Markdown ikke har
syntaksfeil å melde. Årsaken er en forskjell i dialekt: to konvertere som fyller et av
de opprinnelige hullene hver på sin måte. Bestem hvilken dialekt prosjektet skrives i,
som oftest CommonMark eller GFM, bruk en linter som holder filene til den, og kjør
tvilsom input gjennom mer enn én implementasjon før du stoler på den.

**Markdown-kopien av en side bærer med seg HTML.** Den som leser ren tekst-utgaven,
møter rå `svg`-elementer, eller et telefonnummer som begynner med en numerisk
tegnreferanse der plusstegnet skulle stått. En komponent som lager HTML til nettsiden,
lager den samme HTML-en i alle andre formater også, med mindre noen sier noe annet. Hugo
slår opp malen til en shortcode for hvert utdataformat og faller tilbake på HTML-malen.
Shortcode-malene på dette nettstedet har merknader om begge tilfellene: 49 rå
`svg`-elementer i Markdown-kopien av kolofonen, og telefonnummeret på kontaktsiden
escapet for HTML. En shortcode som skriver markup av noe slag, får nå sin egen mal for
Markdown-utdataene, og kvalitetsporten sjekker at tvillingene verken har rå HTML eller
HTML-entiteter, med kode unntatt.

**Rå HTML forsvinner fra siden.** En HTML-blokk skrevet inn i Markdown-teksten mangler
på den bygde siden, mens kilden ser riktig ut. Grubers syntaks lar HTML stå hvor som
helst i teksten, men en konverter står fritt til å avvise den. I Hugo er
Goldmark-innstillingen `unsafe` slått av som standard, så rå HTML blandet inn i Markdown
blir ikke gjengitt, og GFM escaper en kort liste med tagger som `script` og `iframe`,
slik at de skrives ut som tekst. Bruk det generatoren tilbyr i stedet, i Hugo en
shortcode eller en [render hook](https://gohugo.io/render-hooks/), eller slå
innstillingen på med vilje og godta det den slipper gjennom.

**Linteren slipper gjennom det den er bedt om å overse.** En Markdown-fil med ødelagt
struktur kommer gjennom gjennomgangen fordi markdownlint ikke rapporterer noe. Reglene
som ville fanget feilen, var slått av i konfigurasjonen, uten at noen hadde skrevet ned
hvorfor. Utviklingsreglene for dette nettstedet forteller at markdownlint en gang lå i
en JSON-fil med seks regler slått av og ingen kommentarer, og at to av de seks skjulte
ekte feil da de ble målt. Skriv begrunnelsen ved siden av hver regel som er slått av, i
et format som har plass til kommentarer, så den neste kan være uenig.

## Les mer

- [CommonMark Spec](https://spec.commonmark.org/) — spesifikasjonen regel for regel,
  hver knyttet til eksempler på input og HTML-en den skal gi.
- [CommonMark](https://commonmark.org/) — hvorfor en spesifikasjon trengtes, hvordan
  implementasjonene gled fra hverandre, og hvem som vedlikeholder den.
- [Markdown, by John Gruber](https://daringfireball.net/projects/markdown/) — den
  opprinnelige beskrivelsen, designmålet og Perl-skriptet.
- [Markdown: Syntax](https://daringfireball.net/projects/markdown/syntax) — Grubers egen
  gjennomgang av syntaksen, med regelen for HTML i teksten.
- [GitHub Flavored Markdown Spec](https://github.github.com/gfm/) — GitHubs dialekt som
  et supersett av CommonMark, med hver utvidelse merket.
- [RFC 7763: The text/markdown Media Type](https://www.rfc-editor.org/rfc/rfc7763) —
  medietypen, den obligatoriske `charset` og parameteren `variant`.

<https://engineer.company/nb/glossary/markdown/>
