Skip to content
71 changes: 71 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Contributing Guidelines
Contributions are welcome! This document provides some resources and guidelines to help with the process.

Symbol definitions are in `src/modules/`; The syntax should be mostly self-evident.
If you need help with a contribution, you can ask us [on Discord](https://discord.com/channels/1054443721975922748/1277628305142452306).

## Proposals
Proposals used to be written in the [Proposals document](https://typst.app/project/riXtMSim5zLCo7DWngIFbT),
although it is now preferred to have a GitHub issue for each one.
Nonetheless, the document still contains a lot of useful information.

Copy link
Collaborator

@knuesel knuesel Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## Terminology
In this project, related Unicode characters are grouped as *variants* under a common *symbol*.
For example, `→ ⇒ ↑ ⇑` are four variants of the `arrow` symbol. Each symbol has a default variant
(here ``). To refer to a particular variant, *modifiers* can be appended to the symbol name
using dot separators. For example `` is `arrow.double`, `` is `arrow.t` and `` is
`arrow.double.t`. The order of modifiers is generally not important so the latter can also be
referred to as `arrow.t.double`.
Large categories of symbols are further grouped into *modules*, There are currently two modules:
`sym` for regular symbols and `emoji` for emojis.
This document also uses "symbol" in the more abstract sense of a graphical symbol.

I think the document could use some clarification of the terminology (though eventually this should
be moved to a proper documentation page).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit of this is already in the lib.rs doc-comment, but I suppose it doesn't hurt repeating it here.

## Conventions
When adding new modules, symbols or variants, please try to be consistent with
existing ones. Below are some guidelines based on existing symbols. These aren't
always hard rules, especially because of how messy Unicode can be, but you should
adhere to them if possible.

### General Conventions
- English words use US spelling.
- Modifier and module names are entirely lowercase.
- Symbol names are lowercase unless the symbol is an uppercase letter.
- Symbol names should be at least two characters long so they can be used easily in Typst's math mode.
- When a symbol is added to a base, the symbol name is used as a modifier on the base.[^modifname]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- When a symbol is added to a base, the symbol name is used as a modifier on the base.[^modifname]
- For variants that add a geometric shape to a base symbol, the shape name is used as modifier with one of the following meanings:[^modifname]

I think this clarifies it a bit (I was initially confused by the double meaning of "symbol" and no mention of variant).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I slightly disagree. This is specifically about when we already have an existing symbol for the added shape. That's what I meant by "When a symbol is added to a base".

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. But don't we want to apply the same rules regardless of whether the shape is already its own symbol? For example I think we would want plus.square to follow these rules, even if we didn't have a square symbol on its own?

This can have the following meanings:
- The symbol is added around or inside the base as a subordinate (smaller than the base),
e.g. `eq.quest`, `triangle.stroked.dot`.
- The symbol is stacked below the base, e.g. `gt.lt`.
- The symbol is stacked to the right of the base, e.g. `colon.eq`.
- The symbol is overlaid at the center of the base, e.g. `integral.dash`.
- The symbol surrounds the base, e.g. `plus.square`.
Comment on lines +25 to +30
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- The symbol is added around or inside the base as a subordinate (smaller than the base),
e.g. `eq.quest`, `triangle.stroked.dot`.
- The symbol is stacked below the base, e.g. `gt.lt`.
- The symbol is stacked to the right of the base, e.g. `colon.eq`.
- The symbol is overlaid at the center of the base, e.g. `integral.dash`.
- The symbol surrounds the base, e.g. `plus.square`.
1. The shape is added around or inside the base as a subordinate (smaller than the base),
e.g. `eq.quest`, `triangle.stroked.dot`.
2. The shape is stacked below the base, e.g. `gt.lt`.
3. The shape is stacked to the right of the base, e.g. `colon.eq`.
4. The shape is overlaid at the center of the base, e.g. `integral.dash`.
5. The shape surrounds the base, e.g. `plus.square`.

Goes together with the previous suggestion. Also since we refer below to the "number 2" we might as well number the list.

- Notable exceptions to the previous convention:
- When `.eq` is used in the second sense (stacked below), it only adds a single line and not two,
e.g. `lt.eq`. For two lines below, `.equiv` is used, e.g. `lt.equiv`.

[^modifname]: Though a modifier can also just coincidentally be a symbol name, e.g. `.not`.

### Established Generic Modifiers
These have a broad meaning and can have varying interpretations.
<!-- Geometry -->
- `.l`/`.r`/`.t`/`.b`: The four main directions (left/right/top/bottom), e.g. `arrow.l`, `times.r`.
- For delimiters, `.l` means opening and `.r` means closing, e.g. `paren.l`, `quote.r`.
- `.tl`/`.tr`/`.bl`/`.br`: The four corners, e.g. `arrow.tl`, `triangle.stroked.tr`.
- Generally, these are used for a single, diagonal direction,
whereas combinations of two main directions (like `.t.l`) are used to mean both of them at once,
e.g. `arrow.t.l`, if it existed, would be an arrow that points both top and left,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
e.g. `arrow.t.l`, if it existed, would be an arrow that points both top and left,
e.g. `arrow.t.l`, if it existed, would be a two-headed arrow that points both top and left,

similarly to how `arrow.l.r` is an arrow pointing both left and right.
- `.cw`/`.ccw`: Clockwise/Counterclockwise, e.g. `arrow.cw`, `integral.ccw`.
- `.tiny`/`.small`/`.medium`/`.big`: A geometric shape with a certain size, e.g. `square.stroked.small`.
<!-- Strokes -->
- `.stroked`/`.filled`: A symbol that has an empty/filled interior, e.g. `circle.stroked`, `arrow.r.filled`.
(They correspond to Unicode's "white"/"black".)
- `.dotted`: A shape with a dotted line instead of a full stroke, e.g. `circle.dotted`.
- `.light`/`.heavy`: A shape with a certain stroke weight, e.g. `checkmark.heavy`.
<!-- Other (in alphabetic order) -->
- `.alt`: An alternate glyph for the symbol, e.g. `phi.alt`.
- `.double`, `.triple`, `.quad`: A symbol that has 2-4 of something, e.g. `excl.double`, `eq.quad`.

### Established Concrete Modifiers
These have a specific meaning that is not open to much interpretation.
<!-- (in alphabetic order) -->
- `.big`: A [large](https://www.unicode.org/Public/math/latest/MathClassEx-15.html) (n-ary) version
of an operator, e.g. `union.big`.
- `.inv`: Either vertically mirrored or a 180° rotated version of a symbol, e.g. `amp.inv`, `Omega.inv`.
- See also [#108](https://github.com/typst/codex/issues/108).
- `.not`: A negation of the symbol, e.g. `eq.not`.
- `.o`: A symbol with a circle around it, e.g. `plus.circle`.
- See also [#62](https://github.com/typst/codex/pull/62)
- `.rev`: A horizontally mirrored version of a symbol, e.g. `in.rev`.
- See also [#108](https://github.com/typst/codex/issues/108).
- `.sq`: A "squarified" version of a symbol, e.g. `subset.sq`.
- See also [#110](https://github.com/typst/codex/pull/110)