From afa19676c5add4e2dd0be8ff5e65035f2ebeeb37 Mon Sep 17 00:00:00 2001 From: Vivianne Langdon Date: Sun, 10 Mar 2024 20:09:25 -0400 Subject: [PATCH] Add new function to get the first grapheme from a string. Not sure if I have a use-case yet but it seems like it could come in handy. --- uniseg/graphemes.scm | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) 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))