Crosswords in typst

I’ve made a function to create crosswords with typst (thanks a lot to PgBiel for the improved tables). My code is a mess so I won’t share it right now, but I wanted some opinions on the API.

For example:


Can be created with:

#crossword(
  (x:  9, y: 2, d: ttb, w: "text"),
  (x: 11, y: 0, d: ttb, w: "markup"),
  (x: 15, y: 5, d: ttb, w: "typst"),
  (x: 17, y: 0, d: ttb, w: "printing"),
  (x:  9, y: 5, d: ltr, w: "typesetting"),
  (x: 13, y: 9, d: ltr, w: "latex"),
)

x and y are the coordinates in a grid of the first letter of the word, d is the direction of the word. Manually setting the coordinates isn’t convenient at all, but I don’t know what would be a better interface.

8 Likes

Sounds like a cool project, and the results so far are good.

Instead of specifying locations (x, y) for words it would be really cool (and likely really hard) to just give it the words and have the template/package figure out how to lay them out. Or if you specify a shared letter between pairs of words. There could be existing algorithms for the problem of laying out crosswords.

One omission that I see though is the hints. I think each word should also have a hint, then that will be used to create the table.2.

#crossword(
  (x:  9, y: 2, d: ttb, w: "text", h:"what you type"),
  //etc...
)

//Which would result in a list like this
= Down
1. what you type
= Across
//...
2 Likes

Could you share the code? I tried to create one but it were not good as yours.

Hey Lucas,

I put together a small project that lets you create a crossword in Typst (using CeTZ). It’s definitely not perfect, but it works pretty well for simple use cases.

Feel free to check it out and use it if it helps!

// --- Example word list ---
#let my-words = (
  ("TYPST", "A modern markup language for layout and documents"),
  ("LAYOUT", "Arrangement of elements on a page"),
  ("LATEX", "Well-known typesetting language for scientific documents"),
...
)

// --- Generate the crossword (with size limit) ---
#let crossword-data = generate-crossword(my-words, max-width: 20, max-height: 20)

#crossword(crossword-data)

#crossword-list(crossword-data)

Here’s the link:
https://typst.app/project/rSoXp8FcY7pP0RyPnkQM0j

EDIT:
Just wanted to drop an update — I’ve spent the afternoon working on this and now the crossword is generated automatically using a basic algorithm (with a little help from AI).

You only need to provide a list of words, and it will try to arrange them nicely into a grid.

Check it out again if you’re interested.

3 Likes