{"id":46598540,"url":"https://github.com/ikelaiah/stringkit-fp","last_synced_at":"2026-03-07T15:34:57.128Z","repository":{"id":309535209,"uuid":"1036314093","full_name":"ikelaiah/stringkit-fp","owner":"ikelaiah","description":"Comprehensive string manipulation library providing 60+ static methods for validation, case conversion, pattern matching, fuzzy algorithms, phonetic matching, text analysis, and web encoding. Zero external dependencies - uses only Free Pascal RTL.","archived":false,"fork":false,"pushed_at":"2025-11-28T23:50:19.000Z","size":2761,"stargazers_count":10,"open_issues_count":0,"forks_count":3,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-01T01:51:55.592Z","etag":null,"topics":["free-pascal","freepascal","freepascal-library","lazarus-ide","library","string","string-formatter","string-manipulation","string-matching","string-search","string-similarity","string-validation","strings"],"latest_commit_sha":null,"homepage":"https://github.com/ikelaiah/stringkit-fp","language":"Pascal","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ikelaiah.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-11T22:24:07.000Z","updated_at":"2025-11-28T23:29:21.000Z","dependencies_parsed_at":"2025-08-12T13:30:55.657Z","dependency_job_id":"d17c2a86-153c-4fcf-bcc8-e608640a715f","html_url":"https://github.com/ikelaiah/stringkit-fp","commit_stats":null,"previous_names":["ikelaiah/stringkit-fp"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/ikelaiah/stringkit-fp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikelaiah%2Fstringkit-fp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikelaiah%2Fstringkit-fp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikelaiah%2Fstringkit-fp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikelaiah%2Fstringkit-fp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ikelaiah","download_url":"https://codeload.github.com/ikelaiah/stringkit-fp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikelaiah%2Fstringkit-fp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30219548,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-07T14:02:48.375Z","status":"ssl_error","status_checked_at":"2026-03-07T14:02:43.192Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["free-pascal","freepascal","freepascal-library","lazarus-ide","library","string","string-formatter","string-manipulation","string-matching","string-search","string-similarity","string-validation","strings"],"created_at":"2026-03-07T15:34:56.385Z","updated_at":"2026-03-07T15:34:57.112Z","avatar_url":"https://github.com/ikelaiah.png","language":"Pascal","readme":"# 🧵 StringKit-FP: The Complete String Toolkit\n\n[![FPC](https://img.shields.io/badge/Free%20Pascal-3.2.2-blue.svg)](https://www.freepascal.org/)\n[![Lazarus](https://img.shields.io/badge/Lazarus-4.0+-blue.svg)](https://www.lazarus-ide.org/)\n[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE.md)\n[![Documentation](https://img.shields.io/badge/Docs-Available-brightgreen.svg)](docs/)\n[![Tests](https://img.shields.io/badge/Tests-Passing-brightgreen.svg)](tests/)\n[![Status](https://img.shields.io/badge/Status-Ready%20to%20Weave-brightgreen.svg)]()\n[![Version](https://img.shields.io/badge/Version-1.8.0-blueviolet.svg)]()\n\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/logo-v1-320.png\" alt=\"StringKit-FP Logo\" width=\"320\"/\u003e\n\u003c/p\u003e\n\n\n## 📚 Table of Contents\n\n- [Why Choose StringKit-FP?](#-why-choose-stringkit-fp)\n- [Feature Overview](#-feature-overview)\n- [Installation (Lazarus IDE)](#-installation-lazarus-ide)\n- [Manual Installation (General)](#-manual-installation-general)\n- [Usage](#-usage)\n  - [Quick Start](#-quick-start)\n  - [Instance-Style API via Type Helpers](#-instance-style-api-via-type-helpers)\n  - [Modular Helper via Feature Flags (1.6.0+)](#modular-helper)\n- [Start Weaving: Quick Thread Patterns](#-start-weaving-quick-thread-patterns)\n- [System Requirements](#-system-requirements)\n- [Documentation](#-documentation)\n- [Testing](#-testing)\n- [License](#-license)\n- [Changelog](CHANGELOG.md)\n\n\n## 🧵 Why Choose StringKit-FP?\n\nProfessional string toolkit featuring advanced algorithms: Levenshtein/Jaro similarity, Soundex/Metaphone phonetics, readability scoring, regex patterns, HTML/URL encoding, and comprehensive validation. Static API, no instantiation required.\n\n**🎯 Key Advantages:**\n\n- 🧶 **Comprehensive**: 90+ string operations covering validation, transformation, analysis, and encoding\n- 🪡 **Zero Dependencies**: Uses only standard Free Pascal RTL - no external libraries required\n- 📏 **Advanced Analysis**: Readability scoring, n-gram generation, and statistical text analysis\n- 🔍 **Robust Validation**: Regex patterns, format checking, and custom validation rules\n- 🌐 **Web-Ready**: URL encoding, HTML escaping, and modern web standards support\n- 🧪 **Thoroughly Tested**: Comprehensive test suite ensuring reliability in production\n- ⚡ **Simple API**: Static methods - no object instantiation required, just call and use\n\n## ✨ Feature Overview\n\n### 🎭 **Case Conversion \u0026 Formatting**\n\n*Professional text styling and formatting*\n\n- `ToUpper()`, `ToLower()`, `ToTitleCase()` - Standard case transformations\n- `ToCamelCase()`, `ToPascalCase()`, `ToSnakeCase()`, `ToKebabCase()` - Modern naming conventions\n- `PadLeft()`, `PadRight()`, `PadCenter()` - Text alignment with custom padding\n- `Truncate()` - Smart text truncation with ellipsis support\n- `CapitalizeText()` - Intelligent word capitalization\n\n### 🔍 **Validation \u0026 Pattern Matching**\n\n*Robust string validation and pattern extraction*\n\n- `IsValidEmail()`, `IsValidURL()`, `IsValidIP()` - Comprehensive format validation\n- `IsValidDate()` - Date validation with custom format support\n- `MatchesPattern()` - Powerful regex pattern matching\n- `ExtractMatches()`, `ExtractAllMatches()` - Extract matching substrings\n\n### 🧬 **Similarity \u0026 Fuzzy Matching**\n\n*Advanced string comparison algorithms*\n\n- `LevenshteinDistance()`, `LevenshteinSimilarity()` - Edit distance calculations\n- `HammingDistance()` - Character-by-character comparison for equal-length strings\n- `JaroSimilarity()`, `JaroWinklerSimilarity()` - Sophisticated similarity metrics\n- `LongestCommonSubsequence()`, `LCSSimilarity()` - Common subsequence analysis\n- `IsFuzzyMatch()` - Multi-algorithm fuzzy string matching\n\n### 🎵 **Phonetic Matching**\n\n*Sound-based string comparison algorithms*\n\n- `Soundex()` - Russell-Odell phonetic algorithm for name matching\n- `Metaphone()` - Advanced English pronunciation-based matching\n\n### 🏛️ **Number Formatting**\n\n*Professional number and numeric string handling*\n\n- `ToRoman()`, `FromRoman()` - Roman numeral conversion (1-3999)\n- `FormatFileSize()` - Human-readable file size formatting (B, KB, MB, GB, TB)\n- `FormatNumber()`, `FormatFloat()` - Thousand-separator formatting\n- `ToOrdinal()` - Ordinal number formatting (1st, 2nd, 3rd...)\n- `NumberToWords()` - Convert numbers to English words\n\n### 🌐 **Encoding \u0026 Web Utilities**\n\n*Web-safe string encoding and decoding*\n\n- `HTMLEncode()`, `HTMLDecode()` - HTML entity encoding for safe web output\n- `URLEncode()`, `URLDecode()` - URL parameter encoding/decoding\n- `HexEncode()`, `HexDecode()` - Hexadecimal string conversion\n\n### 📊 **Text Analysis**\n\n*Statistical analysis and text insights*\n\n- `CountWords()`, `GetWords()` - Word counting and extraction\n- `FleschKincaidReadability()` - Readability scoring for content assessment\n- `GenerateNGrams()` - N-gram generation for linguistic analysis\n\n### 🛠️ **String Utilities**\n\n*Essential string manipulation operations*\n\n- `Split()`, `Join()` - String splitting and joining operations\n- `ReplaceText()`, `ReplaceRegEx()` - Text replacement with regex support\n- `Contains()`, `StartsWith()`, `EndsWith()` - String content inspection\n- `CollapseWhitespace()`, `RemoveWhitespace()` - Whitespace normalization\n- `DuplicateText()`, `ReverseText()` - String duplication and reversal\n- `GetLength()`, `SubString()`, `LeftStr()`, `RightStr()` - String length and extraction\n- `CountSubString()` - Substring occurrence counting\n\n## 🧶 Installation (Lazarus IDE)\n\n*Quick setup for Lazarus development*\n\n1. **Clone the repository**:\n\n```bash\ngit clone https://github.com/ikelaiah/stringkit-fp\n```\n\n2. **Open your project** - Open/start a new project in Lazarus IDE\n\n3. **Add the package** - Go to `Package` → `Open Package File (.lpk)...`\n\n4. **Select the package** - Navigate to the StringKit packages in the `packages/lazarus/` folder and select `stringkit_fp.lpk`\n\n5. **Compile the package** - In the package window that opens, click `Compile`\n\n6. **Install to project** - Click `Use → Add to Project` to install the package\n\n✅ **Installation complete!** StringKit is now available in your Lazarus project.\n\n## 🧵 Manual Installation (General)\n\n*Alternative setup method*\n\n1. **Clone the repository**:\n\n```bash\ngit clone https://github.com/ikelaiah/stringkit-fp\n```\n\n2. **Configure your project** - Add the source directory to your project's search path.\n\n\n## 🧵 Usage\n\n*Import StringKit into your project*\n\n```pascal\nuses\n  // String manipulation library\n  StringKit;           // All string operations\n```\n\n### 🚀 Quick Start\n\nMinimal end-to-end usage with static and helper APIs:\n\n```pascal\nuses\n  SysUtils,\n  StringKit,\n  StringKitHelper; // enable instance-style helper\n\nbegin\n  // Validation (helper)\n  if 'user@example.com'.IsValidEmail then\n    WriteLn('Valid email');\n\n  // Formatting (static)\n  WriteLn(TStringKit.FormatFileSize(1048576)); // 1.00 MB\n\n  // Encoding (helper)\n  WriteLn('foo'.Encode64); // Zm9v\nend.\n```\n\n### 🧩 Instance-Style API via Type Helpers\n\nStringKit also provides a string type helper for more natural, instance-style calls.\n\n```pascal\nuses\n  StringKit, StringKitHelper; // Enable helper-backed instance methods on 'string'\n\nvar\n  S: string;\nbegin\n  // Instance-style calls (via TStringHelperEx)\n  S := '  hello world  '.Trim;                // 'hello world'\n  S := 'Hello World'.ToSnakeCase;             // 'hello_world'\n  if 'user@example.com'.IsValidEmail then ;   // True\n  S := 'Hello World!'.URLEncode;              // 'Hello+World%21'\n  S := 'foo'.Encode64;                        // 'Zm9v'\n\n  // Equivalent static calls still work\n  S := TStringKit.Trim('  hello world  ');\nend;\n```\n\nNotes:\n- Add `StringKitHelper` to your unit's `uses` clause to enable helper methods.\n- Most `TStringKit` string-first methods are available via the helper for convenience; methods that don't operate on a source string may remain as static calls.\n\n#### ⚙️ Modular Helper via Feature Flags (1.6.0+)\n\nAs of 1.6.0, `TStringHelperEx` is modularized using conditional includes to let you select which groups compile into the helper.\n\n- Default: if no symbols are defined, `SK_ALL` enables all groups.\n- Selective mode: define `SK_ANY` and then enable specific groups you need.\n\nAvailable groups:\n\n- `SK_MANIP` — trim, pad, collapse whitespace, reverse, length, substring\n- `SK_MATCH` — regex match/extract, contains/starts/ends, words, counts\n- `SK_COMPARE` — Levenshtein, Hamming, Jaro/Jaro-Winkler, LCS, fuzzy\n- `SK_CASE` — title, camel, pascal, snake, kebab\n- `SK_VALIDATE` — email, URL, IP (v4/v6), date\n- `SK_FORMAT` — truncate, file size, number/float formatting\n- `SK_NUMERIC` — roman, ordinal, number-to-words, from-roman\n- `SK_ENCODE` — hex, base64, HTML, URL encode/decode\n- `SK_SPLIT` — split, join\n- `SK_PHONETIC` — soundex, metaphone, readability, ngrams, basic counts\n\nNotes:\n\n- Implementation and interface includes live under `src/inc/` and are pulled from `src/StringKitHelper.pas` using `{$I ...}`.\n- When `SK_ALL` (default) is active, the helper API matches the full surface as before.\n- See also: [CHANGELOG 1.6.0](CHANGELOG.md#release-160---2025-08-16) for the summary.\n\n##### 🚀 SK_ENCODE Quick Start (helper-only)\n\nEnable only encoding/decoding helpers via feature flags, then use `StringKitHelper` without static calls.\n\n- Lazarus (FPC): Project Options \u003e Compiler Options \u003e Custom Options\n  - `-dSK_ANY -dSK_ENCODE`\n\nUses:\n\n```pascal\nuses SysUtils, StringKitHelper;\n```\n\nExamples:\n\n```pascal\nbegin\n  // 1) Base64\n  WriteLn('foo'.Encode64);    // Zm9v\n  WriteLn('Zm9v'.Decode64);   // foo\n\n  // 2) URL\n  WriteLn('Hello World!'.URLEncode);    // Hello+World%21\n  WriteLn('Hello+World%21'.URLDecode);  // Hello World!\n\n  // 3) HTML\n  WriteLn('\u003cb\u003eHi\u003c/b\u003e'.HTMLEncode);           // \u0026lt;b\u0026gt;Hi\u0026lt;/b\u0026gt;\n  WriteLn('\u0026lt;b\u0026gt;Hi\u0026lt;/b\u0026gt;'.HTMLDecode);  // \u003cb\u003eHi\u003c/b\u003e\n\n  // 4) Hex\n  WriteLn('abc'.HexEncode);     // 616263\n  WriteLn('616263'.HexDecode);  // abc\n\n  // 5) Chaining (HTML then URL)\n  WriteLn('\u003cp class=\"x\"\u003e'.HTMLEncode.URLEncode);\nend.\n```\n\nNote on defines scope:\n\n- `{$DEFINE ...}` inside your program controls conditional blocks in your program only. It does not affect how `src/StringKitHelper.pas` is compiled in a separate unit.\n- To actually compile the helper with only `SK_ENCODE`, set defines at the project/build level so the compiler sees them when compiling `StringKitHelper.pas`:\n  - Lazarus/FPC: Project Options \u003e Compiler Options \u003e Custom Options → `-dSK_ANY -dSK_ENCODE`\n\n## 🎨 Start Weaving: Quick Thread Patterns\n\n### 🎨 **Thread Dyeing \u0026 Styling**\n*Transform your raw strings into beautifully styled threads*\n\n```pascal\nvar\n  Text: string;\nbegin\n  // Case conversions\n  Text := TStringKit.ToCamelCase('hello world');     // Returns: 'helloWorld'\n  Text := TStringKit.ToPascalCase('hello world');    // Returns: 'HelloWorld'\n  Text := TStringKit.ToSnakeCase('HelloWorld');      // Returns: 'hello_world'\n  Text := TStringKit.ToKebabCase('HelloWorld');      // Returns: 'hello-world'\n  Text := TStringKit.ToTitleCase('hello world');     // Returns: 'Hello World'\n  \n  // Padding and formatting\n  Text := TStringKit.PadLeft('123', 8, '0');         // Returns: '00000123'\n  Text := TStringKit.PadRight('Name', 10, '.');      // Returns: 'Name......'\n  Text := TStringKit.PadCenter('Hi', 10, '-');       // Returns: '----Hi----'\n  Text := TStringKit.Truncate('Very long text', 10); // Returns: 'Very lo...'\n  Text := TStringKit.CapitalizeText('hello world');  // Returns: 'Hello World'\nend;\n```\n\n### 🔍 **Quality Control \u0026 Pattern Weaving**\n*Inspect your threads and extract beautiful patterns*\n\n```pascal\nvar\n  Matches: TMatchesResults;\n  AllMatches: TStringDynArray;\n  i: Integer;\nbegin\n  // Built-in validators\n  if TStringKit.IsValidEmail('user@example.com') then\n    WriteLn('Valid email');\n  if TStringKit.IsValidURL('https://example.com') then\n    WriteLn('Valid URL');\n  if TStringKit.IsValidIPv4('192.168.1.1') then\n    WriteLn('Valid IPv4');\n  if TStringKit.IsValidDate('2023-12-25', 'yyyy-mm-dd') then\n    WriteLn('Valid date');\n    \n  // Pattern matching and extraction\n  if TStringKit.MatchesPattern('ABC123', '^[A-Z]{3}\\d{3}$') then\n    WriteLn('Matches pattern');\n    \n  // Extract all matches with position info\n  Matches := TStringKit.ExtractMatches('Call 555-1234 or 555-5678', '\\d{3}-\\d{4}');\n  for i := 0 to High(Matches) do\n    WriteLn(Format('Found: %s at position %d', [Matches[i].Text, Matches[i].Position]));\n    \n  // Extract just the matched text\n  AllMatches := TStringKit.ExtractAllMatches('Emails: a@b.com, c@d.net', '\\w+@\\w+\\.\\w+');\n  for i := 0 to High(AllMatches) do\n    WriteLn('Email: ' + AllMatches[i]);\nend;\n```\n\n### 🧬 **Thread Similarity Analysis**\n*Compare and measure the likeness between different thread types*\n\n```pascal\nvar\n  Distance: Integer;\n  Similarity: Double;\nbegin\n  // String distance algorithms\n  Distance := TStringKit.LevenshteinDistance('kitten', 'sitting'); // Returns: 3\n  Distance := TStringKit.HammingDistance('karolin', 'kathrin');     // Returns: 3\n  \n  // Similarity ratios (0.0 to 1.0)\n  Similarity := TStringKit.LevenshteinSimilarity('test', 'best');   // Returns: ~0.75\n  Similarity := TStringKit.JaroSimilarity('MARTHA', 'MARHTA');      // Returns: ~0.94\n  Similarity := TStringKit.JaroWinklerSimilarity('MARTHA', 'MARHTA'); // Higher than Jaro\n  \n  // Fuzzy matching with threshold\n  if TStringKit.IsFuzzyMatch('apple', 'appel', 0.8) then\n    WriteLn('Close match found');\n    \n  // Longest common subsequence\n  WriteLn(TStringKit.LongestCommonSubsequence('ABCDEFG', 'ABDZEFXG')); // Returns: 'ABDEG'\nend;\n```\n\n### 🎵 **Sound Thread Identification**\n*Match threads by their sonic fingerprint*\n\n```pascal\nvar\n  Code1, Code2: string;\nbegin\n  // Soundex for name matching\n  Code1 := TStringKit.Soundex('Robert');  // Returns: 'R163'\n  Code2 := TStringKit.Soundex('Rupert');  // Returns: 'R163'\n  if Code1 = Code2 then\n    WriteLn('Names sound similar');\n    \n  // Metaphone for pronunciation\n  Code1 := TStringKit.Metaphone('knight');   // Returns: 'NT'\n  Code2 := TStringKit.Metaphone('night');    // Returns: 'NT'\n  if Code1 = Code2 then\n    WriteLn('Words sound the same');\nend;\n```\n\n### 🏛️ **Number Thread Artistry**\n*Spin numbers into elegant, readable thread patterns*\n\n```pascal\nvar\n  Roman: string;\n  Number: Integer;\n  Formatted: string;\nbegin\n  // Roman numerals\n  Roman := TStringKit.ToRoman(1994);        // Returns: 'MCMXCIV'\n  Number := TStringKit.FromRoman('MCMXCIV'); // Returns: 1994\n  \n  // File size formatting\n  Formatted := TStringKit.FormatFileSize(1048576);    // Returns: '1.00 MB'\n  Formatted := TStringKit.FormatFileSize(1500000000); // Returns: '1.40 GB'\n  \n  // Number formatting\n  Formatted := TStringKit.FormatNumber(1234567);           // Returns: '1,234,567'\n  Formatted := TStringKit.FormatFloat(12345.67, 2);       // Returns: '12,345.67'\n  Formatted := TStringKit.FormatFloat(1234.5, 3, ',', '.'); // Returns: '1.234,500'\n  \n  // Ordinal and word conversion\n  Formatted := TStringKit.ToOrdinal(21);              // Returns: '21st'\n  Formatted := TStringKit.NumberToWords(123);         // Returns: 'one hundred and twenty-three'\nend;\n```\n\n### 🌐 **Web Thread Preparation**\n*Ready your threads for the digital tapestry of the web*\n\n```pascal\nvar\n  Encoded, Decoded: string;\nbegin\n  // HTML encoding for safe web content\n  Encoded := TStringKit.HTMLEncode('\u003cp class=\"bold\"\u003eText\u003c/p\u003e');\n  // Returns: '\u0026lt;p class=\u0026quot;bold\u0026quot;\u0026gt;Text\u0026lt;/p\u0026gt;'\n  \n  Decoded := TStringKit.HTMLDecode('\u0026lt;p\u0026gt;Hello \u0026amp; World\u0026lt;/p\u0026gt;');\n  // Returns: '\u003cp\u003eHello \u0026 World\u003c/p\u003e'\n  \n  // URL encoding for web parameters\n  Encoded := TStringKit.URLEncode('Hello World!');     // Returns: 'Hello+World%21'\n  Decoded := TStringKit.URLDecode('Hello+World%21');   // Returns: 'Hello World!'\n  \n  // Base64 encoding/decoding\n  Encoded := TStringKit.Encode64('foo');               // Returns: 'Zm9v'\n  Decoded := TStringKit.Decode64('Zm8=');              // Returns: 'fo'\n  \n  // Hexadecimal encoding\n  Encoded := TStringKit.HexEncode('Hello');            // Returns: '48656C6C6F'\n  Decoded := TStringKit.HexDecode('48656C6C6F');       // Returns: 'Hello'\nend;\n```\n\n### 📊 **Thread Analysis \u0026 Insights**\n*Examine your woven text like a master craftsperson*\n\n```pascal\nvar\n  WordCount: Integer;\n  Readability: Double;\n  NGrams: TStringDynArray;\n  i: Integer;\nbegin\n  // Basic text statistics\n  WordCount := TStringKit.CountWords('Hello, world! How are you?'); // Returns: 5\n  \n  // Readability scoring (0-100, higher = easier)\n  Readability := TStringKit.FleschKincaidReadability('The quick brown fox jumps.');\n  WriteLn(Format('Readability score: %.1f', [Readability]));\n  \n  // N-gram generation for NLP\n  NGrams := TStringKit.GenerateNGrams('the quick brown fox', 2); // Bigrams\n  for i := 0 to High(NGrams) do\n    WriteLn('Bigram: ' + NGrams[i]);\n  // Output: 'the quick', 'quick brown', 'brown fox'\nend;\n```\n\n### 🛠️ **Master Weaver's Essential Tools**\n*The fundamental techniques every string artisan must know*\n\n```pascal\nvar\n  Parts: TStringDynArray;\n  Joined: string;\n  i: Integer;\nbegin\n  // Splitting and joining\n  Parts := TStringKit.Split('apple,banana,cherry', ',');\n  for i := 0 to High(Parts) do\n    WriteLn('Part: ' + Parts[i]);\n    \n  Joined := TStringKit.Join(Parts, ' | '); // Returns: 'apple | banana | cherry'\n  \n  // Text replacement\n  Joined := TStringKit.ReplaceText('Hello World', 'World', 'Pascal');\n  // Returns: 'Hello Pascal'\n  \n  Joined := TStringKit.ReplaceRegEx('Phone: 123-456-7890', '(\\d{3})-(\\d{3})-(\\d{4})', '($1) $2-$3');\n  // Returns: 'Phone: (123) 456-7890'\n  \n  // String testing\n  if TStringKit.StartsWith('Hello World', 'Hello') then\n    WriteLn('Starts with Hello');\n  if TStringKit.EndsWith('test.txt', '.txt') then\n    WriteLn('Is a text file');\n  if TStringKit.Contains('Hello World', 'World') then\n    WriteLn('Contains World');\n    \n  // Text cleaning\n  Joined := TStringKit.CollapseWhitespace('  Multiple   spaces  '); // Returns: ' Multiple spaces '\n  Joined := TStringKit.RemoveWhitespace('  No spaces  ');          // Returns: 'Nospaces'\n  \n  // String extraction and manipulation\n  Joined := TStringKit.LeftStr('Hello World', 5);     // Returns: 'Hello'\n  Joined := TStringKit.RightStr('Hello World', 5);    // Returns: 'World'\n  Joined := TStringKit.SubString('Hello World', 7, 5); // Returns: 'World'\n  Joined := TStringKit.DuplicateText('Hi! ', 3);      // Returns: 'Hi! Hi! Hi! '\n  \n  // String analysis\n  WriteLn(TStringKit.GetLength('Hello'));             // Returns: 5\n  WriteLn(TStringKit.CountSubString('ababab', 'ab')); // Returns: 3\nend;\n```\n\n## 📂 Working Examples\n\nThe `examples/` folder contains ready-to-run programs demonstrating StringKit-FP features:\n\n### 🎨 StringKitExample\n\nA comprehensive demonstration program showing all major StringKit-FP functionality:\n\n```bash\nfpc -Fu./src ./examples/StringKitExample/StringKitExample.pas\n./StringKitExample\n```\n\nThis example covers:\n\n- Basic string operations (trim, case conversion, padding)\n- Pattern matching and validation\n- String similarity algorithms\n- Text analysis and formatting\n- Web encoding (HTML, URL, Base64)\n- Number formatting and conversion\n\n### 🔧 Selective Feature Examples\n\nFor selective feature compilation using feature flags:\n\n**CaseAndEncodeDemo** - Compile with only CASE and ENCODE features:\n\n```bash\nfpc -dSK_ANY -dSK_CASE -dSK_ENCODE -Fu./src ./examples/directives/CaseAndEncodeDemo.pas\n./CaseAndEncodeDemo\n```\n\n**EncodeOnlyDemo** - Compile with only ENCODE feature:\n\n```bash\nfpc -dSK_ANY -dSK_ENCODE -Fu./src ./examples/directives/EncodeOnlyDemo.pas\n./EncodeOnlyDemo\n```\n\nThese examples demonstrate the modular helper system and how to build lightweight custom versions of StringKit-FP.\n\n## 🚨 Common Beginner Questions\n\n**Q: Why does `.Trim` not work on my string?**\n\nA: Make sure you have `StringKitHelper` in your `uses` clause. Without it, you must use `TStringKit.Trim()` instead.\n\n```pascal\nuses StringKit, StringKitHelper;  // Add StringKitHelper to enable instance methods\n\nS := '  hello  '.Trim;  // Now this works!\n```\n\n**Q: Can I use just the static methods without the helper?**\n\nA: Absolutely! The helper is optional. Use `TStringKit.FunctionName()` for static method calls without importing StringKitHelper.\n\n```pascal\nuses StringKit;  // Helper not needed for static methods\n\nS := TStringKit.Trim('  hello  ');  // This always works\n```\n\n**Q: What's the difference between the two approaches?**\n\n| Approach | Style | Requires StringKitHelper | Example |\n|----------|-------|------------------------|---------|\n| Instance-style | Modern, fluent | ✅ Yes | `'hello'.Trim` |\n| Static method | Traditional | ❌ No | `TStringKit.Trim('hello')` |\n\nBoth are equally valid - choose whichever you prefer!\n\n## 📖 System Requirements\n\n### Tested Environments\n\n| Module                          | Windows 11 | Ubuntu 24.04.2 |\n|---------------------------------|------------|----------------|\n| StringKit                 | ✅         | ✅             |\n\n### Dependencies\n\n- Windows\n  - No external dependencies required\n- Linux\n  - No external dependencies required\n- Uses only standard Free Pascal RTL units\n\n### Build Requirements\n\n- Free Pascal Compiler (FPC) 3.2.2+\n- Lazarus 4.0+\n- Basic development tools (git, terminal, etc)\n\n## 📚 Documentation\n\nFor detailed documentation, see:\n\n- 📋 [Cheat Sheet](docs/cheat-sheet.md)\n- 📝 [StringKit Helper Coverage](docs/stringkit-helper-coverage.md)\n \n\n## ✅ Testing\n\n1. Open the `TestRunner.lpi` using Lazarus IDE\n2. Compile the project\n3. Run the Test Runner:\n\n```bash\n$ cd tests\n$ ./TestRunner.exe -a --format=plain\n```\n\n## 🧭 **Future Weaving Patterns**\n\n*Our roadmap for expanding the string artisan's toolkit*\n\n- Remove custom types and use RTL types\n- Introduce custom method for hashing\n- Enhance multi-byte character weaving for global text tapestries\n- Seamless support for Free Pascal and Lazarus package managers\n\n\n## 🤝 **Join the Weaving Circle**\n\n*Every master weaver started as an apprentice - your contributions help strengthen our tapestry!*\n\nContributions are warmly welcomed! Whether you're adding new thread patterns, fixing loose ends, or improving our weaving techniques, please feel free to submit a Pull Request. For major pattern changes, please open an issue first to discuss your vision.\n\n1. **Fork the Loom** - Fork the Project\n2. **Create your Pattern** - Create your Feature Branch (`git checkout -b feature/AmazingThreadPattern`)\n3. **Weave your Changes** - Commit your Changes (`git commit -m 'Add beautiful new thread pattern'`)\n4. **Share your Work** - Push to the Branch (`git push origin feature/AmazingThreadPattern`)\n5. **Present to the Guild** - Open a Pull Request\n\n## ⚖️ License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE.md) file for details.\n\n## 🙏 **Honoring Our Thread Masters**\n\n*Standing on the shoulders of giants who wove the foundation*\n\n- **🏛️ The FPC Guild** - For crafting the magnificent Free Pascal loom\n- **🧵 Fellow Weavers** - All contributors and maintainers who help strengthen our tapestry\n- **🎨 String Artisans Everywhere** - The community that inspires continuous innovation\n\n\n\n---\n\n*🧶 **Ready to start weaving?** Your feedback helps us craft better tools! Visit our [thread workshop](https://github.com/ikelaiah/stringkit-fp/issues) to share ideas, report loose threads, or track our weaving progress.*\n\n---\n\n**✨ Happy String Weaving! ✨**\n\n*\"In every thread lies infinite possibility, in every string a story waiting to be told.\"*","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fikelaiah%2Fstringkit-fp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fikelaiah%2Fstringkit-fp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fikelaiah%2Fstringkit-fp/lists"}