Add string->grapheme-list and char->grapheme

- string->grapheme-list gets only final graphemes without intermediate ones
- char->grapheme just works for single-chars that are valid graphemes.
This commit is contained in:
Vivianne 2024-03-10 23:50:05 -04:00
parent afa19676c5
commit 50f8bb891d
Signed by: vv
GPG key ID: F3E249EDFAC7BE26

View file

@ -1,5 +1,6 @@
(define-module (uniseg graphemes)
#:use-module (uniseg graphemes stream)
#:use-module (uniseg graphemes iterator)
#:use-module (ice-9 hash-table)
#:use-module (ice-9 streams)
#:use-module (srfi srfi-41)
@ -14,7 +15,9 @@
grapheme-glyphs-reverse
grapheme-state
grapheme-string
string->grapheme))
string->grapheme
string->grapheme-list
char->grapheme))
(define-immutable-record-type <grapheme>
(_make-grapheme width delta-width modification? state glyphs-reverse glyphs-promise string-promise)
@ -45,6 +48,22 @@
"Return a lazily-constructed string of the glyphs in the grapheme."
(force (_grapheme-string-promise grapheme)))
(define (string->grapheme-list str)
"Get a list of all the final graphemes (not including intermediates) in the provided string"
(define stream (string->grapheme-stream str))
(let loop ((stream stream))
(define grapheme (stream-car stream))
(define next-stream (stream-cdr stream))
(define have-next? (stream-pair? next-stream))
(define next-modification?
(and have-next?
(grapheme-modification? (stream-car next-stream))))
(cond
(next-modification? (loop next-stream))
(have-next? (cons grapheme (loop next-stream)))
(else (list grapheme)))))
(define (string->grapheme str)
"Reads from `str' until we reach the end of the first grapheme cluster"
(define stream (string->grapheme-stream str))
@ -64,3 +83,7 @@
(if (grapheme-modification? last-grapheme)
last-grapheme
first-grapheme))
(define (char->grapheme char)
"Attempt to convert a char to a grapheme. Returns #f if no valid grapheme is formed from the single character."
((make-grapheme-iterator) char))