LCOV - code coverage report
Current view: top level - src - tokenizer.dart (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 10 10
Test Date: 2026-07-06 21:47:03 Functions: - 0 0

            Line data    Source code
       1              : // Copyright 2026 The Authors
       2              : //
       3              : // Licensed under the Apache License, Version 2.0 (the "License");
       4              : // you may not use this file except in compliance with the License.
       5              : // You may obtain a copy of the License at
       6              : //
       7              : //     https://www.apache.org/licenses/LICENSE-2.0
       8              : //
       9              : // Unless required by applicable law or agreed to in writing, software
      10              : // distributed under the License is distributed on an "AS IS" BASIS,
      11              : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12              : // See the License for the specific language governing permissions and
      13              : // limitations under the License.
      14              : 
      15              : /// Abstract interface for text segmentation.
      16              : ///
      17              : /// Implementations segment a string into word-like tokens, discarding
      18              : /// whitespace and punctuation boundaries. The pipeline then normalises and
      19              : /// stems the returned tokens; this interface is responsible only for the
      20              : /// segmentation step.
      21              : ///
      22              : /// ## Implementations
      23              : ///
      24              : /// This package provides two implementations:
      25              : ///
      26              : /// - [RegExpTokenizer] — pure Dart, suitable for English-language prose and
      27              : ///   common technical identifiers. Zero FFI dependencies.
      28              : /// - [IcuTokenizer] — backed by the system ICU library via FFI. Conforms to
      29              : ///   UAX #29 Unicode Text Segmentation and handles non-Latin scripts (CJK,
      30              : ///   Thai, Arabic, etc.) correctly. Prefer this implementation for
      31              : ///   multi-language use cases.
      32              : ///
      33              : /// The interface is intentionally narrow so the implementation can be swapped
      34              : /// without touching the calling pipeline.
      35              : ///
      36              : /// ## Unicode Text Segmentation
      37              : ///
      38              : /// Conformant implementations should follow UAX #29 Unicode Text Segmentation
      39              : /// rules for word boundaries. [IcuTokenizer] provides a full UAX #29
      40              : /// implementation via the system ICU library.
      41              : ///
      42              : /// ## Example
      43              : ///
      44              : /// ```dart
      45              : /// final tokenizer = RegExpTokenizer();
      46              : /// final tokens = tokenizer.tokenise('Dr. Jekyll and Mr. Hyde');
      47              : /// // → ['Dr', 'Jekyll', 'and', 'Mr', 'Hyde']
      48              : /// ```
      49              : abstract interface class Tokenizer {
      50              :   /// Segments [text] into word tokens.
      51              :   ///
      52              :   /// Returns only word-like spans (letters, numbers, mixed-case identifiers).
      53              :   /// Punctuation, whitespace, and other non-word spans are discarded.
      54              :   ///
      55              :   /// An empty [text] must return an empty list without error.
      56              :   List<String> tokenise(String text);
      57              : }
      58              : 
      59              : /// A tokenised word span together with its character offsets in the
      60              : /// original text.
      61              : ///
      62              : /// [start] is inclusive and [end] is exclusive, both measured in UTF-16 code
      63              : /// units — i.e. Dart `String` index space, matching [String.substring] (so
      64              : /// `text.substring(span.start, span.end) == span.text` always holds).
      65              : final class TokenSpan {
      66              :   /// Creates a [TokenSpan].
      67            2 :   const TokenSpan(this.text, this.start, this.end);
      68              : 
      69              :   /// The token's text — identical to what [Tokenizer.tokenise] would have
      70              :   /// returned for this span.
      71              :   final String text;
      72              : 
      73              :   /// The inclusive start offset of this token in the source text.
      74              :   final int start;
      75              : 
      76              :   /// The exclusive end offset of this token in the source text.
      77              :   final int end;
      78              : 
      79            1 :   @override
      80            4 :   String toString() => 'TokenSpan($text, $start, $end)';
      81              : 
      82            1 :   @override
      83              :   bool operator ==(Object other) =>
      84            1 :       other is TokenSpan &&
      85            3 :       other.text == text &&
      86            3 :       other.start == start &&
      87            3 :       other.end == end;
      88              : 
      89            1 :   @override
      90            4 :   int get hashCode => Object.hash(text, start, end);
      91              : }
      92              : 
      93              : /// A [Tokenizer] that can also report each token's position in the source
      94              : /// text.
      95              : ///
      96              : /// Implemented by [IcuTokenizer] and [RegExpTokenizer] — position data is a
      97              : /// natural byproduct of both algorithms' underlying implementation (ICU's
      98              : /// break iterator and [RegExp] matches both already carry span boundaries).
      99              : /// Not implemented by [BrowserTokenizer]: `Intl.Segmenter`'s JS result does
     100              : /// carry a comparable `index` field, but no consumer needs offsets from the
     101              : /// web tokenizer today — left as a documented future extension rather than
     102              : /// implemented speculatively.
     103              : abstract interface class OffsetTokenizer implements Tokenizer {
     104              :   /// Segments [text] into word tokens with their character offsets.
     105              :   ///
     106              :   /// Equivalent to [tokenise] but additionally reporting each token's
     107              :   /// `(start, end)` span. An empty [text] must return an empty list without
     108              :   /// error.
     109              :   List<TokenSpan> tokeniseSpans(String text);
     110              : }
        

Generated by: LCOV version 2.0-1