Skip to content

RFC: Vertical Writing Mode #5908

@OverflowCat

Description

@OverflowCat

Introduction

Vertical layout remains vital across various cultures and contexts,
particularly in traditional East Asian typesetting.
This RFC proposes the implementation of vertical writing mode support in Typst.

Features to implement

Vertical writing

Image

And figure placement, accordingly:

Vertical text in graph

Image

Latin & formulae in vertical text

All block formulas are rotated 90° to the right of the entire formula block. Alphanumeric characters and mathematical symbols are all folded sideways.

mn

mn

Short inline math that fits into 1x line-height(?) can be upright (tate-chu-yoko).

ja

More Tate-Chu-Yoko (縦中横)

Numbers:

Full-width letters:

Image

https://tategaki.github.io/

https://marumarumarumori.jp/

Compression or not:

Image CC BY-NC

Image

Punctuations

Punctuation marks used in Taiwan and Hong Kong are usually positioned in the vertical and horizontal center of the square space left for them; while in vertical writing mode and horizontal writing mode, some of the punctuation marks are positioned in different directions so as to mark the corresponding characters more accurately. In Mainland China, the punctuation marks are usually positioned following the characters they are supposed to mark; while some punctuation marks might be positioned in different directions due to the vertical or horizontal writing mode. Also, different writing modes might require different punctuation marks to fulfill the same function, e.g. horizontal writing mode requires curved quotation marks while vertical writing mode requires corner brackets.

Proposed Solution

The core of this proposal is to extend Typst's text model and layout engine to accommodate vertical writing modes, providing a clear API for controlling and customizing text direction.

API changes

writing-mode text attr

Introduce writing-mode as an attribute for the text element and within style contexts that affect text layout. writing-mode should be a general typesetting instruction, independent of specific script systems. Users should be able to explicitly set the text direction.

Values for writing-mode include:

  • "horizontal-tb": Horizontal, top-to-bottom line progression (default, current horizontal mode).
  • "vertical-rl": Vertical, right-to-left column progression (traditional East Asian vertical mode).
  • "vertical-lr": Vertical, left-to-right column progression (e.g., Mongolian script).

inline and block axis

Writing mode is the direction of lines of text at the block level. rtl is the direction of text at the inline level. Properties that follows text direction are called logical ones. They will be mapped to physical ones based on writing-mode & rtl.

New functions, params and values

Existing layout functions like h(), v(), align(), move(), hline, etc. need adjustments for vertical writing modes. The proposal advocates for logical APIs that adapt their behavior based on the current writing-mode.

  • h() and v(): new logical spacing functions (inline-space(), block-space()) that maps to h()/v(). Also, hline() and vline().
  • move(di, db): Modify move(dx, dy) to move(di, db), where di is inline direction movement and db is block direction movement. move's behavior would then adapt to writing-mode.
  • height, width: block-size and inline-size.
  • alignment type: we have start and end for inline. block-start & block-end are needed.
  • direction type: maybe we need ste, ets?

Technical issues

Text shaping

Shaping engines are typically designed for horizontal text. In vertical writing mode, many glyphs require a 90-degree clockwise rotation for correct display. Traditional Mongolian (ᠮᠣᠩᠭᠣᠯ), for instance, also involves a 90-degree clockwise rotation. However, because its block axis progresses from left to right, the order of glyphs within each line needs to be reversed as well.

CJK characters and emojis, on the other hand, generally do not require rotation. To correctly display punctuation marks, it may be necessary to enable the vert OpenType feature (although Unicode provides separate code points for rotated punctuation). Currently, there are no known examples of rtl(?) vertical text.

HTML export

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_logical_properties_and_values

Currently, adding a writing-mode property and all things are done.

Style export should use logical properties and values. However, there are still some values that do not have a logical version, so maybe we need to resolve the logical properties into physical ones.

Backward Compatibility

This proposal prioritizes backward compatibility. writing-mode as a new text attribute defaults to "horizontal-tb", ensuring existing Typst documents render unchanged. API modifications will be carefully designed. Retaining physical attributes alongside new logical attributes helps guarantee backward compatibility during the transition.

Resource Prioritization

Image

Given potential resource constraints, we can make the foundational logical API available first (which benefits rtl text as well — For example, we don't need to write dir.sign() or pass the rtl parameter. Instead, we can directly use the logical layout keyword). Or we will find it too late to make breaking changes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature requestNew feature or requestlayoutRelated to the layout category, which is about composing, positioning, etc.textRelated to the text category, which is all about text handling, shaping, etc.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions