> 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/no/dybdeartikler/47-tex-tables-how-tex-calculates-spanned-column-widths.md).

# TeX-tabeller: Hvordan TeX beregner bredder for kolonner som spenner over flere kolonner

## Målet med denne artikkelen

I denne artikkelen utforsker vi hvordan $$\mathrm\TeX$$ beregner tabellkolonnebredder når tabeller inneholder oppføringer (f.eks. tabelloverskrifter) som spenner over flere kolonner (f.eks. ved bruk av $$\mathrm\TeX$$ primitivene `\omit` og `\span`). Ved å bruke en enkel [«referansetabell»](#reference-table) som utgangspunkt lager vi en rekke eksempler – avledet fra den referansetabellen – ved å endre ulike oppføringer for å lage kolonner som spenner over flere kolonner. Ved å undersøke virkningen av disse endringene kan vi begynne å utvikle en forståelse av den underliggende algoritmen som $$\mathrm\TeX$$ bruker til å beregne bredden på kolonner som spenner over flere kolonner.

### Bruke $$\mathrm\TeX$$ inneholder $$\mathrm\LaTeX$$

For å undersøke og forklare *hvordan* $$\mathrm\TeX$$ bestemmer breddene til kolonner som spenner over flere kolonner, er det nødvendig å legge til side noen av de fantastiske $$\mathrm\LaTeX$$ tabellpakkene og gå tilbake til grunnleggende tabellkonstruksjonskommandoer på lavt nivå (primitive): nærmere bestemt `\\halign{...}`, `\span` og `\omit`. [Eksisterende $$\mathrm\TeX$$/$$\mathrm\LaTeX$$ tabellpakker](https://ctan.org/topic/table) er selvsagt essensielle produktivitetsverktøy og tilbyr et vell av svært nyttig funksjonalitet som gjør at brukere raskt kan produsere et stort spekter av tabellmateriale ved bruk av $$\mathrm\LaTeX$$. Disse pakkene tilbyr essensielt «makro-stillas» bygget rundt $$\mathrm\TeX$$s lavnivåatferd, og utviklerne deres tilbyr svært velkomne abstraksjoner og isolasjonslag som tar seg av den underliggende kompleksiteten. Mange av disse pakkene er virkelig utrolige prestasjoner innen kompleks $$\mathrm\TeX$$ programmering: vi bør alle være takknemlige for at de finnes for å skjerme oss fra å måtte bruke rå $$\mathrm\TeX$$!

Den faktiske algoritmen som $$\mathrm\TeX$$ bruker til å beregne bredder på kolonner som spenner over flere kolonner, er forklart på side 245 i [$$\mathrm\TeX\text{book}$$](https://www.amazon.co.uk/TeXbook-Donald-E-Knuth/dp/0201134489) og, med flere detaljer, i seksjon 801 (side 336) i den trykte boken som inneholder $$\mathrm\TeX$$s kildekode [$$\mathrm\TeX\text{: The Program}$$](https://www.amazon.co.uk/Computers-Typesetting-Tex-Program-TEX/dp/0201134373). Men for mange (meg selv inkludert) er Knuths forklaringer til tider ganske kompakte og konsise, og til tider kan de være vanskelige å følge i detalj: illustrerte eksempler er alltid svært nyttige.

### Ja, tabeller er komplekse

I seksjon 768 (side 322) i boken [$$\mathrm\TeX\text{: The Program}$$](https://www.amazon.co.uk/Computers-Typesetting-Tex-Program-TEX/dp/0201134373), gjør Knuth en interessant bemerkning:

> «Det er nesten et mirakel når `\halign` og `\valign` virker, fordi de går på tvers av så mange av $$\mathrm\TeX$$.»

I tillegg vier bind IV av den firebinds bokserien [$$\mathrm\TeX\text{ in Practice}$$](https://www.amazon.co.uk/Tex-Practice-Set-Stephan-Bechtolsheim/dp/038797296X/ref=sr_1_11?s=books\&ie=UTF8\&qid=1504256043\&sr=1-11\&keywords=TeX+in+Practice) ikke mindre enn 180 sider (s. 199–379) til å lage tabeller i $$\mathrm\TeX$$ via `\halign` og `\valign`.

Så det er trygt å konstatere at $$\mathrm\TeX$$ tabeller faktisk er «ganske vanskelige».

### Kolonnespenn: \\\omit, \\\span og \\\multispan

Som nevnt, for å utforske $$\mathrm\TeX$$s beregninger av kolonnebredder må vi bruke «rå» $$\mathrm\TeX$$; det vil si en kombinasjon av primitive kommandoer og én $$\text{Plain }\mathrm\TeX$$ makro kalt `\\multispan`. Selv om vi ikke skal bruke disse kommandoene til direkte å illustrere våre eksempeltabeller (dvs. fullt ut forklare all $$\mathrm\TeX$$ kode), er det verdt å ta med en kort merknad som forklarer dem:

* `\halign`: En av to $$\mathrm\TeX$$ primitive kommandoer for å lage tabeller. Den andre er `\valign` men den brukes ikke like mye og vil ikke bli diskutert i denne artikkelen.
* `\omit`: En $$\mathrm\TeX$$ primitiv (kommando) som instruerer $$\mathrm\TeX$$ til å ignorere en tabelloppførings preambelmal.
* `\span`: En $$\mathrm\TeX$$ primitiv (kommando) som brukes til å kombinere to nabotabelloppføringer.
* `\\multispan{n}`: En enkel $$\mathrm\TeX$$ makro for å spenne over `n` kolonner.

I hovedsak, for å spenne over kolonner $$\mathrm\TeX$$ ignorerer det passende antallet tabellpreambelmaler og kombinerer det nødvendige antallet tabelloppføringer til én enkelt oppføring. `\\multispan{n}` fungerer ved å utvide seg til sekvensen av `\omit` og `\span` symboler som trengs for å spenne over `n` kolonner. For eksempel, `\\multispan{3}` utvides til `\\omit\\span\\omit\\span\\omit`.

## Introduserer vår «referansetabell»

Her er referansetabellen vår, etterfulgt av en kommentert versjon som forklarer elementene som brukes i konstruksjonen:

![{{{alt}}}](/files/1ba6ddf621621745ce885f701c3df54f709396ed)

Ved å endre referansetabellen vår vil vi observere hva som skjer med tabellens bredde, og bredden til de enkelte kolonnene, når vi legger til oppføringer som spenner over ulike kolonner. Denne referansetabellen ble produsert i rå $$\mathrm\TeX$$ ved bruk av `\\halign{...}` primitiven sammen med en rekke tilpassede makroer som trengs for å sette tabellene – vi kommer ikke til å diskutere disse makroene fordi de ikke er essensielle for å forstå eksemplene og forklaringene.

Her er en kommentert versjon av referansetabellen vår for å forklare funksjonene:

![{{{alt}}}](/files/69fb68cd236e69841517106a0ba8c621cebd5272)

Vårt første sett med eksempeltabeller, og den innledende referansetabellen, har alle satt `\\tabskip=0pt` slik at $$\mathrm\TeX$$ ikke legger til noe mellomrom mellom kolonnene våre: i praksis berører de alle hverandre. Grunnen til å gjøre dette er å forenkle den innledende diskusjonen og de påfølgende beregningene – senere i artikkelen innfører vi ikke-null `\tabskip` lim igjen for å undersøke virkningen på beregning av bredder for kolonner som spenner over flere kolonner.

Som nevnt i kommentarene har vi lagt til en liten mengde mellomrom (5pt) i starten av alle tabelloppføringer som ikke spenner over flere kolonner (unntatt første rad). Disse 5pt med mellomrom utgjør en del av den totale bredden til alle oppføringer som ikke spenner over flere kolonner (unntatt første rad) og ble lagt til bare for å få tabellen til å se litt mindre trang ut.

### En kort merknad om tabellbredder

Den `\\halign{...}` kommando har tre former:

* `\\halign{...}`: sett tabellen til den bredden som $$\mathrm\TeX$$ beregner, basert på størrelsen på oppføringene (og `\tabskip` lim);
* `\\halign to *width* {...}`: instruer $$\mathrm\TeX$$ til å sette tabellen til en angitt `*width*`;
* `\\halign spread *amount*{...}`: juster den beregnede bredden med `*amount*`.

Når $$\mathrm\TeX$$ setter en tabell ved bruk av `\\halign{...}` den må lese hele tabellen inn i minnet for å utføre de ulike beregningene som kreves for å sette den. Følgelig, med mindre du har angitt bredden ved bruk av `\\halign to *width* {...}` kan du ikke kjenne den endelige bredden før $$\mathrm\TeX$$ har fullført behandlingen (settingen) av den. En måte å få tak i bredden på en tabell produsert av `\\halign{...}` er først å sette tabellen inne i en `\vbox{...}` (f.eks. `\\setbox0=\\vbox{\\halign{...}}`) og deretter for eksempel bruke `\\the\\wd0` for å få bredden.

### Ingen automatisk linjebryting i tabelloppføringer

Det er viktig å merke seg at når $$\mathrm\TeX$$ setter en tabell laget med `\\halign{...}` blir all tekst i tabelloppføringer ikke automatisk gjenstand for linjebryting: tabelloppføringer settes i *begrenset horisontal modus*—akkurat som en `\hbox`. For å aktivere linjebryting må teksten i en tabelloppføring omsluttes av en `\vbox{...}` sammen med å bruke en passende verdi for `\hsize` innen den `\vbox{...}`. Merk imidlertid at tekst innen en `\\noalign{...}` kommando (en $$\mathrm\TeX$$ primitiv) brukt i en `\\halign{...}` er underlagt $$\mathrm\TeX$$s linjebryting. I praksis, og som navnet antyder, `\\noalign{...}` lar $$\mathrm\TeX$$ å «rømme» fra `\\halign{...}` og plassere materiale mellom radene i tabellen – typisk for å lage horisontale streker mellom tabellrader.

### Ikke tillatt: \\\halign{...} inne i \\\hbox{...}

Du kan ikke *direkte* sette en `\\halign{...}` inne i en `\hbox{...}`. Å forsøke å bruke `\\hbox{\\halign{...}}` vil generere en ganske forvirrende feilmelding:

```latex
! Manglende } satt inn.
<innsatt tekst>
                }
<to be read again>
                   \halign
l.1 \\hbox{\\halign
```

#### En forklaring på denne feilen

På grunn av den omsluttende `\hbox{...}` $$\mathrm\TeX$$ er i *begrenset horisontal modus*; den oppdager deretter `\\halign{...}` som er en *vertikal modus* kommando. Hvis du for eksempel bruker `\\halign{...}` inne i et avsnitt, $$\mathrm\TeX$$ vil avslutte avsnittet, behandle `\\halign{...}` og deretter fortsette med resten av avsnittet.

Når den brukes inne i en `\hbox{...}`, den `\\halign{...}` utløser $$\mathrm\TeX$$ for å prøve å rømme tilbake til vertikal modus ved å forsøke å tvinge frem lukking av den gjeldende gruppen: $$\mathrm\TeX$$ rapporterer en «`! Manglende }`» og gir en feilmelding fordi den tror du har gjort en feil i bruken av gruppering. Selv om en høyre klamme (`}`) kanskje ikke mangler fra din $$\mathrm\TeX$$ kode, er feilmeldingen et symptom på at `\hbox{...}` «kommer i veien» og $$\mathrm\TeX$$ tar sitt «beste gjetning» på hva som er riktig framgangsmåte for å løse problemet.

## Eksempler på tabeller med kolonner som spenner over flere kolonner

Følgende serie med tabellfigurer gir en rekke eksempler som demonstrerer virkningen av tabellkolonner som spenner over flere kolonner: dette viser at lange tabelloppføringer kan få uventede resultater for bredden på visse kolonner – og følgelig for tabellens egen bredde. Spørsmålet vi skal ta opp er hva gjør $$\mathrm\TeX$$ når en bestemt tabelloppføring spenner over flere kolonner, men den er «for bred til å passe». Som nevnt ovenfor, $$\mathrm\TeX$$ bruker faktisk en bestemt algoritme på dette problemet med å beregne kolonnebredder: de følgende eksemplene er utformet for å hjelpe til med å utvikle en «følelse» for hvordan denne algoritmen virker.

### Eksempeltabell 1

I dette eksempelet bruker vi `\\multispan{2}` for å spenne over kolonnene 1 og 2 med en oppføring der teksten er **En tabelloverskrift**:

![{{{alt}}}](/files/5087e7677a217b057905a70069bed03ebcccc48a)

#### Observasjoner

* Bredden på denne tabellen er den samme som i [referansetabellen](#reference-table): $$327.71722\text{pt}$$.
* Bredden på oppføringen som spenner over kolonnene 1 og 2 er $$81.04953\text{pt}$$ som er mindre enn den totale bredden av oppføringene i kolonnene den spenner over: $$52.56676\text{pt} + 57.06679\text{pt} = 109.63355\text{pt}$$

## Eksempeltabell 2

Som i [Eksempeltabell 1](#example-table-1), bruker dette eksempelet også `\\multispan{2}` for å spenne over kolonnene 1 og 2, men her bruker vi en lengre oppføring der teksten er **En litt lengre tabelloverskrift**.

![{{{alt}}}](/files/e9e4a3d6edbef38f22422ebe515d961b21b3f489)

#### Observasjoner

Hvis du sammenligner dette eksempelet med vår [referansetabellen](#reference-table) kan vi se følgende:

* Bredden på denne tabellen har økt fra $$327.71722\text{pt}$$ til $$374.37032\text{pt}$$: totalt $$46.6531\text{pt}$$.
* Bredden på oppføringen som spenner over kolonnene 1 og 2 ($$156.28664\text{pt}$$) er større enn den totale bredden til oppføringene i kolonnene den spenner over: $$52.56676\text{pt} + 57.06679\text{pt} = 109.63355\text{pt}$$. Denne forskjellen er $$156.28664\text{pt}-109.63355\text{pt} = 46.6531\text{pt}$$ som er den samme mengden som tabellbredden har økt med.
* $$\mathrm\TeX$$ har justert bredden på kolonne 2 for å gi den ekstra plassen som trengs. Senere vil vi se hvordan $$\mathrm\TeX$$ beregner mengden som kolonne 2 må øke med.
* Kolonne 1 er upåvirket: bredden er ikke påvirket av oppføringen som spenner over kolonnene 1 og 2.

### Eksempeltabell 3

I dette eksempelet bruker vi `\\multispan{3}` for å spenne over kolonnene 1 til 3 med en oppføring hvis tekst er den samme som [Eksempeltabell 2](#example-table-2): **En litt lengre tabelloverskrift**.

![{{{alt}}}](/files/696326740dd53b37648995602a9516ad869bf1ed)

#### Observasjoner

* Bredden på denne tabellen er den samme som i [referansetabellen](#reference-table): $$327.71722\text{pt}$$.
* Bredden på oppføringen som spenner over kolonnene 1 til 3 ($$156.28664\text{pt}$$) er mindre enn den totale bredden til oppføringene i de tre kolonnene den spenner over: $$52.56676\text{pt} + 57.06679\text{pt} + 59.03899\text{pt} = 168.67254\text{pt}$$.
* Ingen av kolonnebreddene er blitt påvirket av oppføringen som spenner over kolonnene 1 til 3.

Begynner du å se et mønster som vokser fram?

### Eksempeltabell 4

Som med [Eksempeltabell 3](#example-table-3), bruker vi her `\\multispan{3}` for å spenne over kolonnene 1 til 3, men denne gangen med en oppføring hvis tekst er betydelig lengre: **En betydelig lengre tabelloverskrift som strekker seg langt**.

![{{{alt}}}](/files/68a0f31b4b8f5169bb4e6c1071c30f2ffac71409)

#### Observasjoner

* Sammenlignet med [referansetabellen](#reference-table), har bredden på denne tabellen økt fra $$327.71722\text{pt}$$ til $$465.95685\text{pt}$$: en økning på $$138.23963\text{pt}$$.
* Bredden på oppføringen som spenner over kolonnene 1 til 3 er $$306.91216\text{pt}$$.
* Den totale bredden til oppføringene i de tre spente kolonnene er $$52.56676\text{pt} + 57.06679\text{pt} + 59.03899\text{pt} = 168.67254\text{pt}$$.
* Forskjellen i bredde mellom den lange spenner-oppføringen og oppføringene i kolonnene 1 til 3 er $$306.91216\text{pt}-168.67254\text{pt}=138.23962\text{pt}$$. Samme beløp (til 4 desimaler!) som tabellbredden har økt med.
* Bare kolonne 3 har fått økt bredde: verken kolonne 1 eller kolonne 2 er berørt.

#### Et mønster trer fram

Hvis vi ser på [Eksempeltabell 2](#example-table-2) og [Eksempeltabell 4](#example-table-4) kan vi se at i begge tilfeller er det **siste kolonnen i spennet** som fikk økt bredden for å gi plass til den lange oppføringen som spente over kolonnene:

* I [Eksempeltabell 2](#example-table-2): Den lange oppføringen spente over kolonnene 1 og 2. Kolonne 2 ble «strukket».
* I [Eksempeltabell 4](#example-table-4): Den lange oppføringen spente over kolonnene 1 til 3. Kolonne 3 ble «strukket».

#### Bredden på kolonne 3: Trer en algoritme fram?

De følgende beregningene gir en klarere indikasjon på hva $$\mathrm\TeX$$ gjør. Her er det vi vet:

* Bredden på den lange oppføringen som spenner over kolonnene 1 til 3 er $$306.91216\text{pt}$$.
* Den totale bredden til oppføringene i kolonnene 1 og 2 er $$52.56676\text{pt} + 57.06679\text{pt} = 109.63355\text{pt}$$.

Hva er forskjellen mellom disse verdiene? Den er $$306.91216\text{pt}-109.63355\text{pt} = 197.2786\text{pt}$$ og dette er bredden som brukes for kolonne 3: den oppstår direkte fra algoritmen som brukes av $$\mathrm\TeX$$.

### Eksempeltabell 5

Før vi kommer til et mer komplisert eksempel, her er ett “enkelt” eksempel til. Denne tabellen inneholder den samme lange oppføringen som [Eksempeltabell 4](#example-table-4): **En betydelig lengre tabelloverskrift som strekker seg langt**; men denne gangen bruker vi `\\multispan{6}` som lar den oppføringen spenne over hele tabellen. Som du kan se, har den resulterende tabellen fortsatt samme bredde som vår [referansetabellen](#reference-table) ($$327.71722\text{pt}$$) som betyr at ingen kolonner er blitt påvirket av denne svært lange oppføringen. Tydeligvis er dette fordi bredden på oppføringen ($$306.91216\text{pt}$$) er mindre enn den totale bredden til alle oppføringene den spenner over: $$327.71722\text{pt}$$; dvs. tabellens bredde.

![{{{alt}}}](/files/cbc7304a31497aaf1424e193f4e45185934c686a)

### Eksempeltabell 6: Litt mer komplisert

Her ser vi på en serie på tre eksempeltabeller (6(a)–6(c)) for å vise virkningen av to forskjellige oppføringer som begge spenner inn i kolonne 5. [Eksempeltabell 6(a)](#example-table-6a) og [Eksempeltabell 6(b)](#example-table-6b) viser begge en tabell som inneholder én enkelt oppføring som spenner over flere kolonner helt til kolonne 5. [Eksempeltabell 6(c)](#example-table-6c) kombinerer begge de spente oppføringene i én enkelt tabell og stiller spørsmålet: hvilken oppføring bestemmer faktisk bredden på kolonne 5, og hvorfor? Svaret tar oss til kjernen av algoritmen som brukes av $$\mathrm\TeX$$.

#### Eksempeltabell 6(a)

![{{{alt}}}](/files/0323a7ab2193d0b9db125d8c270771de2251cf2a)

**Observasjoner**

* Sammenlignet med [referansetabellen](#reference-table), har bredden på denne tabellen økt fra $$327.71722\text{pt}$$ til $$371.11153\text{pt}$$: en økning på $$43.39431\text{pt}$$.
* Bredden på oppføringen som spenner over kolonnene 3 til 5 er $$215.06683\text{pt}$$.
* Den totale bredden til oppføringene i kolonnene 3 til 5 er $$59.03899\text{pt} + 52.98344\text{pt} + 59.6501\text{pt} = 171.67253\text{pt}$$.
* Forskjellen i bredde mellom oppføringene som spennes i kolonnene 3 til 5 og bredden på den spenner-oppføringen er $$215.06683\text{pt}-171.67253\text{pt}=43.3943\text{pt}$$: det nøyaktige beløpet (til 4 desimaler!) som tabellbredden har økt med.

#### Eksempeltabell 6(b)

![{{{alt}}}](/files/447f1b86b8bada8f6c21c69d8a8c33cf9ad90db4)

**Observasjoner**

* Sammenlignet med [referansetabellen](#reference-table), har bredden på denne tabellen økt fra $$327.71722\text{pt}$$ til $$353.3233\text{pt}$$: en økning på $$25.60608\text{pt}$$.
* Bredden på oppføringen som spenner over kolonnene 1 til 5 er $$306.91216\text{pt}$$.
* Den totale bredden til oppføringene i kolonnene 1 til 5 er $$52.56676\text{pt} + 57.06679\text{pt} + 59.03899\text{pt} + 52.98344\text{pt} + 59.6501\text{pt} = 281.30608\text{pt}$$.
* Forskjellen i bredde mellom oppføringene som spennes i kolonnene 1 til 5 og bredden på den spenner-oppføringen er $$306.91216\text{pt}-281.30608\text{pt}=25.60608\text{pt}$$: **note** dette er *mindre* enn verdien beregnet for [Eksempel 6(a)](#example-table-6a), som var $$43.3943\text{pt}$$.

#### Eksempeltabell 6(c)

Her kombinerer vi oppføringene i eksempeltabellene [6(a)](#example-table-6a) og [6(b)](#example-table-6b) i én enkelt tabell: hva skjer?

![{{{alt}}}](/files/1e15c1b9cdd2d7493bc797c03e1ad272ddf63136)

**Observasjon**

* Sammenlignet med [referansetabellen](#reference-table), har bredden på denne tabellen økt fra $$327.71722\text{pt}$$ til $$371.11153\text{pt}$$: en økning på $$43.39431\text{pt}$$. Vi merker at dette er nøyaktig det samme som [Eksempeltabell 6(a)](#example-table-6a).

#### Hva gjør $$\mathrm\TeX$$ ?

For å forstå resultatene av $$\mathrm\TeX$$s algoritme og beslutningsprosesser legger vi merke til at denne oppføringen

![{{{alt}}}](/files/bcaa012fdd60906e43ba82698dc0a9e4724c4092)

strekker seg utover oppføringene som dekkes av $$25.60608\text{pt}$$; imidlertid strekker denne oppføringen

![{{{alt}}}](/files/fdd251e0cd1f59d0dbeaf99cce1f6bb0b9519d81)

seg enda lenger utover oppføringene som dekkes: med $$43.3943\text{pt}$$. Dermed «vinner» den oppføringen kappløpet, og kolonne 5 får økt bredde med **maksimum** av disse to verdiene ($$43.3943\text{pt}$$). Bredden på kolonne 5 blir nå $$59.6501\text{pt} + 43.3943\text{pt} = 103.0444\text{pt}$$ for å gi plass til oppføringen som spenner over kolonnene 3 til 5. Vår beskrivelse av den nøyaktige «rekkefølgen av hendelser» er litt forenklet, men resultatet er slik vi har beskrevet.

## Tar med litt kompleksitet igjen

For å minimere kompleksiteten i diskusjonene våre (så langt) har vi brukt relativt enkle eksempler for å demonstrere prinsippene i $$\mathrm\TeX$$s algoritme; særlig satte vi `\\tabskip=0pt`. I praksis vil «virkelige» tabeller sannsynligvis ha mange oppføringer som spenner over et spekter av kolonner og vil selvsagt ha ikke-null verdier for `\tabskip` lim – et tema vi nå skal se på igjen.

### \\\tabskip-lim og bredder for kolonner som spenner over flere kolonner

Tabellutforming krever ofte at det legges til mellomrom mellom kolonner, og selvfølgelig $$\mathrm\TeX$$ har denne funksjonen gjennom en primitiv kommando kalt `\tabskip`. Denne kommandoen kan brukes til å sette fast eller fleksibelt lim (avstand):

* før en tabell (dvs. til venstre for kolonne 1);
* mellom én eller flere kolonner;
* etter tabellen (dvs. til høyre for den siste kolonnen).

Her er et eksempel for å minne oss selv:

![{{{alt}}}](/files/4c87a1b6cd9d2b7ec155643580f28c27c26bedf4)

### Hvordan påvirker \\\tabskip-lim bredder for kolonner som spenner over flere kolonner?

Tilstedeværelsen av ikke-null `\tabskip` lim mellom kolonner gir ekstra plass som spente oppføringer kan «absorbere» før $$\mathrm\TeX$$ trenger å tenke på å øke bredden på den siste kolonnen i et spenn.

I vårt neste eksempel bruker vi to tabeller for å sammenligne resultatene av å spenne over to kolonner. Den eneste forskjellen mellom tabellene er bruken av `\tabskip` lim.

* Det første eksempelet bruker vår opprinnelige «referansetabell» som, hvis du husker, har satt `\\tabskip=0pt`.
* Det andre eksempelet bruker en modifisert versjon av vår [referansetabellen](#reference-table) (kommentert ovenfor) som har `\\tabskip=10pt` før og etter tabellen, men enda viktigere, har den satt `\\tabskip=20pt` mellom kolonnene.

Innen den *modifiserte* referansetabellen har de to spente kolonnene ingen effekt på kolonnebreddene (og tabellbredden), men de påvirker bredden på kolonne 2 (og tabellbredden) i den *opprinnelige* [referansetabellen](#reference-table).

### Opprinnelig referansetabell: \\\tabskip=0pt

Her viser vi vår opprinnelige [referansetabellen](#reference-table) sammen med en andre tabell (avledet fra vår opprinnelige [referansetabellen](#reference-table)) som har en oppføring «**Test en lengre tabelloverskrift**» som spenner over kolonnene 1 og 2. Helt tydelig er både kolonne 2 (i den andre tabellen i diagrammet) og dermed hele tabellen påvirket av de spente kolonnene.

![{{{alt}}}](/files/85da7d5715924395fda1639529947007248c97f0)

### Modifisert referansetabell: \\\tabskip=20pt

Her viser vi vår modifiserte referansetabell sammen med en andre tabell (avledet fra vår modifiserte referansetabell) som også har en oppføring «**Test en lengre tabelloverskrift**» som spenner over kolonnene 1 og 2. Helt tydelig er verken bredden på kolonne 2 eller tabellen i det andre tabellen i diagrammet påvirket av de spente kolonnene. I dette tilfellet har tilstedeværelsen av `\tabskip` lim (`20pt`) mellom kolonnene bidratt til å «absorbere» plassen som teksten i oppføringen som spenner over kolonnene 1 og 2 trenger:

![{{{alt}}}](/files/7fb0df319ebc855ca53e34fb571441e2be689f0c)

## Essensen av $$\mathrm\TeX$$s algoritme

Forhåpentligvis har eksemplene ovenfor bidratt til å utvikle en «fornemmelse» av hva $$\mathrm\TeX$$ gjør for å håndtere oppføringer som spenner over flere kolonner, og hvordan $$\mathrm\TeX$$ ved behov vil justere bredden på den **siste** kolonnen innenfor hvert område av spente kolonner. I tillegg til bredden på oppføringer innenfor enkelte kolonner som spennes, er tilstedeværelsen av ikke-null `\tabskip` lim en viktig faktor som $$\mathrm\TeX$$ tar i betraktning når den avgjør om den trenger å justere noen kolonnebredder. Hovedpoenget å huske er at $$\mathrm\TeX$$s mål er å beregne en passende bredde for **siste kolonne** innenfor hvert område av kolonner som spenner over.

### Endelig tabelleksempel: siste kolonner i et område som spenner over flere kolonner

I dette siste eksemplet bruker vi igjen vår modifiserte referansetabell (med `\tabskip` limverdier omtalt ovenfor) for å avlede en annen tabell som inneholder ulike kolonner som spennes over av streker — vi har brukt streker for å gjøre spennene lettere å se.

De to tabellene er nøye justert for å vise at ingen kolonner før kolonne 5 i den øvre tabellen er påvirket av kolonnene som spenner over. Det mørkere grønne området til venstre i diagrammet viser at kolonne 1 til 4 i begge tabellene fortsatt flukter perfekt. Til høyre er det et lysere grønt skyggeområde som viser at bare kolonne 5 og 6 er blitt påvirket av oppføringene som spenner over.

I den øvre tabellen er spennene som følger:

* kolonnene 1 til 5: dekket av en $$400\text{pt}$$ strek;
* kolonnene 3 til 5: dekket av en $$200\text{pt}$$ strek;
* kolonnene 4 til 6: dekket av en $$250\text{pt}$$ strek.

![{{{alt}}}](/files/371427a90d8c6c43dc253e988ecd3f17aba96fb8)

Forklaringen er igjen at innenfor en serie av kolonner som spenner over flere, justeres bare bredden til den siste kolonnen (om nødvendig): mellomliggende kolonner påvirkes ikke, og her betyr det kolonne 1 til 4 — selv om, selvfølgelig, bredden på kolonne 1 til 4 (og mellomliggende `\tabskip` lim) tas i betraktning når de justerte breddene til kolonne 5 og 6 beregnes.

### En gjennomgang av $$\mathrm\TeX$$s algoritme

Vi avslutter med en *forenklet* gjennomgang av «$$\mathrm\TeX$$dens tankeprosess» mens den beregner breddene til kolonner i oppføringer som spenner over. Å beskrive $$\mathrm\TeX$$s algoritmer er ikke alltid rett fram, så vi vil ta oss noen «forenklede kunstneriske friheter» for å gi en oversikt over hva som skjer. Lesere som er interessert i alle de rotete detaljene, henvises til seksjon 801 (side 336) i den trykte boken som inneholder $$\mathrm\TeX$$s kildekode [$$\mathrm\TeX\text{: The Program}$$](https://www.amazon.co.uk/Computers-Typesetting-Tex-Program-TEX/dp/0201134373).

Tabeller i den virkelige verden blir ofte laget med mange bruk av `\span` primitive kommandoen (f.eks. inne i $$\mathrm\LaTeX$$ pakker) for å konstruere flere forekomster av kolonner som spenner over inni tabellen. For å håndtere dette vedlikeholder datastrukturene (dypt inne i $$\mathrm\TeX$$) informasjon (såkalte *span-noder*) som forteller $$\mathrm\TeX$$ om koblingene (spennene) mellom tabelloppføringer/kolonner. Det er åpenbart at $$\mathrm\TeX$$ må anvende algoritmene sine på en systematisk måte og må behandle hele tabellen for å gjøre sine endelige beregninger — for å fastslå alle kolonnebredder, tabellens totale bredde og, om nødvendig, hvor mye fleksible lim som brukes i tabellen må strekkes eller krympes. Det er egentlig ikke overraskende at $$\mathrm\TeX$$ kan fortelle deg den endelige tabellbredden før den har behandlet `\\halign{...}` kommandoen fullstendig — den har virkelig mye arbeid å gjøre!

Utgangspunktet for beregning av kolonnebredder er kolonne 1 fordi ingenting, selvfølgelig, kan spenne fra venstre for (og *over/inn i*) kolonne 1. $$\mathrm\TeX$$ starter med å bestemme bredden på kolonne 1 ved å finne hvilken oppføring som har den største *naturlige bredden*. La oss kalle den maksimale bredden $$w\_1$$og hvis det finnes oppføringer som spenner fra kolonne 1 til kolonne 2, la oss kalle bredden til den oppføringen $$w\_{12}$$ (bredde fra 1 til 2). I tillegg vil vi betegne `\tabskip` limet mellom kolonne 1 og 2 som $$t\_{1}$$— merk at vi bare vurderer *naturlige bredden* til den `\tabskip` limen, og foreløpig ignorerer eventuelle strekk- eller krympekomponenter det måtte ha. La også den maksimale naturlige bredden til alle oppføringer i kolonne 2 som ikke spenner over flere være $$w\_2$$.

Det viktigste å merke seg er at $$\mathrm\TeX$$ prøver å beregne bredden til kolonne 2 ved bare å vurdere de oppføringene der spennet *starter* med kolonne 1 og *slutter* ved kolonne 2. Hovedhensynet for $$\mathrm\TeX$$ er testen $$\max(w\_{2}, w\_{12} - (w\_1+ t\_1))$$—det kan være flere oppføringer som spenner over kolonne 1 og 2: noen kan være smale (liten $$w\_{12}$$), andre veldig brede (stor $$w\_{12}$$) så $$\mathrm\TeX$$ leter etter den som har størst effekt (derav $$\max(\text{...})$$). Her er verdien av $$w\_{12} -(w\_1+ t\_1)$$ er hvor mye en oppføring som spenner over kolonne 1 og 2 «flyter over» fra kolonne 1 til kolonne 2: merk at $$\mathrm\TeX$$ bruker bredden til kolonne 1 **og** den `\tabskip` lim ($$t\_{1}$$) mellom kolonne 1 og 2. Når $$\mathrm\TeX$$ har fastslått om noen spenn fra kolonne 1 til 2 faktisk påvirker bredden til kolonne 2, setter den bredden til kolonne 2 til den maksimale verdien den har fastslått (ved å bruke testen som er beskrevet). $$\mathrm\TeX$$ fortsetter å arbeide seg gjennom alle de andre kolonnene og utføre lignende tester.

Og til slutt, bare for fullstendighetens skyld, siterer vi her essensen av $$\mathrm\TeX$$s algoritme for beregning av kolonnebredder (hentet fra Knuths kildekodedokumentasjon for $$\mathrm\TeX$$):

La $$w\_{ij}$$ være maksimum av de naturlige breddene til alle oppføringer som spenner over kolonnene $$i$$ til $$j$$, inklusive. De endelige kolonnebreddene er definert ved formelen

$$\begin{equation\*} w\_j=\max\_{1\leq i\leq j}\biggl(w\_{ij}-\sum\_{i\leq k< j}(t\_k+w\_k)\biggr) \end{equation\*}$$

der $$t\_k$$ er den naturlige bredden til tabskip-limet mellom kolonnene $$k$$ og $$k+1$$.

## Kolofon: Bruk av Overleaf til å lage tabeller som SVG-grafikk

Alle $$\mathrm\TeX$$ tabellene som presenteres i denne artikkelen, er Scalable Vector Graphics (SVG)-filer produsert på Overleaf-plattformen. Anmerkningene (piler og grønne bokser) ble lagt til ved å åpne SVG-grafikken i Inkscape — merk imidlertid at teksten i anmerkningene ble satt i $$\mathrm\TeX$$ som ekstra tekst for å ledsage tabellen: bare pilene og de grønne bakgrunnene ble lagt til i Inkscape. Hvis du er interessert i å vite hvordan dette ble oppnådd, les videre.

Overleafs servere bruker $$\mathrm\TeX \text{ Live}$$ distribusjonen som, i tillegg til $$\mathrm\TeX$$-baserte typemotorer, tilbyr et vell av svært nyttige $$\mathrm\TeX$$-relaterte programvareverktøy og hjelpemidler. Blant disse er et som heter [`dvisvgm`](https://dvisvgm.de) som, som navnet antyder, konverterer $$\mathrm\TeX$$s tradisjonelle DVI (**D**e**V**ice **I**uavhengig)-utdatafilformat til SVG. Blant de mange [kommandolinjealternativene](https://dvisvgm.de/Manpage/) `dvisvgm` finnes et alternativ (`-n` eller `--no-fonts`) som vil instruere det til å konvertere all tekst til *baner* hvilket betyr at teksten i SVG-grafikk tegnes med linjer og kurver i stedet for faktiske skrifter og glyfer. Dette kan øke filstørrelsen på den resulterende SVG-grafikken, men det sikrer at SVG-grafikken er ekstremt portabel og nesten garantert vil fungere godt på enhver enhet.

### Så ... hvordan ble det gjort?

I en [tidligere artikkel](https://www.overleaf.com/blog/510-using-luatex-to-run-tools-and-utilities-installed-on-overleafs-servers) beskrev jeg hvordan du kan bruke $$\text{Lua}\mathrm\TeX$$ for å kjøre de ulike programvareverktøyene og hjelpemidlene installert på Overleafs servere — det er en ekstremt enkel og praktisk teknikk. Denne teknikken ble brukt til å generere SVG-grafikk av satte $$\mathrm\TeX$$ tabeller, som følger. Fra hoved- $$\mathrm\TeX$$ dokumentfilen ble koden for å sette hver tabell (opprettet ved å bruke `\halign`) skrevet til en `.tex` fil. Dette ble oppnådd ved å omslutte tabellkoden i et par kommandoer som jeg kalte `\beginscoop` og `\endscoop`. Det finnes trolig mange andre måter å oppnå de ønskede resultatene på, men her er makrodefinisjonene jeg brukte:

```latex
\def\cc{\catcode`\#=12\relax}
\long\def\scoop#1\endscoop{\global\fulltoks={#1}\egroup}
\def\beginscoop{\global\advance\numfigs by1\relax\bgroup\cc\scoop}
```

Du bruker dem slik:

```latex
\beginscoop
\\halign{...}
\endscoop
```

Merk at `\endscoop` tokenet bare tjener til å avgrense parameteren til `\scoop` makroen: $$\mathrm\TeX$$ effektivt forkaster `\endscoop` tokenet, så vi trenger egentlig ikke å definere det (f.eks. ved `\def\endscoop{...}`).

Den $$\mathrm\TeX$$ koden som finnes i `\\halign{...}` lagres i en `toks` register kalt `\fulltoks`. Et vanskelig punkt jeg støtte på (med $$\text{Lua}\mathrm\TeX$$) var behovet for å hindre `#` tegn i `\\halign{...}` preamblen fra å bli «doblet» til `##` når de skrives ut til en `.tex` fil. For å unngå dette måtte jeg midlertidig sette `\catcode`på `#` tegnene til 12 før jeg lagret $$\mathrm\TeX$$ koden (tokenene) i `\fulltoks` tokenregisteret.

Neste steg er å skrive tokenene som finnes i `\fulltoks` som en $$\mathrm\TeX$$ fil — fordi jeg brukte $$\text{Lua}\mathrm\TeX$$ viste dette seg å være *ekstremt* enkelt takket være $$\text{Lua}\mathrm\TeX$$s fantastiske Lua-API. Kort fortalt skrev jeg en makro kalt `\writefile{...}` som tar som parameter navnet på et tokenregister hvis tokenene du vil skrive ut til en fil (f.eks. `\writefile{fulltoks}`). Inne i `\writefile{...}` makroen brukte jeg Lua-API-et til å få en tekstlig representasjon av `\fulltoks` tokenregisteret:

```latex
\def\writefile#1{%
\directlua{
...
...
 local p=tex.toks["#1"]
...
...
}}
```

Her er et skjermbilde som viser litt mer av `\writefile{...}` kommandoen:

[![{{{alt}}}](/files/36045cf8b8d328bca872f6abe50cd6a7721aab24)](https://www.filepicker.io/api/file/ngeDmgRStGWvG044RE1A)

Lua-språket og Lua-API-et som tilbys av $$\text{Lua}\mathrm\TeX$$ kan ofte forenkle $$\mathrm\TeX$$ programmeringsoppgaver, og det er på grunn av disse nyttige og kraftfulle funksjonene at jeg har brukt $$\text{Lua}\mathrm\TeX$$ siden rundt 2009 — og fortsatt er en stor fan av denne virkelig fantastiske $$\mathrm\TeX$$ motoren. OK, reklamen $$\text{Lua}\mathrm\TeX$$ avsluttes nå.

Etter å så enkelt ha fått tak i $$\mathrm\TeX$$ koden som er lagret i `\fulltoks` skrives den ut til en fil sammen med litt ekstra kode for å gjøre den til en korrekt formet $$\mathrm\LaTeX$$ fil. De neste trinnene er:

1. Behandle `.tex` filen som inneholder tabellen vår med $$\text{pdf}\mathrm\LaTeX$$ (i DVI-modus) slik at den setter tabellen og genererer en `.dvi` fil for `dvisvgm` å behandle. Ja, du kan bruke $$\text{Lua}\mathrm\TeX$$ til å kjøre $$\text{pdf}\mathrm\LaTeX$$— igjen brukte jeg metoden omtalt i en [tidligere artikkel](/latex/no/dybdeartikler/52-using-luatex-to-run-tools-and-utilities-installed-on-overleaf-s-servers.md).
2. Og til slutt, kjør `dvisvgm` for å behandle `.dvi` filen for å generere en SVG-grafikk av den satte $$\mathrm\TeX$$ tabellen.
3. For å få tak i selve SVG-grafikken kan du laste ned en ZIP-fil fra Overleaf — og sørge for å velge **Input- og output-filer** alternativet.


---

# 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/no/dybdeartikler/47-tex-tables-how-tex-calculates-spanned-column-widths.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.
