diff options
Diffstat (limited to 'docs/src/tutorial/4-template.md')
| -rw-r--r-- | docs/src/tutorial/4-template.md | 380 |
1 files changed, 0 insertions, 380 deletions
diff --git a/docs/src/tutorial/4-template.md b/docs/src/tutorial/4-template.md deleted file mode 100644 index 320f82b2..00000000 --- a/docs/src/tutorial/4-template.md +++ /dev/null @@ -1,380 +0,0 @@ ---- -description: Typst's tutorial. ---- - -# Making a Template -In the previous three chapters of this tutorial, you have learned how to write a -document in Typst, apply basic styles, and customize its appearance in-depth to -comply with a publisher's style guide. Because the paper you wrote in the -previous chapter was a tremendous success, you have been asked to write a -follow-up article for the same conference. This time, you want to take the style -you created in the previous chapter and turn it into a reusable template. In -this chapter you will learn how to create a template that you and your team can -use with just one show rule. Let's get started! - -## A toy template { #toy-template } -In Typst, templates are functions in which you can wrap your whole document. To -learn how to do that, let's first review how to write your very own functions. -They can do anything you want them to, so why not go a bit crazy? - -```example -#let amazed(term) = box[✨ #term ✨] - -You are #amazed[beautiful]! -``` - -This function takes a single argument, `term`, and returns a content block with -the `term` surrounded by sparkles. We also put the whole thing in a box so that -the term we are amazed by cannot be separated from its sparkles by a line break. - -Many functions that come with Typst have optional named parameters. Our -functions can also have them. Let's add a parameter to our function that lets us -choose the color of the text. We need to provide a default color in case the -parameter isn't given. - -```example -#let amazed(term, color: blue) = { - text(color, box[✨ #term ✨]) -} - -You are #amazed[beautiful]! -I am #amazed(color: purple)[amazed]! -``` - -Templates now work by using an "everything" show rule that applies the custom -function to our whole document. Let's do that with our `amazed` function. - -```example ->>> #let amazed(term, color: blue) = { ->>> text(color, box[✨ #term ✨]) ->>> } -#show: amazed -I choose to focus on the good -in my life and let go of any -negative thoughts or beliefs. -In fact, I am amazing! -``` - -Our whole document will now be passed to the `amazed` function, as if we -wrapped it around it. This is not especially useful with this particular -function, but when combined with set rules and named arguments, it can be very -powerful. - -## Embedding set and show rules { #set-and-show-rules } -To apply some set and show rules to our template, we can use `set` and `show` -within a content block in our function and then insert the document into -that content block. - -```example -#let template(doc) = [ - #set text(font: "Inria Serif") - #show "something cool": [Typst] - #doc -] - -#show: template -I am learning something cool today. -It's going great so far! -``` - -Just like we already discovered in the previous chapter, set rules will apply to -everything within their content block. Since the everything show rule passes our -whole document to the `template` function, the text set rule and string show -rule in our template will apply to the whole document. Let's use this knowledge -to create a template that reproduces the body style of the paper we wrote in the -previous chapter. - -```example -#let conf(title, doc) = { - set page( - paper: "us-letter", ->>> margin: auto, - header: align( - right + horizon, - title - ), -<<< ... - ) - set par(justify: true) - set text( - font: "Linux Libertine", - size: 11pt, - ) - - // Heading show rules. -<<< ... ->>> show heading.where( ->>> level: 1 ->>> ): it => block( ->>> align(center, ->>> text( ->>> 13pt, ->>> weight: "regular", ->>> smallcaps(it.body), ->>> ) ->>> ), ->>> ) ->>> show heading.where( ->>> level: 2 ->>> ): it => box( ->>> text( ->>> 11pt, ->>> weight: "regular", ->>> style: "italic", ->>> it.body + [.], ->>> ) ->>> ) - - columns(2, doc) -} - -#show: doc => conf( - [Paper title], - doc, -) - -= Introduction -#lorem(90) - -<<< ... ->>> == Motivation ->>> #lorem(140) ->>> ->>> == Problem Statement ->>> #lorem(50) ->>> ->>> = Related Work ->>> #lorem(200) -``` - -We copy-pasted most of that code from the previous chapter. The only two -differences are that we wrapped everything in the function `conf` and are -calling the columns function directly on the `doc` argument as it already -contains the content of the document. Moreover, we used a curly-braced code -block instead of a content block. This way, we don't need to prefix all set -rules and function calls with a `#`. In exchange, we cannot write markup -directly into it anymore. - -Also note where the title comes from: We previously had it inside of a variable. -Now, we are receiving it as the first parameter of the template function. -Thus, we must specify it in the show rule where we call the template. - -## Templates with named arguments { #named-arguments } -Our paper in the previous chapter had a title and an author list. Let's add these -things to our template. In addition to the title, we want our template to accept -a list of authors with their affiliations and the paper's abstract. To keep -things readable, we'll add those as named arguments. In the end, we want it to -work like this: - -```typ -#show: doc => conf( - title: [Towards Improved Modelling], - authors: ( - ( - name: "Theresa Tungsten", - affiliation: "Artos Institute", - email: "tung@artos.edu", - ), - ( - name: "Eugene Deklan", - affiliation: "Honduras State", - email: "e.deklan@hstate.hn", - ), - ), - abstract: lorem(80), - doc, -) - -... -``` - -Let's build this new template function. First, we add a default value to the -`title` argument. This way, we can call the template without specifying a title. -We also add the named `authors` and `abstract` parameters with empty defaults. -Next, we copy the code that generates title, abstract and authors from the -previous chapter into the template, replacing the fixed details with the -parameters. - -The new `authors` parameter expects an [array]($type/array) of -[dictionaries]($type/dictionary) with the keys `name`, `affiliation` and -`email`. Because we can have an arbitrary number of authors, we dynamically -determine if we need one, two or three columns for the author list. First, we -determine the number of authors using the [`.len()`]($type/array.len) method on -the `authors` array. Then, we set the number of columns as the minimum of this -count and three, so that we never create more than three columns. If there are -more than three authors, a new row will be inserted instead. For this purpose, -we have also added a `row-gutter` parameter to the `grid` function. Otherwise, -the rows would be too close together. To extract the details about the authors -from the dictionary, we use the [field access syntax]($scripting/#fields). - -We still have to provide an argument to the grid for each author: Here is where -the array's [`map` method]($type/array.map) comes in handy. It takes a function -as an argument that gets called with each item of the array. We pass it a -function that formats the details for each author and returns a new array -containing content values. We've now got one array of values that we'd like to -use as multiple arguments for the grid. We can do that by using the [`spread` -operator]($type/arguments). It takes an array and applies each of its items as a -separate argument to the function. - -The resulting template function looks like this: - -```typ -#let conf( - title: none, - authors: (), - abstract: [], - doc, -) = { - // Set and show rules from before. -<<< ... - - set align(center) - text(17pt, title) - - let count = authors.len() - let ncols = calc.min(count, 3) - grid( - columns: (1fr,) * ncols, - row-gutter: 24pt, - ..authors.map(author => [ - #author.name \ - #author.affiliation \ - #link("mailto:" + author.email) - ]), - ) - - par(justify: false)[ - *Abstract* \ - #abstract - ] - - set align(left) - columns(2, doc) -} -``` - -## A separate file { #separate-file } -Most of the time, a template is specified in a different file and then imported -into the document. This way, the main file you write in is kept clutter free and -your template is easily reused. Create a new text file in the file panel by -clicking the plus button and name it `conf.typ`. Move the `conf` function -definition inside of that new file. Now you can access it from your main file by -adding an import before the show rule. Specify the path of the file between the -`{import}` keyword and a colon, then name the function that you -want to import. - -```example:single ->>> #let conf( ->>> title: none, ->>> authors: (), ->>> abstract: [], ->>> doc, ->>> ) = { ->>> set text(font: "Linux Libertine", 11pt) ->>> set par(justify: true) ->>> set page( ->>> "us-letter", ->>> margin: auto, ->>> header: align( ->>> right + horizon, ->>> title ->>> ), ->>> numbering: "1", ->>> ) ->>> ->>> show heading.where( ->>> level: 1 ->>> ): it => block( ->>> align(center, ->>> text( ->>> 13pt, ->>> weight: "regular", ->>> smallcaps(it.body), ->>> ) ->>> ), ->>> ) ->>> show heading.where( ->>> level: 2 ->>> ): it => box( ->>> text( ->>> 11pt, ->>> weight: "regular", ->>> style: "italic", ->>> it.body + [.], ->>> ) ->>> ) ->>> ->>> set align(center) ->>> text(17pt, title) ->>> ->>> let count = calc.min(authors.len(), 3) ->>> grid( ->>> columns: (1fr,) * count, ->>> row-gutter: 24pt, ->>> ..authors.map(author => [ ->>> #author.name \ ->>> #author.affiliation \ ->>> #link("mailto:" + author.email) ->>> ]), ->>> ) ->>> ->>> par(justify: false)[ ->>> *Abstract* \ ->>> #abstract ->>> ] ->>> ->>> set align(left) ->>> columns(2, doc) ->>>} -<<< #import "conf.typ": conf -#show: doc => conf( - title: [ - Towards Improved Modelling - ], - authors: ( - ( - name: "Theresa Tungsten", - affiliation: "Artos Institute", - email: "tung@artos.edu", - ), - ( - name: "Eugene Deklan", - affiliation: "Honduras State", - email: "e.deklan@hstate.hn", - ), - ), - abstract: lorem(80), - doc, -) - -= Introduction -#lorem(90) - -== Motivation -#lorem(140) - -== Problem Statement -#lorem(50) - -= Related Work -#lorem(200) -``` - -We have now converted the conference paper into a reusable template for that -conference! Why not share it on -[Typst's Discord server](https://discord.gg/2uDybryKPe) so that others can use -it too? - -## Review { #review } -Congratulations, you have completed Typst's Tutorial! In this section, you have -learned how to define your own functions and how to create and apply templates -that define reusable document styles. You've made it far and learned a lot. You -can now use Typst to write your own documents and share them with others. - -We are still a super young project and are looking for feedback. If you have any -questions, suggestions or you found a bug, please let us know on -[Typst's Discord server](https://discord.gg/2uDybryKPe), on our -[contact form](https://typst.app/contact), or on -[social media.](https://twitter.com/typstapp) - -So what are you waiting for? [Sign up](https://typst.app) and write something! |
