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

# TeX-tabeller: Hur TeX beräknar bredden på kolumner som spänner över flera kolumner

## Målet med denna artikel

I den här artikeln utforskar vi hur $$\mathrm\TeX$$ beräknar tabellkolumners bredd när tabeller innehåller poster (t.ex. tabellrubriker) som sträcker sig över flera kolumner (t.ex. med hjälp av $$\mathrm\TeX$$ primitiver `\omit` och `\span`). Med en enkel [”referenstabell”](#reference-table) som utgångspunkt skapar vi en rad exempel—utifrån denna referenstabell—genom att ändra olika poster för att skapa kolumner som sträcker sig över flera kolumner. Genom att undersöka effekten av dessa ändringar kan vi börja utveckla en förståelse för den underliggande algoritm som $$\mathrm\TeX$$ använder för att beräkna bredden på kolumner som sträcker sig över flera kolumner.

### Använda $$\mathrm\TeX$$ inte $$\mathrm\LaTeX$$

För att undersöka och förklara *hur* $$\mathrm\TeX$$ bestämmer bredden på kolumner som sträcker sig över flera kolumner är det nödvändigt att avstå från alla de fantastiska $$\mathrm\LaTeX$$ tabellpaketen och återgå till grundläggande, lågnivå (primitiva) tabellskapande kommandon: särskilt, `\\halign{...}`, `\span` och `\omit`. [Befintliga $$\mathrm\TeX$$/$$\mathrm\LaTeX$$ tabellpaket](https://ctan.org/topic/table) är naturligtvis viktiga produktivitetsverktyg och erbjuder en mängd mycket användbar funktionalitet som gör det möjligt för användare att snabbt producera ett enormt utbud av tabellmaterial med hjälp av $$\mathrm\LaTeX$$. Dessa paket tillhandahåller nödvändig ”makroscaffolding” byggd kring $$\mathrm\TeX$$s lågnivåbeteende och deras utvecklare tillhandahåller mycket välkomna abstraktioner och isolerande lager som tar hand om de underliggande komplexiteterna. Många av dessa paket är verkligen otroliga bedrifter inom komplex $$\mathrm\TeX$$ programmering: vi borde alla vara tacksamma för att de finns och skyddar oss från att behöva använda rå $$\mathrm\TeX$$!

Den faktiska algoritm som $$\mathrm\TeX$$ använder för att beräkna bredder för kolumner som sträcker sig över flera kolumner förklaras på sidan 245 i [$$\mathrm\TeX\text{book}$$](https://www.amazon.co.uk/TeXbook-Donald-E-Knuth/dp/0201134489) och, med ytterligare detaljer, i avsnitt 801 (sidan 336) i den tryckta boken som innehåller $$\mathrm\TeX$$s källkod [$$\mathrm\TeX\text{: The Program}$$](https://www.amazon.co.uk/Computers-Typesetting-Tex-Program-TEX/dp/0201134373). Men för många människor (inklusive mig själv) är Knuths förklaringar ibland ganska kompakta och koncisa och kan ibland vara svåra att följa i detalj: illustrerade exempel är alltid mycket hjälpsamma.

### Ja, tabeller är komplexa

I avsnitt 768 (sidan 322) i boken [$$\mathrm\TeX\text{: The Program}$$](https://www.amazon.co.uk/Computers-Typesetting-Tex-Program-TEX/dp/0201134373), gör Knuth en intressant kommentar:

> ”Det är lite av ett mirakel varje gång `\halign` och `\valign` fungerar, eftersom de skär över så många av styrstrukturerna i $$\mathrm\TeX$$.”

Dessutom ägnar volym IV av den fyra volymer långa 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) inte mindre än 180 sidor (s. 199–379) åt att skapa tabeller i $$\mathrm\TeX$$ via `\halign` och `\valign`.

Så det är säkert att konstatera att $$\mathrm\TeX$$ tabeller verkligen är ”ganska knepiga”.

### Kolumnöverspanning: \\\omit, \\\span och \\\multispan

Som nämnts, för att utforska $$\mathrm\TeX$$s kolumnbreddsberäkningar behöver vi använda ”rå” $$\mathrm\TeX$$; vilket innebär en kombination av primitiva kommandon och en $$\text{Plain }\mathrm\TeX$$ makro kallad `\\multispan`. Även om vi inte kommer att använda dessa kommandon för att direkt illustrera våra exempeltabeller (dvs. fullt ut förklara all $$\mathrm\TeX$$ kod), är det värt att ta med en kort notis som förklarar dem:

* `\halign`: En av två $$\mathrm\TeX$$ primitiver (kommandon) för att skapa tabeller. Den andra är `\valign` men den används inte lika ofta och kommer inte att diskuteras i den här artikeln.
* `\omit`: En $$\mathrm\TeX$$ primitiv (kommando) som instruerar $$\mathrm\TeX$$ att ignorera en tabellposts preambelmall.
* `\span`: En $$\mathrm\TeX$$ primitiv (kommando) som används för att kombinera två intilliggande tabellposter.
* `\\multispan{n}`: En enkel $$\mathrm\TeX$$ makro för att spänna över `n` kolumner.

I huvudsak, för att spänna över kolumner $$\mathrm\TeX$$ ignoreras lämpligt antal tabellpreambelmallar och det nödvändiga antalet tabellposter kombineras till en enda post. `\\multispan{n}` fungerar genom att expandera till sekvensen av `\omit` och `\span` token som behövs för att spänna över `n` kolumner. Till exempel, `\\multispan{3}` expanderas till `\\omit\\span\\omit\\span\\omit`.

## Introduktion av vår ”referenstabell”

Här är vår referenstabell följd av en kommenterad version som förklarar elementen som används i dess uppbyggnad:

![{{{alt}}}](/files/9e41487b28e445d066aac5187f8fdb4a172a33b3)

Genom att ändra vår referenstabell kommer vi att observera vad som händer med tabellens bredd, och med de enskilda kolumnernas bredd, när vi lägger till poster som sträcker sig över olika kolumner. Denna referenstabell skapades i rå $$\mathrm\TeX$$ med hjälp av `\\halign{...}` primitiven tillsammans med ett antal egna makron som behövs för att sätta tabellerna—vi kommer inte att diskutera dessa makron eftersom de inte är nödvändiga för att förstå exemplen och förklaringarna.

Här är en kommenterad version av vår referenstabell för att förklara dess egenskaper:

![{{{alt}}}](/files/28bcb1d601e07c7c19912dc46c03d67e5e7a0a7e)

Vår första uppsättning exempeltabeller, och den ursprungliga referenstabellen, har alla satt `\\tabskip=0pt` så att $$\mathrm\TeX$$ inte lägger till något utrymme mellan våra kolumner: i praktiken vidrör de alla varandra. Anledningen till detta är att förenkla den inledande diskussionen och de efterföljande beräkningarna—senare i artikeln återinför vi glue-värden som inte är noll för att undersöka dess effekt på beräkningen av kolumnbredder för kolumner som spänner över flera kolumner. `\tabskip` glue för att undersöka dess effekt på beräkningen av kolumnbredder för kolumner som spänner över flera kolumner.

Som noterat i kommentarerna har vi lagt till en liten mängd blanktecken (5pt) i början av alla icke-överspännande tabellposter (utom första raden). Det där blanktecknet på 5pt utgör en del av den totala bredden för alla icke-överspännande poster (utom första raden) och lades till enbart för att tabellen skulle se något mindre rörig ut.

### En kort notis om tabellbredder

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

* `\\halign{...}`: sätt tabellen till den bredd som $$\mathrm\TeX$$ beräknar, baserat på posternas storlek (och `\tabskip` glue);
* `\\halign to *bredd* {...}`: instruera $$\mathrm\TeX$$ att sätta tabellen med en angiven `*bredd*`;
* `\\halign spread *mängd*{...}`: justera den beräknade bredden med `*mängd*`.

När $$\mathrm\TeX$$ sätter en tabell med hjälp av `\\halign{...}` den måste läsa in hela tabellen i minnet för att utföra de olika beräkningar som krävs för att sätta den. Följaktligen, om du inte har angett bredden med hjälp av `\\halign to *bredd* {...}` kan du inte känna till den slutliga bredden förrän $$\mathrm\TeX$$ har avslutat behandlingen (sättning) av den. Ett sätt att få bredden på en tabell som producerats av `\\halign{...}` är att först sätta tabellen inuti en `\vbox{...}` (t.ex., `\\setbox0=\\vbox{\\halign{...}}`) och sedan, till exempel, använda `\\the\\wd0` för att få fram bredden.

### Ingen automatisk radbrytning i tabellposter

Det är viktigt att notera att när $$\mathrm\TeX$$ sätter en tabell skapad med `\\halign{...}` som helst text inom tabellposter inte automatiskt blir föremål för radbrytning: tabellposter sätts i *begränsat horisontellt läge*—precis som en `\hbox`. För att aktivera radbrytning behöver texten i en tabellpost omslutas av en `\vbox{...}` tillsammans med att använda ett lämpligt värde för `\hsize` inom den `\vbox{...}`. Observera dock att text inom en `\\noalign{...}` kommando (en $$\mathrm\TeX$$ primitiv) som används i en `\\halign{...}` är föremål för $$\mathrm\TeX$$s radbrytning. I praktiken, och som namnet antyder, `\\noalign{...}` låter $$\mathrm\TeX$$ att ”fly” från `\\halign{...}` och placera material mellan raderna i tabellen—vanligtvis för att skapa horisontella linjer mellan tabellraderna.

### Inte tillåtet: \\\halign{...} inuti \\\hbox{...}

Du kan inte *direkt* sätta en `\\halign{...}` inuti en `\hbox{...}`. Att försöka använda `\\hbox{\\halign{...}}` kommer att generera ett ganska förvirrande fel:

```latex
! Missing } inserted.
<infogat text>
                }
<to be read again>
                   \halign
l.1 \\hbox{\\halign
```

#### En förklaring till detta fel

På grund av den omslutande `\hbox{...}` $$\mathrm\TeX$$ är i *begränsat horisontellt läge*; sedan upptäcker den `\\halign{...}` som är ett *vertikalt läge. Till exempel, om du använder* i ett stycke, `\\halign{...}` kommer att avsluta stycket, bearbeta $$\mathrm\TeX$$ och sedan fortsätta med resten av stycket. `\\halign{...}` När det används inuti en

utlöser `\hbox{...}`, den `\\halign{...}` för att försöka fly tillbaka till vertikalt läge genom att försöka tvinga fram stängning av den aktuella gruppen: $$\mathrm\TeX$$ rapporterar ett ” $$\mathrm\TeX$$ ! Missing }`” och ger ett fel eftersom den tror att du har gjort ett misstag i din användning av grupperingar. Även om en högerklammer (`) kanske inte saknas i din`}`kod, är felmeddelandet ett symptom på att $$\mathrm\TeX$$ ”står i vägen” och `\hbox{...}` gör sin ”bästa gissning” om lämplig åtgärd för att lösa problemet. $$\mathrm\TeX$$ gör sin ”bästa gissning” om lämplig åtgärd för att lösa problemet.

## Exempel på tabeller med kolumner som sträcker sig över flera kolumner

Följande serie tabellfigurer ger ett antal exempel som demonstrerar effekten av att spänna över tabellkolumner: vilket visar att långa tabellposter kan få oväntade resultat på bredden hos vissa kolumner—och därmed på tabellens bredd. Frågan vi ska ta itu med är vad $$\mathrm\TeX$$ gör när en viss tabellpost sträcker sig över ett antal kolumner men är ”för bred för att få plats”. Som nämnt ovan, $$\mathrm\TeX$$ använder faktiskt en specifik algoritm för detta problem med att beräkna kolumnbredder: följande exempel är utformade för att hjälpa till att utveckla en ”känsla” för hur den algoritmen fungerar.

### Exempeltabell 1

I detta exempel använder vi `\\multispan{2}` för att spänna över kolumnerna 1 och 2 med en post vars text är **En tabellrubrik**:

![{{{alt}}}](/files/6625b4068cf7144c6c04838fd94ae881d7995a9e)

#### Observationer

* Den här tabellens bredd är densamma som [referenstabellens](#reference-table): $$327.71722\text{pt}$$.
* Bredden på posten som spänner över kolumnerna 1 och 2 är $$81.04953\text{pt}$$ vilket är mindre än den totala bredden för posterna i de kolumner den spänner över: $$52.56676\text{pt} + 57.06679\text{pt} = 109.63355\text{pt}$$

## Exempeltabell 2

Som i [Exempeltabell 1](#example-table-1), använder detta exempel också `\\multispan{2}` för att spänna över kolumnerna 1 och 2 men här använder vi en längre post vars text är **En något längre tabellrubrik**.

![{{{alt}}}](/files/54abe8c8c7960ef0adbe229d9fd361c8b0f52444)

#### Observationer

Om du jämför detta exempel med vår [referenstabellens](#reference-table) kan vi se följande:

* Bredden på denna tabell har ökat från $$327.71722\text{pt}$$ till $$374.37032\text{pt}$$: totalt $$46.6531\text{pt}$$.
* Bredden på posten som spänner över kolumnerna 1 och 2 ($$156.28664\text{pt}$$) är större än den totala bredden för posterna i de kolumner den spänner över: $$52.56676\text{pt} + 57.06679\text{pt} = 109.63355\text{pt}$$. Den skillnaden är $$156.28664\text{pt}-109.63355\text{pt} = 46.6531\text{pt}$$ vilket är samma belopp som tabellens bredd har ökat med.
* $$\mathrm\TeX$$ har justerat bredden på kolumn 2 för att ge det extra utrymme som behövs. Senare kommer vi att se hur $$\mathrm\TeX$$ beräknar det belopp med vilket kolumn 2 måste öka.
* Kolumn 1 påverkas inte: dess bredd har inte påverkats av posten som spänner över kolumnerna 1 och 2.

### Exempeltabell 3

I detta exempel använder vi `\\multispan{3}` för att spänna över kolumnerna 1 till 3 med en post vars text är densamma som [Exempeltabell 2](#example-table-2): **En något längre tabellrubrik**.

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

#### Observationer

* Den här tabellens bredd är densamma som [referenstabellens](#reference-table): $$327.71722\text{pt}$$.
* Bredden på posten som spänner över kolumnerna 1 till 3 ($$156.28664\text{pt}$$) är mindre än den totala bredden för posterna i de tre kolumner den spänner över: $$52.56676\text{pt} + 57.06679\text{pt} + 59.03899\text{pt} = 168.67254\text{pt}$$.
* Ingen av kolumnbredderna har påverkats av posten som spänner över kolumnerna 1 till 3.

Börjar du se ett mönster växa fram?

### Exempeltabell 4

Som med [Exempeltabell 3](#example-table-3), använder vi här `\\multispan{3}` för att spänna över kolumnerna 1 till 3 men den här gången med en post vars text är betydligt längre: **En betydligt längre tabellrubrik som sträcker sig långt**.

![{{{alt}}}](/files/14e6ff22e78412dc286c1dc34615ae95df1d6a29)

#### Observationer

* Jämfört med [referenstabellens](#reference-table), har bredden på denna tabell ökat från $$327.71722\text{pt}$$ till $$465.95685\text{pt}$$: en ökning med $$138.23963\text{pt}$$.
* Bredden på posten som spänner över kolumnerna 1 till 3 är $$306.91216\text{pt}$$.
* Den totala bredden för posterna i de tre spända kolumnerna är $$52.56676\text{pt} + 57.06679\text{pt} + 59.03899\text{pt} = 168.67254\text{pt}$$.
* Skillnaden i bredd mellan den långa posten som sträcker sig över flera kolumner och posterna i kolumnerna 1 till 3 är $$306.91216\text{pt}-168.67254\text{pt}=138.23962\text{pt}$$. Samma belopp (avrundat till 4 decimaler!) som tabellens bredd har ökat med.
* Endast kolumn 3 har fått ökad bredd: varken kolumn 1 eller kolumn 2 påverkas.

#### Ett mönster framträder

Om vi tittar på [Exempeltabell 2](#example-table-2) och [Exempeltabell 4](#example-table-4) kan vi se att det i båda fallen är den **sista kolumnen i spannet** vars bredd ökades för att ge plats åt den långa post som spände över kolumnerna:

* I [Exempeltabell 2](#example-table-2): Den långa posten spände över kolumnerna 1 och 2. Kolumn 2 blev ”utsträckt”.
* I [Exempeltabell 4](#example-table-4): Den långa posten spände över kolumnerna 1 till 3. Kolumn 3 blev ”utsträckt”.

#### Bredden på kolumn 3: Framträder en algoritm?

Följande beräkningar ger en tydligare indikation på vad $$\mathrm\TeX$$ gör. Här är vad vi vet:

* Bredden på den långa posten som spänner över kolumnerna 1 till 3 är $$306.91216\text{pt}$$.
* Den totala bredden för posterna i kolumnerna 1 och 2 är $$52.56676\text{pt} + 57.06679\text{pt} = 109.63355\text{pt}$$.

Vad är skillnaden mellan dessa värden? Den är $$306.91216\text{pt}-109.63355\text{pt} = 197.2786\text{pt}$$ och detta är den bredd som används för kolumn 3: den uppstår direkt ur den algoritm som används av $$\mathrm\TeX$$.

### Exempeltabell 5

Innan vi kommer till ett mer komplicerat exempel, här är ytterligare ett ”enkelt” exempel. Denna tabell innehåller samma långa post som [Exempeltabell 4](#example-table-4): **En betydligt längre tabellrubrik som sträcker sig långt**; dock använder vi den här gången `\\multispan{6}` vilket gör att den posten kan spänna över hela tabellen. Som du kan se har den resulterande tabellen fortfarande samma bredd som vår [referenstabellens](#reference-table) ($$327.71722\text{pt}$$) vilket innebär att inga kolumner har påverkats av denna mycket långa post. Uppenbarligen beror detta på att bredden på posten ($$306.91216\text{pt}$$) är mindre än den totala bredden för alla poster den spänner över: $$327.71722\text{pt}$$; dvs. tabellens bredd.

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

### Exempeltabell 6: Något mer komplicerad

Här tittar vi på en serie av tre exempeltabeller (6(a)–6(c)) för att visa effekten av två olika poster som båda sträcker sig in i kolumn 5. [Exempeltabell 6(a)](#example-table-6a) och [Exempeltabell 6(b)](#example-table-6b) visar båda en tabell som innehåller en enda post som sträcker sig över flera kolumner upp till kolumn 5. [Exempeltabell 6(c)](#example-table-6c) kombinerar båda dessa spännande poster i en enda tabell och ställer frågan: vilken post avgör faktiskt bredden på kolumn 5, och varför? Svaret för oss till kärnan i algoritmen som används av $$\mathrm\TeX$$.

#### Exempeltabell 6(a)

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

**Observationer**

* Jämfört med [referenstabellens](#reference-table), har bredden på denna tabell ökat från $$327.71722\text{pt}$$ till $$371.11153\text{pt}$$: en ökning med $$43.39431\text{pt}$$.
* Bredden på posten som spänner över kolumnerna 3 till 5 är $$215.06683\text{pt}$$.
* Den totala bredden för posterna i kolumnerna 3 till 5 är $$59.03899\text{pt} + 52.98344\text{pt} + 59.6501\text{pt} = 171.67253\text{pt}$$.
* Skillnaden i bredd mellan posterna som spänner över kolumnerna 3 till 5 och bredden på spänningsposten är $$215.06683\text{pt}-171.67253\text{pt}=43.3943\text{pt}$$: det exakta beloppet (avrundat till 4 decimaler!) med vilket tabellens bredd har ökat.

#### Exempeltabell 6(b)

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

**Observationer**

* Jämfört med [referenstabellens](#reference-table), har bredden på denna tabell ökat från $$327.71722\text{pt}$$ till $$353.3233\text{pt}$$: en ökning med $$25.60608\text{pt}$$.
* Bredden på posten som spänner över kolumnerna 1 till 5 är $$306.91216\text{pt}$$.
* Den totala bredden för posterna i kolumnerna 1 till 5 är $$52.56676\text{pt} + 57.06679\text{pt} + 59.03899\text{pt} + 52.98344\text{pt} + 59.6501\text{pt} = 281.30608\text{pt}$$.
* Skillnaden i bredd mellan posterna som spänner över kolumnerna 1 till 5 och bredden på spänningsposten är $$306.91216\text{pt}-281.30608\text{pt}=25.60608\text{pt}$$: **note** detta är *mindre* än värdet som beräknades för [Exempel 6(a)](#example-table-6a), som var $$43.3943\text{pt}$$.

#### Exempeltabell 6(c)

Här kombinerar vi posterna i exempeltabellerna [6(a)](#example-table-6a) och [6(b)](#example-table-6b) i en enda tabell: vad händer?

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

**Observation**

* Jämfört med [referenstabellens](#reference-table), har bredden på denna tabell ökat från $$327.71722\text{pt}$$ till $$371.11153\text{pt}$$: en ökning med $$43.39431\text{pt}$$. Vi noterar att detta är exakt samma som [Exempeltabell 6(a)](#example-table-6a).

#### Vad gör $$\mathrm\TeX$$ ?

För att förstå resultaten av $$\mathrm\TeX$$s algoritm och beslutsprocesser noterar vi att denna post

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

sträcker sig bortom de poster som spänns över av $$25.60608\text{pt}$$; dock sträcker sig denna post

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

ännu längre bortom de poster som spänns över: med $$43.3943\text{pt}$$. Därför ”vinner” den posten loppet och kolumn 5 får sin bredd ökad med det **maximala** av dessa två värden ($$43.3943\text{pt}$$). Kolumn 5:s bredd blir nu $$59.6501\text{pt} + 43.3943\text{pt} = 103.0444\text{pt}$$ för att rymma den post som spänner över kolumnerna 3 till 5. Vår beskrivning av den exakta ”sekvensen av händelser” är något förenklad men utfallet är som vi har beskrivit.

## Att återinföra lite komplexitet

För att minimera komplexiteten i våra diskussioner (hittills) har vi använt relativt enkla exempel för att visa principerna i $$\mathrm\TeX$$s algoritm; särskilt satte vi `\\tabskip=0pt`. I praktiken har tabeller i ”verkligheten” sannolikt många poster som spänner över ett antal kolumner och kommer naturligtvis att ha icke-nollvärden för `\tabskip` glue—ett ämne vi nu återkommer till.

### \\\tabskip glue och bredden på kolumner som spänner över flera kolumner

Tabellutformning kräver ofta att man lägger till blankutrymme mellan kolumner och naturligtvis $$\mathrm\TeX$$ har denna funktion genom ett primitivt kommando kallat `\tabskip`. Detta kommando kan användas för att lägga in fast eller flexibel glue (mellanrum):

* före en tabell (dvs. till vänster om kolumn 1);
* mellan en eller flera kolumner;
* efter tabellen (dvs. till höger om den sista kolumnen).

Här är ett exempel som påminner oss:

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

### Hur påverkar \\\tabskip glue bredderna på kolumner som spänner över flera kolumner?

Förekomsten av icke-noll `\tabskip` glue mellan kolumnerna ger extra utrymme som spännande poster kan ”absorbera” innan $$\mathrm\TeX$$ behöver börja tänka på att öka bredden på den sista kolumnen i ett spann.

I vårt nästa exempel kommer vi att använda två tabeller för att jämföra resultaten av att spänna över två kolumner. Den enda skillnaden mellan tabellerna är användningen av `\tabskip` glue.

* Det första exemplet använder vår ursprungliga ”referenstabell” som, om du minns, har satt `\\tabskip=0pt`.
* Det andra exemplet använder en modifierad version av vår [referenstabellens](#reference-table) (kommenterad ovan) som har `\\tabskip=10pt` före och efter tabellen men, viktigare, har satt `\\tabskip=20pt` mellan kolumnerna.

Inom den *modifierade* referenstabellen har de två spända kolumnerna ingen effekt på kolumnbredderna (och tabellbredden) men de påverkar bredden på kolumn 2 (och tabellbredden) i den *ursprungliga* [referenstabellens](#reference-table).

### Ursprunglig referenstabell: \\\tabskip=0pt

Här visar vi vår ursprungliga [referenstabellens](#reference-table) tillsammans med en andra tabell (härledd från vår ursprungliga [referenstabellens](#reference-table)) som har en post ”**Testa en längre tabellrubrik**” som spänner över kolumnerna 1 och 2. Det är helt tydligt att kolumn 2 (i den andra tabellen i diagrammet) och därmed hela tabellen, båda påverkas av kolumnerna som spänner över flera kolumner.

![{{{alt}}}](/files/44c78a11843690af3bc042b65cb31590f3a5dbbb)

### Modifierad referenstabell: \\\tabskip=20pt

Här visar vi vår modifierade referenstabell tillsammans med en andra tabell (härledd från vår modifierade referenstabell) som också har en post ”**Testa en längre tabellrubrik**” som spänner över kolumnerna 1 och 2. Det är helt tydligt att inom den andra tabellen i diagrammet påverkas varken bredden på kolumn 2 eller tabellen av kolumner som spänner över flera kolumner. I detta fall har förekomsten av `\tabskip` glue (`20pt`) mellan kolumnerna hjälpt till att ”absorbera” det utrymme som behövs av texten i posten som spänner över kolumnerna 1 och 2:

![{{{alt}}}](/files/29529ee34fa6995f127610cc707e246e25265544)

## Kärnan i $$\mathrm\TeX$$s algoritm

Förhoppningsvis har det spann av exempel som getts ovan hjälpt till att utveckla en ”känsla” för vad $$\mathrm\TeX$$ gör för att rymma poster som spänner över flera kolumner och hur $$\mathrm\TeX$$ vid behov kommer att justera bredden på den **sista** kolumnen inom varje intervall av kolumner som spänner över flera kolumner. Utöver bredden på posterna inom enskilda kolumner som spänns över, är förekomsten av icke-noll `\tabskip` glue en viktig faktor som $$\mathrm\TeX$$ tar hänsyn till när den avgör om den behöver justera några kolumnbredder. Nyckelpunkten att komma ihåg är att $$\mathrm\TeX$$s mål är att beräkna en lämplig bredd för den **sista kolumnen** inom varje intervall av kolumner som omfattas.

### Slutligt tabellexempel: sista kolumner i ett spann av kolumner

I detta slutliga exempel använder vi åter vår modifierade referenstabell (med `\tabskip` gluevärdena som diskuterats ovan) för att härleda en annan tabell som innehåller olika kolumner som spänns över av linjer — vi har använt linjer för att göra spannen lättare att se.

De två tabellerna har noggrant justerats för att visa att inga kolumner före kolumn 5 har påverkats av de kolumner som omfattas av spann. Det mörkare gröna området till vänster i diagrammet visar att kolumnerna 1 till 4 i båda tabellerna fortfarande ligger exakt i linje. Till höger finns ett ljusare grönt skuggat område som visar att endast kolumnerna 5 och 6 har påverkats av de poster som omfattas av spann.

I den övre tabellen ser spannen ut så här:

* kolumnerna 1 till 5: spända av en $$400\text{pt}$$ linje;
* kolumnerna 3 till 5: spända av en $$200\text{pt}$$ linje;
* kolumnerna 4 till 6: spända av en $$250\text{pt}$$ linje.

![{{{alt}}}](/files/67b815107f646008f0273ad1a6fbdc163fc3e592)

Återigen är förklaringen att inom en serie av kolumner som omfattas av spann justeras endast bredden på den sista kolumnen (om det behövs): mellanliggande kolumner påverkas inte och här betyder det kolumnerna 1 till 4 — även om naturligtvis bredden hos kolumnerna 1 till 4 (och mellanliggande `\tabskip` glue) beaktas när de justerade bredderna för kolumnerna 5 och 6 beräknas.

### En genomgång av $$\mathrm\TeX$$s algoritm

Vi avslutar med en *förenklad* genomgång av “$$\mathrm\TeX$$’s tankegångar” när den arbetar sig fram till kolumnbredderna i poster som omfattas av spann. Att beskriva $$\mathrm\TeX$$’s algoritmer är inte alltid okomplicerade så vi kommer att tillämpa lite “förenklad konstnärlig frihet” för att ge en överblick av vad som händer. Läsare som är intresserade av alla de röriga detaljerna hänvisas till avsnitt 801 (sida 336) i den tryckta bok som innehåller $$\mathrm\TeX$$s källkod [$$\mathrm\TeX\text{: The Program}$$](https://www.amazon.co.uk/Computers-Typesetting-Tex-Program-TEX/dp/0201134373).

Tabeller i verkliga världen skapas ofta med många användningar av `\span` primitivet (t.ex. inuti $$\mathrm\LaTeX$$ paket) för att konstruera flera instanser av kolumnspann inom tabellen. För att hantera detta upprätthåller datastrukturerna (djupt inne i $$\mathrm\TeX$$) information (så kallade *spannnoder*) som berättar $$\mathrm\TeX$$ för $$\mathrm\TeX$$ om länkarna (spannen) mellan tabellposter/kolumner. Tydligt nog måste $$\mathrm\TeX$$ tillämpa sina algoritmer på ett systematiskt sätt och behöver bearbeta hela tabellen för att göra sina slutliga beräkningar — för att bestämma alla kolumnbredder, tabellens totala bredd och, om det krävs, hur mycket de flexibla glue-värden som används i tabellen måste sträckas eller krympas. Det är egentligen inte förvånande att `\\halign{...}` inte kan tala om den slutliga tabellbredden förrän den helt har bearbetat

kommandot — den har verkligen mycket arbete att göra! *över/in i*kolumn 1. $$\mathrm\TeX$$ börjar med att bestämma bredden på kolumn 1 genom att fastställa vilken post som har den största *naturliga bredden*. Låt oss kalla den maximala bredden $$w\_1$$och om det finns poster som sträcker sig från kolumn 1 till kolumn 2 låt oss kalla bredden för den posten $$w\_{12}$$ (bredd från 1 till 2). Dessutom betecknar vi `\tabskip` glue mellan kolumnerna 1 och 2 som $$t\_{1}$$—notera att vi endast betraktar *naturliga bredden* hos det `\tabskip` glue och, för tillfället, bortser från eventuella stretch- eller shrink-komponenter den kan ha. Låt också den maximala naturliga bredden hos alla icke-spännande poster i kolumn 2 vara $$w\_2$$.

Det viktiga att notera är att $$\mathrm\TeX$$ försöker beräkna bredden på kolumn 2 genom att endast betrakta de poster där spannet *börjar* med kolumn 1 och *slutar* vid kolumn 2. Den viktigaste faktorn för $$\mathrm\TeX$$ är testet $$\max(w\_{2}, w\_{12} - (w\_1+ t\_1))$$—det kan finnas flera poster som sträcker sig över kolumnerna 1 och 2: vissa kan vara smala (liten $$w\_{12}$$), andra mycket breda (stor $$w\_{12}$$) så $$\mathrm\TeX$$ letar efter den som har störst effekt (därav $$\max(\text{...})$$). Här är värdet av $$w\_{12} -(w\_1+ t\_1)$$ den mängd med vilken en post som sträcker sig över kolumnerna 1 och 2 “svämmar över” från kolumn 1 in i kolumn 2: notera att $$\mathrm\TeX$$ använder bredden på kolumn 1 **och** den `\tabskip` glue ($$t\_{1}$$) mellan kolumnerna 1 och 2. När $$\mathrm\TeX$$ har fastställt om några spann från kolumn 1 till 2 faktiskt påverkar bredden på kolumn 2, sätter den bredden på kolumn 2 till det maximala värde den har fastställt (med hjälp av det test som beskrivs). $$\mathrm\TeX$$ fortsätter att arbeta sig igenom alla de andra kolumnerna och utför liknande tester.

Och slutligen, bara för fullständighetens skull, citerar vi här kärnan i $$\mathrm\TeX$$s algoritm för att beräkna kolumnbredder (hämtad från Knuths källkodsokumentation för $$\mathrm\TeX$$):

Låt $$w\_{ij}$$ vara maximum av de naturliga bredderna för alla poster som sträcker sig över kolumner $$i$$ till $$j$$, inklusive. De slutliga kolumnbredderna definieras av formeln

$$\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\*}$$

där $$t\_k$$ är den naturliga bredden hos tabskip-glue mellan kolumner $$k$$ och $$k+1$$.

## Kolofon: Att använda Overleaf för att skapa tabeller som SVG-grafik

Alla $$\mathrm\TeX$$ tabeller som presenteras i denna artikel är skalbar vektorgrafik (SVG)-filer som producerats på Overleaf-plattformen. Anteckningarna (pilarna och de gröna rutorna) lades till genom att öppna SVG-grafiken i Inkscape—observera dock att texten i anteckningarna sattes i $$\mathrm\TeX$$ som ytterligare text som följer tabellen: endast pilarna och de gröna bakgrunderna lades till i Inkscape. Om du är intresserad av att veta hur detta gick till, läs vidare.

Overleafs servrar använder $$\mathrm\TeX \text{ Live}$$ distributionen som, förutom $$\mathrm\TeX$$-baserade sättningsmotorer, tillhandahåller en mängd mycket användbara $$\mathrm\TeX$$-relaterade programvaruverktyg och hjälpprogram. Bland dem finns ett som heter [`dvisvgm`](https://dvisvgm.de) som, som namnet antyder, konverterar $$\mathrm\TeX$$s traditionella DVI (**D**e**V**is **I**oberoende) utdatafilformat till SVG. Bland dess många [kommandoradsalternativ](https://dvisvgm.de/Manpage/) `dvisvgm` erbjuder ett alternativ (`-n` eller `--no-fonts`) som instruerar det att konvertera all text till *banor* vilket betyder att texten i SVG-grafik ritas med linjer och kurvor i stället för faktiska typsnitt och glyfer. Detta kan öka filstorleken på den resulterande SVG-grafiken men säkerställer att SVG-grafiken är extremt portabel och nästan säkert fungerar bra på alla enheter.

### Så... hur gjordes det?

I en [tidigare artikel](https://www.overleaf.com/blog/510-using-luatex-to-run-tools-and-utilities-installed-on-overleafs-servers) diskuterade jag hur du kan använda $$\text{Lua}\mathrm\TeX$$ för att köra de olika programvaruverktyg och hjälpprogram som är installerade på Overleafs servrar — det är en extremt enkel och bekväm teknik. Den tekniken användes för att generera SVG-grafik av satta $$\mathrm\TeX$$ tabeller, enligt följande. Från huvud- $$\mathrm\TeX$$ dokumentfilen skrevs koden för att sätta varje tabell (skapad med `\halign`) till en `.tex` fil. Detta åstadkoms genom att omsluta tabellkoden inom ett par kommandon som jag kallade `\beginscoop` och `\endscoop`. Det finns sannolikt många andra sätt att uppnå önskat resultat, men här är de makrodefinitioner som jag använde:

```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 använder dem så här:

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

Observera att `\endscoop` tokenet fungerar bara som avgränsare för parametern till `\scoop` makrot: $$\mathrm\TeX$$ faktiskt kastar bort `\endscoop` tokenet så vi behöver egentligen inte definiera det (t.ex. genom `\def\endscoop{...}`).

Den $$\mathrm\TeX$$ kod som finns i `\\halign{...}` sparas i en `toks` register som kallas `\fulltoks`. En knepig sak jag stötte på (med $$\text{Lua}\mathrm\TeX$$) var behovet att förhindra att `#` tecken inom `\\halign{...}` preambeln “dubblades” till `##` när de skrevs ut till en `.tex` fil. För att undvika detta var jag tvungen att tillfälligt sätta `\\catcode`för `#` tecknen till 12 innan jag sparade $$\mathrm\TeX$$ koden (token) i `\fulltoks` tokenregistret.

Nästa steg är att skriva de token som finns i `\fulltoks` som en $$\mathrm\TeX$$ fil — eftersom jag använde $$\text{Lua}\mathrm\TeX$$ detta visade sig vara *extremt* enkelt tack vare $$\text{Lua}\mathrm\TeX$$s underbara Lua-API. Kort sagt skrev jag ett makro kallat `\writefile{...}` som tar som parameter namnet på ett tokenregister vars token du vill skriva ut till en fil (t.ex. `\writefile{fulltoks}`). Inom `\writefile{...}` makrot använde jag Lua-API:t för att få en textuell representation av `\fulltoks` tokenregistret:

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

Här är en skärmdump som visar lite mer av `\writefile{...}` kommandot:

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

Lua-språket och Lua-API:t som tillhandahålls av $$\text{Lua}\mathrm\TeX$$ kan ofta förenkla $$\mathrm\TeX$$ programmeringsuppgifter och det är tack vare dessa användbara och kraftfulla funktioner som jag har använt $$\text{Lua}\mathrm\TeX$$ sedan omkring 2009 — och förblir ett stort fan av denna verkligen fantastiska $$\mathrm\TeX$$ motor. Okej, reklamen $$\text{Lua}\mathrm\TeX$$ är nu avslutad.

Efter att så enkelt ha fått $$\mathrm\TeX$$ koden lagrad i `\fulltoks` den skrivs ut till en fil tillsammans med en del ytterligare kod för att göra den till en korrekt formad $$\mathrm\LaTeX$$ fil. Nästa steg är:

1. Bearbeta `.tex` filen som innehåller vår tabell med $$\text{pdf}\mathrm\LaTeX$$ (i DVI-läge) så att den sätter tabellen och genererar en `.dvi` fil för `dvisvgm` att bearbeta. Ja, du kan använda $$\text{Lua}\mathrm\TeX$$ för att köra $$\text{pdf}\mathrm\LaTeX$$—återigen använde jag metoden som diskuterades i en [tidigare artikel](/latex/sv/fordjupade-artiklar/52-using-luatex-to-run-tools-and-utilities-installed-on-overleaf-s-servers.md).
2. Och slutligen, kör `dvisvgm` för att bearbeta `.dvi` filen för att generera en SVG-grafik av den satta $$\mathrm\TeX$$ tabellen.
3. För att få själva SVG-grafiken kan du ladda ner en ZIP-fil från Overleaf—se till att välja **In- och utdatafiler** 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/sv/fordjupade-artiklar/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.
