lolli42/finediff
Create HTML diffs between two strings with fine-grained character or word comparison. Outputs / markup, escapes HTML entities, supports multibyte strings, and exposes internal opcodes for diff processing. PHP 8.2+ in v1.1.
Install via Composer: composer require lolli42/finediff. Once installed, the core usage is straightforward: compare two strings ($old and $new) and get a diff or patch.
First use case: generate a human-readable diff in a console command:
use FineDiff\Generator\Generator;
use FineDiff\Parser\Parser;
$generator = new Generator();
$diff = $generator->getDelta($oldContent, $newContent); // e.g., '=Hello world.' ( '=' = keep, '+' = insert, '-' = delete )
For patch-based workflows (reversible change storage), generate and apply patches:
$parser = new Parser();
$patch = $parser->getDelta($oldContent, $newContent); // raw patch string (e.g., '=Hel=lo -w +W or=ld!')
// Later...
$reconstructed = $parser->applyPatch($oldContent, $patch);
Check the GitHub repo’s README for basic examples—though minimal, it covers the two primary flows: getDelta() and applyPatch().
getDelta() results when editing models (e.g., in an updated model event), store patches in a content_versions table for lightweight version history.old_text and new_text, return structured diff (e.g., JSON with insert/delete regions) for frontend clients to highlight changes.$final = applyPatch($initial, composePatches($patches))) for version rollbacks or rebasing.Tokenization control matters: FineDiff supports custom tokenizers. For example, use word-level granularity for editorial workflows:
$parser = new Parser(new Tokenizer\WordTokenizer());
$patch = $parser->getDelta($old, $new);
For large-scale diff generation (e.g., document comparison), batch diffs and store them asynchronously via queued jobs.
=Hel=lo -w +W or=ld!). To debug, use the Generator's output for display, or create a simple visualizer mapping ops to colorized HTML spans.getDelta() without a tokenizer, changes may split multibyte characters (e.g., emojis, Cyrillic). Always supply Tokenizer\CharTokenizer() or custom tokenizer for UTF-8 content.WordTokenizer, you must use the same tokenizer to apply it—mismatched tokenization leads to corruption.strlen($old) + strlen($new) < X).DiffService singleton or helper to wrap tokenization, diff generation, and patching—especially useful if you re-use tokenizer settings across your app (e.g., WordTokenizer for blog post edits).assertEquals($expectedPatch, $actualPatch) in unit tests, but also assert $parser->applyPatch($base, $patch) === $target to validate round-trip correctness.How can I help you explore Laravel packages today?