Skip to content

Releases: sergey-tihon/Clippit

3.9.0 - August 12, 2026

Choose a tag to compare

@github-actions github-actions released this 12 Aug 08:12
  • perf: optimize immutable lookups, dictionary access, enumeration, and string slicing across Excel, HTML, PowerPoint, and Word (#444, #445, #448, #450, #451, #452, #454, #459, #462, #463, #466, #470)
  • refactor: modernize core types and remove dead code/debug scaffolding from production and tests (#443, #456, #458, #459, #461)
  • test(common): add StrictOoxmlTranslator coverage (#447)
  • chore(deps): update SkiaSharp 4.150.1 → 4.151.1, TUnit 1.59.0 → 1.64.13, JsonSchema.Net 9.2.2 → 9.4.0, and System.CommandLine preview.5 → preview.7 (#442, #455, #457, #463, #467, #469)
  • chore(ci): bump actions/setup-dotnet from 5 to 6 (#446)

3.8.0 - July 19, 2026

Choose a tag to compare

@github-actions github-actions released this 20 Jul 06:03
910b61e
  • feat(cli): add clippit install --skills command to install bundled Clippit workspace skills for OpenCode, Pi, and Claude Code assistants
  • perf: convert static readonly Dictionary to FrozenDictionary in PowerPoint and Word (#434)
  • perf: convert static readonly Dictionary to FrozenDictionary in Word and Html (#435)
  • perf: convert static readonly Dictionary to FrozenDictionary in Excel, Html, and Word (#437)
  • perf(word): use Dictionary for O(1) image deduplication in DocumentBuilder (#428)
  • test(common): strengthen MetricsGetter tests with structural assertions (MG002-MG014) (#436)
  • test+refactor: StringExtensions.SplitAndKeep tests + fr_FR dead code removal (#430)
  • chore(deps): update SkiaSharp 4.148.0 → 4.150.0 (#429)
  • chore(deps): update SkiaSharp 4.150.0→4.150.1, TUnit 1.58.0→1.59.0, Test.Sdk 18.7.0→18.8.1 (#431)
  • chore(deps): bump actions/setup-node from 6 to 7 (#433)

3.7.0 - July 12, 2026

Choose a tag to compare

@github-actions github-actions released this 12 Jul 08:25
  • feat(cli): add clippit word build init/run command (#422)
  • feat(cli): add clippit excel create command (#423)
  • feat: add clippit word consolidate command (#419)
  • feat(word): add RegisterCustomHandler extensibility to DocumentAssembler (#417)
  • feat(cli): add clippit word simplify-markup command (#412)
  • feat(cli): add clippit word assemble command (#405)
  • feat(cli): add clippit word accept-revisions command (#406)
  • perf(word): fix image deduplication in DocumentBuilder (#415)
  • fix(excel): correct dimension element and table id in SpreadsheetWriter (#425)
  • fix(excel): keep tableColumns count in sync when data rows are wider than headings (#404)
  • fix(word): respect xml:space="preserve" in UnicodeMapper.RunToString (#411)
  • fix: correct OpenXmlRegex matching with lastRenderedPageBreak (#409)
  • fix(word): correct DocumentAssembler xml:space preservation for content text (#408)
  • fix: isolate Sample2 output dirs to prevent parallel test collision
  • test(cli): add JSON contract tests for word assemble, consolidate, and excel create (#427)
  • test: add OpenXmlRegex callback/delete tests and PPTX TextReplacer tests (#426)
  • docs: split CLI docs by format (#413)
  • ci: migrate NuGet publish to trusted publishing (OIDC) (#407)

3.6.0 - July 4, 2026

Choose a tag to compare

@github-actions github-actions released this 04 Jul 08:15
  • feat(word): add German and Spanish localized list-item text getters (de-DE, es-ES) (#389)
  • feat(cli): add word compare command for DOCX diff (#365)
  • feat(cli): add Windows ARM64 npm binary (#363)
  • feat(cli): add Linux ARM64 npm binary (#360)
  • perf: use FrozenSet<T> for HashSet lookups (#361)
  • perf: convert Dictionary to FrozenDictionary (#362)
  • perf: replace remaining List<T> with FrozenSet<T> in PtOpenXmlUtil (#371)
  • fix: guard TextReplacer against IndexOutOfRangeException on empty replacement string (#381)
  • fix(word): add Optional="true" support to Conditional directive in DocumentAssembler (#382)
  • feat(word): add HeaderRowCount attribute to DocumentAssembler Table directive for multi-row headers (#387)
  • fix: guard WmlComparer.HashBlockLevelContent against ArgumentNullException from missing pt:Unid attributes (#380)
  • fix: guard WmlComparer.FindIndexOfNextParaMark against InvalidCastException from non-ComparisonUnitWord units (#385)
  • fix(html): preserve w:anchor fragment on external hyperlinks — append #anchor when the URL has no existing fragment (#384)
  • fix(html): correct rowspan for vertically merged cells when preceding cells use w:gridSpan (#383)
  • fix(pptx): handle ExtendedPart chart workbooks in CopyChartObjects and CopyExtendedChartObjects — prevents silent data loss when a chart's external data relationship resolves to an ExtendedPart (#388)
  • refactor: modernize == null/!= null to is null/is not null across 20+ files (#349, #350, #352, #353, #355, #356)
  • test: add FieldRetriever.ParseField unit tests FR001–FR010 (#354)
  • test: add regression tests for TextReplacer empty-string replacement TR007–TR008 (#381)
  • test: add regression tests for WmlComparer defensive fixes WC380, WC385 (#380, #385)
  • chore(deps): update TUnit 1.56.35 → 1.57.17 (#351, #359, #369)
  • chore(ci): update actions/checkout v6 → v7 (#347)

3.5.1 - June 23, 2026

Choose a tag to compare

@sergey-tihon sergey-tihon released this 04 Jul 07:44
0ec3a78
  • chore(deps): update SkiaSharp 3.119.4 → 4.148.0 with migration fix (#346)
  • chore(deps): update Microsoft.NET.Test.Sdk 18.6.0 → 18.7.0 (#346)
  • chore(deps): update dotnet-outdated-tool 4.7.1 → 4.8.1 (#346)
  • chore(deps): update csharpier 1.2.6 → 1.3.0 (#346)
  • chore(deps): update System.CommandLine 3.0.0-preview.4 → preview.5 (#346)
  • fix: replace deprecated SKPaint.MeasureText with SKFont.MeasureText for SkiaSharp 4.x compatibility (#346)

3.5.0 - June 20, 2026

Choose a tag to compare

@sergey-tihon sergey-tihon released this 04 Jul 07:43
b307784
  • feat: replace SixLabors.ImageSharp with SkiaSharp for all image processing (#341)
  • feat: add Linux native SkiaSharp asset support (SkiaSharp.NativeAssets.Linux.NoDependencies) (#341)
  • fix(html): guard null srcAttribute in LoadImageForTransform to prevent NullReferenceException (#341)
  • fix(html): encode image before adding ImagePart to prevent dangling empty relationship on encode failure (#341)
  • fix(docs): update WmlToHtmlConverter tutorial from ImageSharp to SkiaSharp API (#341)
  • fix(docs): add using SkiaSharp; note in tutorial code sample (#341)
  • refactor: replace Image.Load/Image.Save with SKBitmap.Decode/SKImage.Encode across all converters and helpers (#341)
  • refactor: replace SixLabors.Fonts text measurement with SKTypeface/SKPaint.MeasureText in MetricsGetter and PtOpenXmlUtil (#341)
  • refactor: use safe fallback chain for GetTextWidthArgumentException catch now works correctly after removing blanket catch in _getTextWidth (#341)
  • fix(cli): use FileMode.Create instead of FileMode.OpenOrCreate in DefaultImageHandler to avoid corrupted image on re-encode (#341)
  • fix(cli): return null instead of null! in CreateInlineImage failure paths (#341)
  • fix(test): add explicit null-check with InvalidOperationException in BuildTestPng SkiaSharp encode (#341)
  • perf: wrap SKTypeface/SKFont/SKImage with using to prevent native handle leaks (#341)
  • chore(deps): remove SixLabors.ImageSharp.Drawing dependency (#341)
  • chore(deps): add SkiaSharp 3.119.4 (#341)

3.4.7 - June 16, 2026

Choose a tag to compare

@sergey-tihon sergey-tihon released this 16 Jun 15:42
  • feat(cli): add word to-html, word from-html, and excel to-html commands (#338)
  • fix(powerpoint): support ISO/IEC 29500 Strict OOXML presentations — translate Strict namespace URIs lazily via XmlReader wrapper in GetXDocument() (#339)
  • fix(powerpoint): translate <a:graphicData uri=…> content-type URIs and fix source XDocument mutation in CopyPresentationParts (#340)
  • refactor: modernize as + null-check to is not pattern matching in WmlToHtmlConverter and WmlToXml (#336)
  • chore(deps): update TUnit 1.49.0 → 1.54.0 (#337)

3.4.6 - June 10, 2026

Choose a tag to compare

@sergey-tihon sergey-tihon released this 10 Jun 19:32
  • feat(cli): add word verify and excel verify commands (#329)
  • fix(html): convert w:pageBreakBefore paragraph property to CSS page-break-before (#325)
  • refactor: modernize as + null-check to is not pattern matching in OpenXmlRegex (#315)
  • chore(deps): update TUnit 1.48.6 → 1.49.0 (#327)
  • chore(deps): update JsonSchema.Net 7.4.0 → 9.2.1 (#317)

3.4.5 - June 3, 2026

Choose a tag to compare

@sergey-tihon sergey-tihon released this 03 Jun 20:24
510a612
  • feat: add Clippit CLI — pptx split, pptx build, pptx verify, and version commands (#309)
  • fix(pptx): fix PowerPoint relationship copying edge cases — prevent missing parts after slide copy (#312)
  • fix(cli): set AssemblyName=clippit to avoid NativeAOT rename on Windows
  • fix(cli): use $(ExeSuffix) in RenameNativeAotExecutable MSBuild target
  • fix(cli): fix npm publishing workflow
  • refactor: modernize as + null-check to is not pattern matching in RevisionProcessor (#307)
  • refactor: modernize as + null-check to is not pattern matching in MarkupSimplifier (#308)
  • test(excel): expand WorksheetAccessor tests — SetCellValue/GetCellValue round-trips WA004–WA013 (#314)
  • chore(deps): update TUnit 1.47.0 → 1.48.6 (#313)
  • docs: add README for Clippit.Cli NuGet tool and npm clippit package (#320)
  • docs: restore classic Clippy hero image and redesign homepage with retro Clippy speech bubble

3.4.4 - May 20, 2026

Choose a tag to compare

@sergey-tihon sergey-tihon released this 20 May 15:16
  • fix(pptx): prevent NullReferenceException in GetSlideTitle when cSld/spTree is missing (#287)
  • fix(html): render Word page breaks as CSS page-break div in HTML output (#281)
  • fix(word): RemoveSoftHyphens and RemoveLastRenderedPageBreak in MarkupSimplifier were silently ignored (#284)
  • perf: replace ToUpper()+StartsWith() with OrdinalIgnoreCase comparisons (#282)
  • perf: replace .Where(pred).Count() with .Count(pred) and Count()!=1 with Skip(1).Any() (#270)
  • perf: replace ContainsKey+indexer double-lookups with TryGetValue (#274)
  • refactor: modernize GetListItemText locale files (#283)
  • refactor: modernize UnicodeMapper.cs (#278)
  • refactor: modernize Word/Assembler helper files (#275)
  • refactor: modernize MetricsGetter.cs — file-scoped namespace, is null/is not null, pattern matching (#273)
  • refactor: modernize FieldRetriever.cs — file-scoped namespace, W.* constants, is null, slices, TryGetValue (#272)
  • refactor: simplify Select().SelectMany() chains in WmlComparer to SelectMany() (#271)
  • refactor: simplify FileUtils.GetFilesRecursive using SearchOption.AllDirectories (#268)
  • refactor: modernize null checks to use ArgumentNullException.ThrowIfNull (#265)
  • test: add unit tests for OpenXmlPowerToolsDocument and OpenXmlMemoryStreamDocument (OXD001–OXD040) (#266)
  • test: add ReferenceAdder unit tests (RA100–RA140) and fix AddTof w:dirty namespace bug (#263)
  • chore(deps): update TUnit 1.43.11 → 1.45.8 (#264, #267, #276, #277)