How to repeat a template multiple times?

I’m trying to put together a document containing articles from multiple authors. On each article’s first page, I want to display title and author in a specific formatting style; I also want them to appear in a table of contents,

Title1 (Author1)…3
Title2 (Author2)…5

etc.

I think the answer to this is a custom function for each article, that sets title and author variables in such a way that outline can read them, but I’m very new at this and I’m having trouble finding documentation in between the tutorials (jolly good but don’t cover what I’m after) and the reference (almost certainly does cover what I’m after, but I can’t find it).

Any suggestions on (a) how to do this but also (b) other documentation sources?

(I am a coder but I’m just starting with typst code. If it matters I’m using the CLI exclusively.)

Hi there. You can look at ijimai – Typst Universe, which is recently an official template for the journal that accepts articles in Typst. But you can’t just use it for each article, because multiple bibliographies are not supported yet. Do you use bibliography()? If not, then I think you can copy the necessary stuff from that template and that’s it.

The gist of the template function is:

#show: doc => {
  [above]
  doc
  [below]
}

Do you know how to create templates?

Then you would include the template in each article’s file and merge them with simple includes:

#include "ijimai1/paper.typ"
#include "ijimai2/paper.typ"

Then the above and below (with custom content) will show up above and below the article where the template is used.

Although one problem still, is that if article will use non-unique custom labels, then the main document won’t compile. I guess you can use a custom label() throughout the article that will internally create unique labels, even though it’s not as convenient as using special syntax.

But if you don’t reference anything in the articles, then there should be no issues at all.

You can make a function and wrap the whole article in it, but then you won’t be able to compile the article by itself with all the necessary styling. You don’t normally wrap a whole document in a function explicitly.

1 Like

Thanks for this, which has got me a lot further. The article-level template is working well. But my original question, which may have got lost in the other things I didn’t understand, was about generating the ToC. The IJIMAI code doesn’t seem to include the material for creating a whole issue of the journal with multiple papers, or I’ve failed to spot it.

To put it another way, I want to say somewhere in the article file:

title = “title one”
author = “author one”

(in whatever format is needed, with a conf file, that’s all flexible), and then build an outline() that will look for all those definitions and produce a ToC that looks like

title one (author one)…3
title two (author two)…5

etc.

In other words, I think, I need to define an element that is locatable so that outline() can find it, but not displayed. Or maybe I’m completely on the wrong track there.

And I’ve now resolved that thanks to the Typst Examples book.

An alternative approach which makes the PDF “Bookmarks” work too is to sacrifice the level-1 heading to the article title.

The article template runs something like:

#let article(title: "", subtitle: "", author: "", doc) = {
  set page(columns: 2)
  show heading: it => [
    #block(sticky: true, 
      if it.level == 1 {
      } else if it.level == 2 {
        text(16.1pt, weight: "bold", font: "Myriad Pro")[
          #it.body
        ]
      } // etc. for level 3 and 4
    )
  ]
  heading(
    level: 1,
    emph(title) + " (" + author + ")",
  )
  place(
    top + left,
    scope: "parent",
    float: true,
    text(18.2pt, weight: "bold", font: "Myriad Pro")[
      #title
    ],
  )
  if subtitle.len() > 0 {
    // place the subtitle similarly, elided boring code
  }
  place(
    top + left,
    scope: "parent",
    float: true,
    text()[
      #author
    ]
  )
  doc
}

and the top of the article runs:

#import "article_template.typst": article
#show: doc => article(
  title: "Title",
  author: "Author Name",
  doc
)

and headers used within the article must start at level-2. The outline is restricted to depth: 1, though it needn’t be.

You can make it simpler:

#let article(doc, title: "", subtitle: "", author: "") = {
  set page(columns: 2)
  set heading(offset: 1)
  show heading: set text(16.1pt, weight: "bold", font: "Myriad Pro")
  show heading.where(level: 1): none
  let bold = text.with(weight: "bold", font: "Myriad Pro")
  let place = place.with(top, scope: "parent", float: true)
  heading(level: 1, emph(title) + " (" + author + ")")
  place(bold(18.2pt, title))
  if subtitle.len() > 0 { place(bold(17.15pt, subtitle)) }
  place(author)
  doc
}

#outline(target: heading.where(level: 1), title: "Articles")

#[
  #show: article.with(title: "title one", author: "author one")

  = Section 1
  == Subsection 1
  = Section 2
]

#[
  #show: article.with(title: "title two", subtitle: "Subtitle", author: "author two")

  = Section 1
  == Subsection 1
  = Section 2
]

image

image image

image

1 Like