{"route":"/en-US-v0.13.1/reference/context/","title":"Context","description":"How to deal with content that reacts to its location in the document.\n","part":null,"outline":[{"id":"style-context","name":"Style context","children":[]},{"id":"location-context","name":"Location context","children":[]},{"id":"nested-contexts","name":"Nested contexts","children":[]},{"id":"compiler-iterations","name":"Compiler iterations","children":[]}],"body":{"kind":"html","content":"<h1>Context</h1>\n<p>Sometimes, we want to create content that reacts to its location in the\ndocument. This could be a localized phrase that depends on the configured text\nlanguage or something as simple as a heading number which prints the right\nvalue based on how many headings came before it. However, Typst code isn't\ndirectly aware of its location in the document. Some code at the beginning of\nthe source text could yield content that ends up at the back of the document.</p>\n<p>To produce content that is reactive to its surroundings, we must thus\nspecifically instruct Typst: We do this with the <code><span class=\"typ-key\">context</span></code> keyword, which\nprecedes an expression and ensures that it is computed with knowledge of its\nenvironment. In return, the context expression itself ends up opaque. We cannot\ndirectly access whatever results from it in our code, precisely because it is\ncontextual: There is no one correct result, there may be multiple results in\ndifferent places of the document. For this reason, everything that depends on\nthe contextual data must happen inside of the context expression.</p>\n<p>Aside from explicit context expressions, context is also established implicitly\nin some places that are also aware of their location in the document:\n<a href=\"/en-US-v0.13.1/reference/styling/#show-rules\">Show rules</a> provide context<sup class=\"footnote-reference\"><a href=\"#1\">1</a></sup> and numberings in the\noutline, for instance, also provide the proper context to resolve counters.</p>\n<h2 id=\"style-context\">Style context</h2>\n<p>With set rules, we can adjust style properties for parts or the whole of our\ndocument. We cannot access these without a known context, as they may change\nthroughout the course of the document. When context is available, we can\nretrieve them simply by accessing them as fields on the respective element\nfunction.</p>\n<div class=\"previewed-code\"><pre><code><span class=\"typ-key\">#</span><span class=\"typ-key\">set</span> <span class=\"typ-func\">text</span><span class=\"typ-punct\">(</span>lang<span class=\"typ-punct\">:</span> <span class=\"typ-str\">&quot;de&quot;</span><span class=\"typ-punct\">)</span>\n<span class=\"typ-key\">#</span><span class=\"typ-key\">context</span> text<span class=\"typ-punct\">.</span>lang\n</code></pre><div class=\"preview\"><img src=\"/en-US-v0.13.1/assets/1137ad51a48ad89d691e97514545b36a.png\" alt=\"Preview\"></div></div>\n<p>As explained above, a context expression is reactive to the different\nenvironments it is placed into. In the example below, we create a single context\nexpression, store it in the <code>value</code> variable and use it multiple times. Each use\nproperly reacts to the current surroundings.</p>\n<div class=\"previewed-code\"><pre><code><span class=\"typ-key\">#</span><span class=\"typ-key\">let</span> value <span class=\"typ-op\">=</span> <span class=\"typ-key\">context</span> text<span class=\"typ-punct\">.</span>lang\n<span class=\"typ-pol\">#</span><span class=\"typ-pol\">value</span>\n\n<span class=\"typ-key\">#</span><span class=\"typ-key\">set</span> <span class=\"typ-func\">text</span><span class=\"typ-punct\">(</span>lang<span class=\"typ-punct\">:</span> <span class=\"typ-str\">&quot;de&quot;</span><span class=\"typ-punct\">)</span>\n<span class=\"typ-pol\">#</span><span class=\"typ-pol\">value</span>\n\n<span class=\"typ-key\">#</span><span class=\"typ-key\">set</span> <span class=\"typ-func\">text</span><span class=\"typ-punct\">(</span>lang<span class=\"typ-punct\">:</span> <span class=\"typ-str\">&quot;fr&quot;</span><span class=\"typ-punct\">)</span>\n<span class=\"typ-pol\">#</span><span class=\"typ-pol\">value</span>\n</code></pre><div class=\"preview\"><img src=\"/en-US-v0.13.1/assets/7142666b497eed6d8f9b4b5710a2668c.png\" alt=\"Preview\"></div></div>\n<p>Crucially, upon creation, <code>value</code> becomes opaque <a href=\"/en-US-v0.13.1/reference/foundations/content/\" title=\"content\">content</a> that we cannot peek\ninto. It can only be resolved when placed somewhere because only then the\ncontext is known. The body of a context expression may be evaluated zero, one,\nor multiple times, depending on how many different places it is put into.</p>\n<h2 id=\"location-context\">Location context</h2>\n<p>We've already seen that context gives us access to set rule values. But it can\ndo more: It also lets us know <em>where</em> in the document we currently are, relative\nto other elements, and absolutely on the pages. We can use this information to\ncreate very flexible interactions between different document parts. This\nunderpins features like heading numbering, the table of contents, or page\nheaders dependent on section headings.</p>\n<p>Some functions like <a href=\"/en-US-v0.13.1/reference/introspection/counter/#definitions-get\"><code>counter.get</code></a> implicitly access the current\nlocation. In the example below, we want to retrieve the value of the heading\ncounter. Since it changes throughout the document, we need to first enter a\ncontext expression. Then, we use <code>get</code> to retrieve the counter's current value.\nThis function accesses the current location from the context to resolve the\ncounter value. Counters have multiple levels and <code>get</code> returns an array with the\nresolved numbers. Thus, we get the following result:</p>\n<div class=\"previewed-code\"><pre><code><span class=\"typ-key\">#</span><span class=\"typ-key\">set</span> <span class=\"typ-func\">heading</span><span class=\"typ-punct\">(</span>numbering<span class=\"typ-punct\">:</span> <span class=\"typ-str\">&quot;1.&quot;</span><span class=\"typ-punct\">)</span>\n\n<span class=\"typ-heading\">= Introduction</span>\n<span class=\"typ-func\">#</span><span class=\"typ-func\">lorem</span><span class=\"typ-punct\">(</span><span class=\"typ-num\">5</span><span class=\"typ-punct\">)</span>\n\n<span class=\"typ-key\">#</span><span class=\"typ-key\">context</span> <span class=\"typ-func\">counter</span><span class=\"typ-punct\">(</span>heading<span class=\"typ-punct\">)</span><span class=\"typ-punct\">.</span><span class=\"typ-func\">get</span><span class=\"typ-punct\">(</span><span class=\"typ-punct\">)</span>\n\n<span class=\"typ-heading\">= Background</span>\n<span class=\"typ-func\">#</span><span class=\"typ-func\">lorem</span><span class=\"typ-punct\">(</span><span class=\"typ-num\">5</span><span class=\"typ-punct\">)</span>\n\n<span class=\"typ-key\">#</span><span class=\"typ-key\">context</span> <span class=\"typ-func\">counter</span><span class=\"typ-punct\">(</span>heading<span class=\"typ-punct\">)</span><span class=\"typ-punct\">.</span><span class=\"typ-func\">get</span><span class=\"typ-punct\">(</span><span class=\"typ-punct\">)</span>\n</code></pre><div class=\"preview\"><img src=\"/en-US-v0.13.1/assets/6d038d5175695d636eb9410eacbb33a5.png\" alt=\"Preview\"></div></div>\n<p>For more flexibility, we can also use the <a href=\"/en-US-v0.13.1/reference/introspection/here/\" title=\"`here`\"><code>here</code></a> function to directly extract\nthe current <a href=\"/en-US-v0.13.1/reference/introspection/location/\" title=\"location\">location</a> from the context. The example below\ndemonstrates this:</p>\n<ul>\n<li>We first have <code><span class=\"typ-func\">counter</span><span class=\"typ-punct\">(</span>heading<span class=\"typ-punct\">)</span><span class=\"typ-punct\">.</span><span class=\"typ-func\">get</span><span class=\"typ-punct\">(</span><span class=\"typ-punct\">)</span></code>, which resolves to <code><span class=\"typ-punct\">(</span><span class=\"typ-num\">2</span><span class=\"typ-punct\">,</span><span class=\"typ-punct\">)</span></code> as\nbefore.</li>\n<li>We then use the more powerful  <a href=\"/en-US-v0.13.1/reference/introspection/counter/#definitions-at\" title=\"`counter.at`\"><code>counter.at</code></a> with <a href=\"/en-US-v0.13.1/reference/introspection/here/\" title=\"`here`\"><code>here</code></a>, which in\ncombination is equivalent to <code>get</code>, and thus get <code><span class=\"typ-punct\">(</span><span class=\"typ-num\">2</span><span class=\"typ-punct\">,</span><span class=\"typ-punct\">)</span></code>.</li>\n<li>Finally, we use <code>at</code> with a <a href=\"/en-US-v0.13.1/reference/foundations/label/\" title=\"label\">label</a> to retrieve the value of the counter at a\n<em>different</em> location in the document, in our case that of the introduction\nheading. This yields <code><span class=\"typ-punct\">(</span><span class=\"typ-num\">1</span><span class=\"typ-punct\">,</span><span class=\"typ-punct\">)</span></code>. Typst's context system gives us time travel\nabilities and lets us retrieve the values of any counters and states at <em>any</em>\nlocation in the document.</li>\n</ul>\n<div class=\"previewed-code\"><pre><code><span class=\"typ-key\">#</span><span class=\"typ-key\">set</span> <span class=\"typ-func\">heading</span><span class=\"typ-punct\">(</span>numbering<span class=\"typ-punct\">:</span> <span class=\"typ-str\">&quot;1.&quot;</span><span class=\"typ-punct\">)</span>\n\n<span class=\"typ-heading\">= Introduction</span> <span class=\"typ-label\">&lt;intro&gt;</span>\n<span class=\"typ-func\">#</span><span class=\"typ-func\">lorem</span><span class=\"typ-punct\">(</span><span class=\"typ-num\">5</span><span class=\"typ-punct\">)</span>\n\n<span class=\"typ-heading\">= Background</span> <span class=\"typ-label\">&lt;back&gt;</span>\n<span class=\"typ-func\">#</span><span class=\"typ-func\">lorem</span><span class=\"typ-punct\">(</span><span class=\"typ-num\">5</span><span class=\"typ-punct\">)</span>\n\n<span class=\"typ-key\">#</span><span class=\"typ-key\">context</span> <span class=\"typ-punct\">[</span>\n  <span class=\"typ-func\">#</span><span class=\"typ-func\">counter</span><span class=\"typ-punct\">(</span>heading<span class=\"typ-punct\">)</span><span class=\"typ-punct\">.</span><span class=\"typ-func\">get</span><span class=\"typ-punct\">(</span><span class=\"typ-punct\">)</span> <span class=\"typ-escape\">\\</span>\n  <span class=\"typ-func\">#</span><span class=\"typ-func\">counter</span><span class=\"typ-punct\">(</span>heading<span class=\"typ-punct\">)</span><span class=\"typ-punct\">.</span><span class=\"typ-func\">at</span><span class=\"typ-punct\">(</span><span class=\"typ-func\">here</span><span class=\"typ-punct\">(</span><span class=\"typ-punct\">)</span><span class=\"typ-punct\">)</span> <span class=\"typ-escape\">\\</span>\n  <span class=\"typ-func\">#</span><span class=\"typ-func\">counter</span><span class=\"typ-punct\">(</span>heading<span class=\"typ-punct\">)</span><span class=\"typ-punct\">.</span><span class=\"typ-func\">at</span><span class=\"typ-punct\">(</span><span class=\"typ-label\">&lt;intro&gt;</span><span class=\"typ-punct\">)</span>\n<span class=\"typ-punct\">]</span>\n</code></pre><div class=\"preview\"><img src=\"/en-US-v0.13.1/assets/822a7dba085e89a6327630048f6fe36e.png\" alt=\"Preview\"></div></div>\n<p>As mentioned before, we can also use context to get the physical position of\nelements on the pages. We do this with the <a href=\"/en-US-v0.13.1/reference/introspection/locate/\" title=\"`locate`\"><code>locate</code></a> function, which works\nsimilarly to <code>counter.at</code>: It takes a location or other <a href=\"/en-US-v0.13.1/reference/foundations/selector/\" title=\"selector\">selector</a> that resolves\nto a unique element (could also be a label) and returns the position on the\npages for that element.</p>\n<div class=\"previewed-code\"><pre><code>Background is at: <span class=\"typ-escape\">\\</span>\n<span class=\"typ-key\">#</span><span class=\"typ-key\">context</span> <span class=\"typ-func\">locate</span><span class=\"typ-punct\">(</span><span class=\"typ-label\">&lt;back&gt;</span><span class=\"typ-punct\">)</span><span class=\"typ-punct\">.</span><span class=\"typ-func\">position</span><span class=\"typ-punct\">(</span><span class=\"typ-punct\">)</span>\n\n<span class=\"typ-heading\">= Introduction</span> <span class=\"typ-label\">&lt;intro&gt;</span>\n<span class=\"typ-func\">#</span><span class=\"typ-func\">lorem</span><span class=\"typ-punct\">(</span><span class=\"typ-num\">5</span><span class=\"typ-punct\">)</span>\n<span class=\"typ-func\">#</span><span class=\"typ-func\">pagebreak</span><span class=\"typ-punct\">(</span><span class=\"typ-punct\">)</span>\n\n<span class=\"typ-heading\">= Background</span> <span class=\"typ-label\">&lt;back&gt;</span>\n<span class=\"typ-func\">#</span><span class=\"typ-func\">lorem</span><span class=\"typ-punct\">(</span><span class=\"typ-num\">5</span><span class=\"typ-punct\">)</span>\n</code></pre><div class=\"preview\"><img src=\"/en-US-v0.13.1/assets/15d46686485c6a70637c453971b72de.png\" alt=\"Preview\"></div></div>\n<p>There are other functions that make use of the location context, most\nprominently <a href=\"/en-US-v0.13.1/reference/introspection/query/\" title=\"`query`\"><code>query</code></a>. Take a look at the\n<a href=\"/en-US-v0.13.1/reference/introspection/\">introspection</a> category for more details on those.</p>\n<h2 id=\"nested-contexts\">Nested contexts</h2>\n<p>Context is also accessible from within function calls nested in context blocks.\nIn the example below, <code>foo</code> itself becomes a contextual function, just like\n<a href=\"/en-US-v0.13.1/reference/layout/length/#definitions-to-absolute\"><code>to-absolute</code></a> is.</p>\n<div class=\"previewed-code\"><pre><code><span class=\"typ-key\">#</span><span class=\"typ-key\">let</span> <span class=\"typ-func\">foo</span><span class=\"typ-punct\">(</span><span class=\"typ-punct\">)</span> <span class=\"typ-op\">=</span> <span class=\"typ-num\">1em</span><span class=\"typ-punct\">.</span><span class=\"typ-func\">to-absolute</span><span class=\"typ-punct\">(</span><span class=\"typ-punct\">)</span>\n<span class=\"typ-key\">#</span><span class=\"typ-key\">context</span> <span class=\"typ-punct\">{</span>\n  <span class=\"typ-func\">foo</span><span class=\"typ-punct\">(</span><span class=\"typ-punct\">)</span> <span class=\"typ-op\">==</span> text<span class=\"typ-punct\">.</span>size\n<span class=\"typ-punct\">}</span>\n</code></pre><div class=\"preview\"><img src=\"/en-US-v0.13.1/assets/b4160bb9fbad465465d9927f3c09bea3.png\" alt=\"Preview\"></div></div>\n<p>Context blocks can be nested. Contextual code will then always access the\ninnermost context. The example below demonstrates this: The first <code>text.lang</code>\nwill access the outer context block's styles and as such, it will <strong>not</strong>\nsee the effect of <code><span class=\"typ-key\">set</span> <span class=\"typ-func\">text</span><span class=\"typ-punct\">(</span>lang<span class=\"typ-punct\">:</span> <span class=\"typ-str\">&quot;fr&quot;</span><span class=\"typ-punct\">)</span></code>. The nested context block around the\nsecond <code>text.lang</code>, however, starts after the set rule and will thus show\nits effect.</p>\n<div class=\"previewed-code\"><pre><code><span class=\"typ-key\">#</span><span class=\"typ-key\">set</span> <span class=\"typ-func\">text</span><span class=\"typ-punct\">(</span>lang<span class=\"typ-punct\">:</span> <span class=\"typ-str\">&quot;de&quot;</span><span class=\"typ-punct\">)</span>\n<span class=\"typ-key\">#</span><span class=\"typ-key\">context</span> <span class=\"typ-punct\">[</span>\n  <span class=\"typ-key\">#</span><span class=\"typ-key\">set</span> <span class=\"typ-func\">text</span><span class=\"typ-punct\">(</span>lang<span class=\"typ-punct\">:</span> <span class=\"typ-str\">&quot;fr&quot;</span><span class=\"typ-punct\">)</span>\n  <span class=\"typ-pol\">#</span><span class=\"typ-pol\">text</span><span class=\"typ-punct\">.</span><span class=\"typ-pol\">lang</span> <span class=\"typ-escape\">\\</span>\n  <span class=\"typ-key\">#</span><span class=\"typ-key\">context</span> text<span class=\"typ-punct\">.</span>lang\n<span class=\"typ-punct\">]</span>\n</code></pre><div class=\"preview\"><img src=\"/en-US-v0.13.1/assets/fbc647b8dd00903360d605e600eed7db.png\" alt=\"Preview\"></div></div>\n<p>You might wonder why Typst ignores the French set rule when computing the first\n<code>text.lang</code> in the example above. The reason is that, in the general case, Typst\ncannot know all the styles that will apply as set rules can be applied to\ncontent after it has been constructed. Below, <code>text.lang</code> is already computed\nwhen the template function is applied. As such, it cannot possibly be aware of\nthe language change to French in the template.</p>\n<div class=\"previewed-code\"><pre><code><span class=\"typ-key\">#</span><span class=\"typ-key\">let</span> <span class=\"typ-func\">template</span><span class=\"typ-punct\">(</span>body<span class=\"typ-punct\">)</span> <span class=\"typ-op\">=</span> <span class=\"typ-punct\">{</span>\n  <span class=\"typ-key\">set</span> <span class=\"typ-func\">text</span><span class=\"typ-punct\">(</span>lang<span class=\"typ-punct\">:</span> <span class=\"typ-str\">&quot;fr&quot;</span><span class=\"typ-punct\">)</span>\n  <span class=\"typ-func\">upper</span><span class=\"typ-punct\">(</span>body<span class=\"typ-punct\">)</span>\n<span class=\"typ-punct\">}</span>\n\n<span class=\"typ-key\">#</span><span class=\"typ-key\">set</span> <span class=\"typ-func\">text</span><span class=\"typ-punct\">(</span>lang<span class=\"typ-punct\">:</span> <span class=\"typ-str\">&quot;de&quot;</span><span class=\"typ-punct\">)</span>\n<span class=\"typ-key\">#</span><span class=\"typ-key\">context</span> <span class=\"typ-punct\">[</span>\n  <span class=\"typ-key\">#</span><span class=\"typ-key\">show</span><span class=\"typ-punct\">:</span> <span class=\"typ-func\">template</span>\n  <span class=\"typ-pol\">#</span><span class=\"typ-pol\">text</span><span class=\"typ-punct\">.</span><span class=\"typ-pol\">lang</span> <span class=\"typ-escape\">\\</span>\n  <span class=\"typ-key\">#</span><span class=\"typ-key\">context</span> text<span class=\"typ-punct\">.</span>lang\n<span class=\"typ-punct\">]</span>\n</code></pre><div class=\"preview\"><img src=\"/en-US-v0.13.1/assets/a6d31a15dab2710195f259b4ea0dbdfa.png\" alt=\"Preview\"></div></div>\n<p>The second <code>text.lang</code>, however, <em>does</em> react to the language change because\nevaluation of its surrounding context block is deferred until the styles for it\nare known. This illustrates the importance of picking the right insertion point for a context to get access to precisely the right styles.</p>\n<p>The same also holds true for the location context. Below, the first\n<code>c<span class=\"typ-punct\">.</span><span class=\"typ-func\">display</span><span class=\"typ-punct\">(</span><span class=\"typ-punct\">)</span></code> call will access the outer context block and will thus not see\nthe effect of <code>c<span class=\"typ-punct\">.</span><span class=\"typ-func\">update</span><span class=\"typ-punct\">(</span><span class=\"typ-num\">2</span><span class=\"typ-punct\">)</span></code> while the second <code>c<span class=\"typ-punct\">.</span><span class=\"typ-func\">display</span><span class=\"typ-punct\">(</span><span class=\"typ-punct\">)</span></code> accesses the inner context and will thus see it.</p>\n<div class=\"previewed-code\"><pre><code><span class=\"typ-key\">#</span><span class=\"typ-key\">let</span> c <span class=\"typ-op\">=</span> <span class=\"typ-func\">counter</span><span class=\"typ-punct\">(</span><span class=\"typ-str\">&quot;mycounter&quot;</span><span class=\"typ-punct\">)</span>\n<span class=\"typ-pol\">#</span><span class=\"typ-pol\">c</span><span class=\"typ-punct\">.</span><span class=\"typ-func\">update</span><span class=\"typ-punct\">(</span><span class=\"typ-num\">1</span><span class=\"typ-punct\">)</span>\n<span class=\"typ-key\">#</span><span class=\"typ-key\">context</span> <span class=\"typ-punct\">[</span>\n  <span class=\"typ-pol\">#</span><span class=\"typ-pol\">c</span><span class=\"typ-punct\">.</span><span class=\"typ-func\">update</span><span class=\"typ-punct\">(</span><span class=\"typ-num\">2</span><span class=\"typ-punct\">)</span>\n  <span class=\"typ-pol\">#</span><span class=\"typ-pol\">c</span><span class=\"typ-punct\">.</span><span class=\"typ-func\">display</span><span class=\"typ-punct\">(</span><span class=\"typ-punct\">)</span> <span class=\"typ-escape\">\\</span>\n  <span class=\"typ-key\">#</span><span class=\"typ-key\">context</span> c<span class=\"typ-punct\">.</span><span class=\"typ-func\">display</span><span class=\"typ-punct\">(</span><span class=\"typ-punct\">)</span>\n<span class=\"typ-punct\">]</span>\n</code></pre><div class=\"preview\"><img src=\"/en-US-v0.13.1/assets/ea69407d29bbeb8eaf88ee12f2e6ba83.png\" alt=\"Preview\"></div></div>\n<h2 id=\"compiler-iterations\">Compiler iterations</h2>\n<p>To resolve contextual interactions, the Typst compiler processes your document\nmultiple times. For instance, to resolve a <code>locate</code> call, Typst first provides a\nplaceholder position, layouts your document and then recompiles with the known\nposition from the finished layout. The same approach is taken to resolve\ncounters, states, and queries. In certain cases, Typst may even need more than\ntwo iterations to resolve everything. While that's sometimes a necessity, it may\nalso be a sign of misuse of contextual functions (e.g. of\n<a href=\"/en-US-v0.13.1/reference/introspection/state/#caution\">state</a>). If Typst cannot resolve everything within five\nattempts, it will stop and output the warning &quot;layout did not converge within 5\nattempts.&quot;</p>\n<p>A very careful reader might have noticed that not all of the functions presented\nabove actually make use of the current location. While\n<code><span class=\"typ-func\">counter</span><span class=\"typ-punct\">(</span>heading<span class=\"typ-punct\">)</span><span class=\"typ-punct\">.</span><span class=\"typ-func\">get</span><span class=\"typ-punct\">(</span><span class=\"typ-punct\">)</span></code> definitely depends on it,\n<code><span class=\"typ-func\">counter</span><span class=\"typ-punct\">(</span>heading<span class=\"typ-punct\">)</span><span class=\"typ-punct\">.</span><span class=\"typ-func\">at</span><span class=\"typ-punct\">(</span><span class=\"typ-label\">&lt;intro&gt;</span><span class=\"typ-punct\">)</span></code>, for instance, does not. However, it still\nrequires context. While its value is always the same <em>within</em> one compilation\niteration, it may change over the course of multiple compiler iterations. If one\ncould call it directly at the top level of a module, the whole module and its\nexports could change over the course of multiple compiler iterations, which\nwould not be desirable.</p>\n<div class=\"footnote-definition\" id=\"1\"><sup class=\"footnote-definition-label\">1</sup>\n<p>Currently, all show rules provide styling context, but only show rules on\n<a href=\"/en-US-v0.13.1/reference/introspection/location/#locatable\">locatable</a> elements provide a location context.</p>\n</div>"}}