> For the complete documentation index, see [llms.txt](https://overleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://overleaf-pro.ayaka.space/latex/da/dybtgaende-artikler/14-how-do-tex-engines-typeset-tables.md).

# Hvordan TeX-motorer sætter tabeller

## Hvordan sætter TeX-motorer tabeller

## Introduktion: Hvad dækker denne serie?

At fremstille æstetisk tiltalende tabeller kan være en tidskrævende opgave — uanset om du bruger et visuelt layoutværktøj, LaTeX eller et markeringssprog som HTML eller Markdown. For LaTeX-brugere i særdeleshed ligger opsætning af tabeller højt på mange menneskers liste over “smertepunkter”, hvilket måske ses af, at “tabeller” er et af de mest [højt taggede emner på tex.stackexchange](https://tex.stackexchange.com/tags).

Ud over svarene og eksemplerne på tex.stackexchange afslører selv et overfladisk kig på den hjælp, der er tilgængelig til opsætning af tabeller med LaTeX, en række tabelrelaterede informationsressourcer:

* Overleafs [hjælpesider](https://www.overleaf.com/learn/latex/tables) og andre sites såsom [learnlatex.org](https://www.learnlatex.org/en/lesson-08)
* CTAN, Comprehensive TeX Network, oplister over [70 TeX-/LaTeX-pakker](https://ctan.org/topic/table) relateret til at oprette tabeller
* et helt [bog om opsætning af tabeller med LaTeX](https://www.amazon.co.uk/Typesetting-Tables-LaTeX-Herbert-Voss/dp/1906860254)
* en fremragende [online LaTeX-tabelgenerator](https://www.tablesgenerator.com/latex_tables)

En simpel Google-søgning efter [LaTeX-tabeller](https://www.google.com/search?q=latex+tables) giver et enormt antal resultater og lister mange sites, der tilbyder hjælp, råd, eksempler og forklaringer.

### TeX, ikke LaTeX

Når man tager den store mængde litteratur i betragtning, der findes om opsætning af tabeller med LaTeX, er der så overhovedet mere at skrive om dem — endnu flere tabel-eksempler og opremsning/demonstration af pakke-kommandoer? Findes der en måde at gribe emnet opsætning af tabeller an på, som fremhæver eller fokuserer på de grundlæggende principper og begreber bag tabelopsætning? Det gør der, men det kræver, at man piller LaTeX-løget af…

Vi besluttede at producere en artikelserie, der søger at give læserne baggrundsinformation og forklaringer om den underliggende *mekanik* i TeX-baseret tabelopsætning. I stedet for at fokusere på opsætning af tabeller ved hjælp af specifikke LaTeX-makroer/-pakker vil vi udforske den *underliggende adfærd* hos TeX-motorer: vi undersøger det lavniveau-typografiske maskineri, som udgør fundamentet, som LaTeX-makrokommandoer er bygget på. Det overordnede mål er at udlede og forklare de centrale metoder og algoritmer i TeX-baseret tabelopsætning — forhåbentlig for at hjælpe læsere/brugere med bedre at forstå, hvorfor tabeller opfører sig, som de gør. En uundgåelig konsekvens af denne tilgang, hvor man skræller de beskyttende lag af LaTeX-makro-isolering væk, er eksponering for rodede lavniveau-detaljer, som brugere normalt (og med glæde) er skærmet fra gennem lag af LaTeX-makrokode.

Det har taget meget tid at undersøge, skrive og illustrere disse artikler, så vores håb er, at de vil være et værdifuldt bidrag til litteraturen og give materiale, der vil informere læserne og hjælpe dem med bedre at forstå dette komplekse område af TeX-typografi. Vi bør understrege, at denne artikelserie vil *ikke* bevæge sig ind på at diskutere *æstetik* i tabeldesign — det er et emne fyldt med subjektive præferencer, og argumenterne om det må udkæmpes andre steder…

### Udforskning af mekanikken i TeX-tabeller: Hvordan kan man gøre det?

For at udforske og derefter skrive om de lavere-niveau mekanismer og processer, der foregår inde i TeX-motorer, såsom opsætning af tabeller, byggede Overleaf “debug”-versioner af Knuths TeX-motor ved hjælp af Martin Rucketts [Web2W-proces](https://w3-o.cs.hm.edu/users/ruckert/public_html/web2w/index.html).

Traditionelt involverer bygning af TeX en proces kaldet Web2C, der bruges i TeX Live, som genererer C-kode ved at konvertere TeXs oprindelige Pascal-kildekode til dens C-ækvivalent. Den proces genererer C-kode, som aldrig var tiltænkt at blive læst af mennesker, kun af C-kompilatorer. Den mekanisk genererede C-kode er *ekstremt* svær at læse eller ændre med henblik på eksperimenter.

I kontrast hertil producerer Web2W C-kildekode (tilgængelig [her](https://w3-o.cs.hm.edu/users/ruckert/public_html/web2w/ctex.c)) som er *flere størrelsesordener* mere læsbar end kode produceret af Web2C. Følgelig er Web2Ws C-kildekode langt mere velegnet til ændringer med henblik på læring/eksperimenter.

Web2W producerer en version af TeX (“CTeX”), som er *ekstremt* tæt på Knuths oprindelige program: “CTeX” indeholder ikke de mange ændringer og forbedringer, der blev indført gennem Web2C-processen — såsom SyncTeX, kommandolinjebehandling og filsøgning via Kpathsea. Selv om man mister disse værdifulde forbedringer, er den resulterende (Web2W) C-kode relativt let at navigere i ved hjælp af Knuths udgivne TeX-kildekode, selv om TeX blev skrevet i Pascal.

* **En note om navne:** Strengt taget må navnet “TeX” kun henvise til den oprindelige software, skrevet og udgivet af Donald Knuth. Enhver ændring af hans software må bruge et andet navn for den resulterende TeX-baserede typografisoftare. Her brugte vi Web2W-processen til at bygge en motor, som stadig i praksis er Knuths oprindelige software. Men for at undgå tvivl vil vi bruge betegnelsen “CTeX” om den specifikke version, der er bygget med Web2W, men vi vil også bruge “TeX” til enten Knuths oprindelige motor eller som en generel betegnelse for typografisproget baseret på principperne i Knuths TeX. Vi håber, at læserne vil tilgive eventuelle lejlighedsvise brud på den strengt korrekte terminologi: vi håber, at mening/intention fremgår af konteksten.

Debug-versionen af CTeX blev kørt ved hjælp af [Eclipse IDE](https://www.eclipse.org/downloads/packages/), hvilket gjorde det muligt at observere realtidsbehandlingen af C-koden, der implementerer de lavniveau primitive (indbyggede) TeX-kommandoer og algoritmer, som Knuth designede til at understøtte tabelopsætning.

Den følgende korte video (ca. 90 sekunder) demonstrerer CTeX-motoren, der kører inde i [Eclipse IDE](https://www.eclipse.org/downloads/packages/):

{% embed url="<https://videos.ctfassets.net/nrgyaltdicpt/7drdFwYR6h5xD88XnurDIH/36511f504755ab274f4da2e3f3fc1ce5/TeXtables.mp4>" %}

Ud over CTeX kompilerede vi også e-TeX for at få adgang til et par ekstra primitiver, som ikke findes i Knuths oprindelige software. Selvom CTeX og e-TeX nu er gamle TeX-baserede motorer, er de stadig velegnede som grundlag for at udforske mekanikken bag tabelopsætning, fordi disse underliggende principper stadig gælder for alle TeX-baserede typografimotorer.

### Hvorfor bruge en ældre TeX-motor til at udforske tabeller?

For det første er den trykte bog, [TeX:The Program](https://www.amazon.co.uk/Computers-Typesetting-TeX-Program-TEX/dp/0201134373), som oplister og forklarer TeXs kildekode, stadig en yderst praktisk guide til TeXs dunkle indre mekanismer, selv om den blev udgivet for mere end 30 år siden (1986). Selvfølgelig kan du selv sætte dokumentationen til TeXs kildekode, for eksempel se Overleaf-projektet [Sæt dokumentationen til kildekoden for TeX, e-TeX eller pdfTeX](https://www.overleaf.com/latex/examples/typeset-the-source-code-documentation-for-tex-e-tex-or-pdftex/qkgfgyspnhcv). Siden udgivelsen af TeX:The Program i 1986 er der udviklet nye TeX-motorer, herunder pdfTeX, XeTeX og LuaTeX, som alle har introduceret funktioner og kommandoer, der ikke er dokumenteret i TeX:The Program, simpelthen fordi de ikke fandtes i Knuths oprindelige software.

For mange kerneprocesser, såsom TeXs tabelopsætning, er koden dokumenteret i TeX:The Program stadig relevant som grundlag for studier — selv om TeXs kildekode er skrevet i Pascal. Derudover er Knuths TeX forholdsvis let og hurtig at kompilere — især via den enormt nyttige [Web2W](https://w3-o.cs.hm.edu/users/ruckert/public_html/web2w/index.html) -proces udviklet af Martin Ruckert. Lethed/hastighed i kompilering gør det langt mere bekvemt at ændre TeX på enkle måder — såsom oprettelsen af SVG-grafik, der bruges senere i denne artikelserie.

### Forstå forskellen mellem TeX og LaTeX

Mange læsere ved allerede, at LaTeX faktisk ikke er et *eksekverbart* typografiprogram, men en stor samling kommandoer (*makroer*) som i sidste ende er skrevet i et lavere-niveau typografi-/programmeringssprog kaldet TeX. Din LaTeX-kode producerer kun opsat output, efter at den er blevet behandlet af et eksekverbart program kaldet en *TeX-motor*— den software, der ligger mellem din LaTeX-kode (dit dokument) og den opsatte PDF. I dag kan brugere vælge mellem forskellige TeX-motorer til at sætte deres LaTeX-kode, herunder pdfTeX, XeTeX og varianter af LuaTeX.

Dem, der er nye i TeX/LaTeX-økosystemet, bliver ofte — og forståeligt nok — forvirrede over den overflod af kryptisk-klingende navne, der bruges om de værktøjer, de møder: TeX, LaTeX, pdfTeX, pdfLaTeX, XeTeX, XeLaTeX, LuaTeX og LuaLaTeX. Hvis du føler det samme, er hjælpen lige ved hånden i Overleaf-artiklen [Hvad ligger der i et navn: En guide til TeXs mange varianter](/latex/da/dybtgaende-artikler/55-what-s-in-a-name-a-guide-to-the-many-flavours-of-tex.md) som forklarer oprindelsen og betydningen af alle disse termer.

#### Dialekter og TeX-primitiver

Hver TeX-motor har et sæt indbyggede kommandoer kaldet *primitiver* som tilsammen udgør den pågældende motors “dialekt” af TeX-typografisproget og afspejler de muligheder, der er indbygget i hver motor. Her betyder betegnelsen “primitive”, der bruges til at beskrive TeX-motorers indbyggede kommandoer, ikke *ikke* at disse kommandoer er grundlæggende eller simple, men at de er fundamentale og udelelige: de er ikke bygget af andre kommandoer (i modsætning til makroer). Alle TeX-motorer deler et stort fælles sæt primitiver, men nogle indeholder primitiver, der er specifikke for netop den motor — hvilket giver anledning til forestillingen om en “dialekt” af TeX.

Uanset hvilken TeX-motor der bruges til at sætte dit LaTeX-dokument, er dens opgave at behandle (“eksekvere”) den samling af LaTeX-kommandoer (dvs. makroer), der bruges til at skrive og opbygge dit dokument. I praksis “konverterer” TeX-motoren din LaTeX-kode (makroer) *tilbage til* deres bestående TeX-motor-primitive kommandoer, som motoren kan eksekvere for at udføre den faktiske opsætning. Du behøver ikke *skal* at bruge LaTeX-kommandoer til at sætte dokumenter med TeX-motorer — du *kunne* vælge at konstruere dine dokumenter udelukkende med TeX-primitiver, dvs. direkte i det lavniveau- *TeX-programmeringssprog* indbygget i TeX-motorer. Men efter nutidens standarder er TeX-sproget ret esoterisk og generelt betragtet som vanskeligt at programmere i — det kan også kræve et stort antal indbyggede primitiver for at opnå dit typografiske mål, hvilket gør det til en fejlbehæftet og potentielt repetitiv programmeringsopgave.

For at undgå at skulle skrive direkte på TeX-sproget eller hele tiden taste den samme række kommandoer igen og igen, lader TeX-motorer dig oprette “genveje” kaldet *makroer*. Ved at oprette makroer definerer du dine egne kommandoer, som pakker potentielt lange og komplekse sekvenser af TeX-sprogets primitiver (eller andre makroer) ind i en enkelt “højere-niveau”-kommando. TeX-programmører kan skrive meget sofistikerede makroer, som indkapsler en stor mængde funktionalitet i en enkelt kommando — såsom de kommandoer, der leveres af LaTeX. Ved at bruge makropakker, såsom LaTeX (eller [ConTeXt](https://wiki.contextgarden.net/Main_Page)), er dokumentforfattere (for det meste) skærmet fra mange kedelige detaljer, hvilket giver dem mulighed for at fokusere på at skrive og sætte tekst i stedet for hele tiden at kæmpe med kompleksiteten og nuancerne i TeX-sproget.

## I begyndelsen...

Sammen med at designe algoritmer til opsætning af matematik og avanceret linjebrud stod Knuth over for udfordringen med at programmere sin TeX-software til at sætte tabeller. Det er klart, at enhver tabelopbygningsalgoritme(r) ikke må være urimeligt begrænsende, fordi det ville frustrere brugere, som har brug for friheden til at skabe et næsten uendeligt udvalg af tabelayouts. Desuden kan tabelceller indeholde et bredt spektrum af indhold, herunder matematik, grafik og tekststykker opdelt i pænt opsatte linjer — faktisk alt, som TeX er i stand til at sætte. At levere denne fleksibilitet kræver, at TeXs tabelopbygningsalgoritmer arbejder hånd i hånd med andre dele af TeXs typografimaskineri.

Men TeX-motorer opkræver en pris for den fleksibilitet, deres tabelopbygningsfunktioner giver: adskillige finesser og nuancer i den lavniveau-adfærd, som de indbyggede (primitive) kommandoer til tabelopsætning har, og der er 9 af dem:

* **`\halign`**, **`\valign`**: centrale kommandoer til tabelopbygning
* **`\tabskip`**: lim placeret mellem \halign-kolonner eller \valign-rækker
* **`\cr`**: obligatorisk afslutning af alle linjer i en tabel
* **`\noalign`**: indsæt materiale mellem \halign-rækker eller \valign-kolonner
* **`\everycr`**: kommandoer (token-register) der læses efter registrering af \cr
* **`\span`**: en kommando med dobbelt funktion: \span opretter celler, der spænder over kolonner eller rækker, eller udvider kommandoer i tabelpræamblen (det vil vi se nærmere på)
* **`\omit`**: spring skabelonerne for en bestemt celle over
* **`\crcr`**: bruges i makroer for at undgå fejl, hvis brugerne glemmer en påkrævet \cr

Vi vil støde på disse kommandoer på vores rejse gennem tabelopbygning.

### Fjerne ekkoer af udfordringerne

Begravet i [TeXs kildekode](https://www.overleaf.com/latex/examples/typeset-the-source-code-documentation-for-tex-e-tex-or-pdftex/qkgfgyspnhcv) er en noget skræmmende introduktion til emnet om implementeringen af de lavniveau-kommandoer \halign og \valign, der er designet til at sætte tabeller:

> “Det er nærmest et mirakel, hver gang \halign og \valign virker, fordi de skærer på tværs af så mange af TeXs kontrolstrukturer. Derfor er denne side nok ikke det bedste sted for en begynder at starte læsningen af dette program; det er bedre først at mestre alt det andet.”

Knuth fortsætter med at sige

> “Bemærk, at mens \halign behandles, giver vi frygtløst kontrollen videre til resten af TeX. På kritiske tidspunkter bliver en justeringsrutine kaldt ind for at udføre en lille handling, men det meste af tiden lurer disse rutiner bare i baggrunden. Det er noget i retning af posthypnotisk suggestion.”

Ud fra disse kommentarer forekommer det rimeligt at konkludere, at selv for Knuth var implementeringen af TeXs tabelopsætning “noget af en udfordring” — at give kontrol og fleksibilitet til brugeren, men samtidig sikre, at TeXs automatiserede algoritmer til tabelopbygning var velorkestrerede sammen med TeXs kerneprocesser for typografi.

Forfatteren bekræfter gerne kompleksiteten af koden og algoritmerne bag TeXs muligheder for tabelopsætning, men også sin beundring for den enorme mængde funktionalitet, der findes i en relativt lille mængde, om end tæt, Pascal- (eller C-) kode.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://overleaf-pro.ayaka.space/latex/da/dybtgaende-artikler/14-how-do-tex-engines-typeset-tables.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
