2 Character Properties
dxtr edited this page 2026-10-11 23:39:14 +02:00
This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Character properties

Every Unicode character has dozens of properties in the Unicode Character Database (UCD): its general category, bidi class, script, line break class, East Asian width, emoji status, and so on. cl-icu reads them from ICU, so they always match the ICU's Unicode version.

Functions here take a single character: a Lisp character or a code point integer from 0 to #x10FFFF.

char-property char property → value

The value of property for char. property names a UCD property, as a keyword or a string, matched loosely the way ICU does (case, spaces, hyphens and underscores ignored, short aliases accepted):

(icu:char-property #\一 :east-asian-width)        ; => :WIDE
(icu:char-property #\一 "East_Asian_Width")      ; => :WIDE
(icu:char-property #\一 "ea")                    ; => :WIDE

The value depends on the kind of property:

Kind Value Examples
binary t or nil :alphabetic, :white-space, :emoji, :emoji-presentation, :extended-pictographic, :ideographic, :default-ignorable-code-point, :bidi-mirrored, :xid-start, :xid-continue, :uppercase, :lowercase, :regional-indicator, :emoji-modifier, :changes-when-casefolded
enumerated a keyword made from the value's long name (Left_To_Right → :left-to-right), or an integer for a value without a name :general-category, :bidi-class, :script, :line-break, :east-asian-width, :vertical-orientation, :grapheme-cluster-break, :word-break, :sentence-break, :joining-type, :joining-group, :hangul-syllable-type, :numeric-type, :canonical-combining-class, :bidi-paired-bracket-type, :indic-syllabic-category, :indic-positional-category, :block

Unsupported kinds, numeric (:numeric-value), string (:name, :age, case mappings) and mask properties (:general-category-mask), signal an icu-error. So does a name ICU does not know:

ICU knows no Unicode property named :NONSENSE.
Name a property of the Unicode Character Database, as a keyword
such as :EAST-ASIAN-WIDTH or a string such as "East_Asian_Width" or "ea".

The type unicode-property ((or keyword string)) describes a property name.

Properties useful for text layout

Property Example Used for
:east-asian-width #\一 → :wide, #\a → :narrow, A → :fullwidth, α → :ambiguous terminal and monospace column widths
:vertical-orientation #\一 → :upright, #\a → :rotated, 。 → :transformed-upright vertical text (UTR #50)
:line-break #\a → :alphabetic, #\一 → :ideographic custom line breaking
:emoji, :emoji-presentation 😀 → t, t; ❤ (U+2764) → t, nil; #\1 → t, nil choosing an emoji font; ❤ and digits are emoji only with U+FE0F
:extended-pictographic 😀 → t emoji detection, including future emoji
:default-ignorable-code-point ZWSP, ZWJ, variation selectors → t characters that draw nothing
:white-space space, tab, newline, NBSP → t trimming, hanging spaces at line ends
:joining-type ا → :right-joining Arabic-script analysis
:canonical-combining-class U+0301 → :above, #\a → :not-reordered, U+05B0 → :ccc10 mark handling
:script #\a → :latin, ー → :common as char-script, but as a keyword of the long name
:block #\a → :basic-latin grouping in character pickers

Note that (char-property c :script) returns the long name as a keyword (:latin), while char-script returns the ISO 15924 code ("Latn") that HarfBuzz takes.

char-general-category char → keyword

Shorthand for (char-property char :general-category):

(icu:char-general-category #\A)                    ; => :UPPERCASE-LETTER
(icu:char-general-category #\Space)                ; => :SPACE-SEPARATOR
(icu:char-general-category (code-char #x301))      ; => :NONSPACING-MARK
(icu:char-general-category (code-char #x1F600))    ; => :OTHER-SYMBOL
(icu:char-general-category (code-char #xE000))     ; => :PRIVATE-USE
(icu:char-general-category (code-char #x378))      ; => :UNASSIGNED

The 30 values: :uppercase-letter, :lowercase-letter, :titlecase-letter, :modifier-letter, :other-letter, :nonspacing-mark, :spacing-mark, :enclosing-mark, :decimal-number, :letter-number, :other-number, :connector-punctuation, :dash-punctuation, :open-punctuation, :close-punctuation, :initial-punctuation, :final-punctuation, :other-punctuation, :math-symbol, :currency-symbol, :modifier-symbol, :other-symbol, :space-separator, :line-separator, :paragraph-separator, :control, :format, :surrogate, :private-use, :unassigned.

char-bidi-class char → keyword

Shorthand for (char-property char :bidi-class): the character's directional type for the bidirectional algorithm.

(icu:char-bidi-class #\a)                     ; => :LEFT-TO-RIGHT
(icu:char-bidi-class (code-char #x5D0))       ; => :RIGHT-TO-LEFT     Hebrew
(icu:char-bidi-class (code-char #x627))       ; => :ARABIC-LETTER
(icu:char-bidi-class #\1)                     ; => :EUROPEAN-NUMBER
(icu:char-bidi-class (code-char #x661))       ; => :ARABIC-NUMBER
(icu:char-bidi-class #\Newline)               ; => :PARAGRAPH-SEPARATOR
(icu:char-bidi-class #\Tab)                   ; => :SEGMENT-SEPARATOR
(icu:char-bidi-class #\Space)                 ; => :WHITE-SPACE
(icu:char-bidi-class (code-char #x2067))      ; => :RIGHT-TO-LEFT-ISOLATE

:paragraph-separator is how to recognise characters that end a paragraph.

Names

char-unicode-name char &key alias → string or nil

The character's Unicode name, or nil if it has none (control characters, private use, unassigned). With alias true, its correction alias instead, for the few characters whose official name is wrong, or nil.

(icu:char-unicode-name #\a)                          ; => "LATIN SMALL LETTER A"
(icu:char-unicode-name (code-char #x1F600))          ; => "GRINNING FACE"
(icu:char-unicode-name (code-char #x4E00))           ; => "CJK UNIFIED IDEOGRAPH-4E00"
(icu:char-unicode-name (code-char #xAC00))           ; => "HANGUL SYLLABLE GA"
(icu:char-unicode-name #\Newline)                    ; => NIL
(icu:char-unicode-name (code-char #x1A2))            ; => "LATIN CAPITAL LETTER OI"
(icu:char-unicode-name (code-char #x1A2) :alias t)   ; => "LATIN CAPITAL LETTER GHA"

unicode-name-char name → character or nil

The character with the Unicode name or correction alias name, matched case-insensitively (but otherwise exactly), or nil: the inverse of char-unicode-name, as cl:name-char is of cl:char-name. Unlike cl:name-char, it knows every name in ICU's Unicode version, including algorithmic ones:

(icu:unicode-name-char "snowman")                     ; => #\SNOWMAN
(icu:unicode-name-char "grinning face")               ; => #\GRINNING_FACE
(icu:unicode-name-char "CJK UNIFIED IDEOGRAPH-4E00")  ; => #\U4E00
(icu:unicode-name-char "hangul syllable ga")          ; => #\HANGUL_SYLLABLE_GA
(icu:unicode-name-char "LATIN CAPITAL LETTER GHA")    ; => #\LATIN_CAPITAL_LETTER_OI
(icu:unicode-name-char "Snow Man")                    ; => NIL

char-mirror char → character

The character that mirrors char in right-to-left text, or char itself if it has none:

(icu:char-mirror #\()                  ; => #\)
(icu:char-mirror #\«)                  ; => #\»
(icu:char-mirror (code-char #x2264))   ; ≤ => #\≥
(icu:char-mirror #\a)                  ; => #\a

A shaper such as HarfBuzz mirrors characters itself in right-to-left runs. Use char-mirror when displaying bidirectional text without one; see Visual order for plain text.