/* * Copyright (c) 2022, Idan Horowitz <idan.horowitz@serenityos.org> * Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include <AK/Forward.h> #include <AK/Function.h> #include <AK/IterationDecision.h> #include <AK/Optional.h> #include <AK/Types.h> namespace Unicode { using SegmentationCallback = Function<IterationDecision(size_t)>; void for_each_grapheme_segmentation_boundary(Utf8View const&, SegmentationCallback); void for_each_grapheme_segmentation_boundary(Utf16View const&, SegmentationCallback); void for_each_grapheme_segmentation_boundary(Utf32View const&, SegmentationCallback); template<typename ViewType> Optional<size_t> next_grapheme_segmentation_boundary(ViewType const& view, size_t index) { Optional<size_t> result; for_each_grapheme_segmentation_boundary(view, [&](auto boundary) { if (boundary > index) { result = boundary; return IterationDecision::Break; } return IterationDecision::Continue; }); return result; } template<typename ViewType> Optional<size_t> previous_grapheme_segmentation_boundary(ViewType const& view, size_t index) { Optional<size_t> result; for_each_grapheme_segmentation_boundary(view, [&](auto boundary) { if (boundary < index) { result = boundary; return IterationDecision::Continue; } return IterationDecision::Break; }); return result; } void for_each_word_segmentation_boundary(Utf8View const&, SegmentationCallback); void for_each_word_segmentation_boundary(Utf16View const&, SegmentationCallback); void for_each_word_segmentation_boundary(Utf32View const&, SegmentationCallback); template<typename ViewType> Optional<size_t> next_word_segmentation_boundary(ViewType const& view, size_t index) { Optional<size_t> result; for_each_word_segmentation_boundary(view, [&](auto boundary) { if (boundary > index) { result = boundary; return IterationDecision::Break; } return IterationDecision::Continue; }); return result; } template<typename ViewType> Optional<size_t> previous_word_segmentation_boundary(ViewType const& view, size_t index) { Optional<size_t> result; for_each_word_segmentation_boundary(view, [&](auto boundary) { if (boundary < index) { result = boundary; return IterationDecision::Continue; } return IterationDecision::Break; }); return result; } void for_each_sentence_segmentation_boundary(Utf8View const&, SegmentationCallback); void for_each_sentence_segmentation_boundary(Utf16View const&, SegmentationCallback); void for_each_sentence_segmentation_boundary(Utf32View const&, SegmentationCallback); template<typename ViewType> Optional<size_t> next_sentence_segmentation_boundary(ViewType const& view, size_t index) { Optional<size_t> result; for_each_sentence_segmentation_boundary(view, [&](auto boundary) { if (boundary > index) { result = boundary; return IterationDecision::Break; } return IterationDecision::Continue; }); return result; } template<typename ViewType> Optional<size_t> previous_sentence_segmentation_boundary(ViewType const& view, size_t index) { Optional<size_t> result; for_each_sentence_segmentation_boundary(view, [&](auto boundary) { if (boundary < index) { result = boundary; return IterationDecision::Continue; } return IterationDecision::Break; }); return result; } }