diff --git a/uniseg/graphemes.scm b/uniseg/graphemes.scm index c89b259..432249d 100644 --- a/uniseg/graphemes.scm +++ b/uniseg/graphemes.scm @@ -1,5 +1,8 @@ (define-module (uniseg graphemes) - #:use-module (ice-9 hash-table) + #:use-module (uniseg graphemes stream) + #:use-module (ice-9 hash-table) + #:use-module (ice-9 streams) + #:use-module (srfi srfi-41) #:use-module (srfi srfi-1) #:use-module (srfi srfi-9 gnu) #:export (make-grapheme @@ -10,7 +13,8 @@ grapheme-glyphs grapheme-glyphs-reverse grapheme-state - grapheme-string)) + grapheme-string + string->grapheme)) (define-immutable-record-type (_make-grapheme width delta-width modification? state glyphs-reverse glyphs-promise string-promise) @@ -40,3 +44,23 @@ (define (grapheme-string grapheme) "Return a lazily-constructed string of the glyphs in the grapheme." (force (_grapheme-string-promise grapheme))) + +(define (string->grapheme str) + "Reads from `str' until we reach the end of the first grapheme cluster" + (define stream (string->grapheme-stream str)) + (define first-grapheme (stream-car stream)) + + ;; Skip first, we want to get the last entry that is a modification + ;; (or the first entry, if there are no mods afterwards) + (define last-grapheme + (let loop ((stream stream)) + (define grapheme (stream-car stream)) + (define next-stream (stream-cdr stream)) + (if (and (stream-pair? next-stream) + (grapheme-modification? (stream-car next-stream))) + (loop next-stream) + grapheme))) + + (if (grapheme-modification? last-grapheme) + last-grapheme + first-grapheme))