Notes de version

Les 15 dernières versions de DocToolkit, de la plus récente à la plus ancienne, telles que publiées sur GitHub.

Les notes de version sont rédigées en anglais.

v0.61.0

Sur GitHub

Ajouts

  • Core: DocxFormField.IsLocked is true when a content control's content is locked (w:lock set to contentLocked or sdtContentLocked), which is exactly when DocxForm.Fill refuses to write it. A form UI can grey the field out instead of finding out from an exception.
  • Core: DocxFormIssueKind.LockedControl (value 10).

Modifications

  • Core: DocxForm.Fill now writes a control locked only against deletion (sdtLocked), as Word does, and keeps the lock. Since 0.54.0 it refused all three lock kinds alike.
  • Core: DocxForm.Validate reports a value aimed at a content-locked control as DocxFormIssueKind.LockedControl; it reported Other before. A consumer that switched on Other for locks needs the new case.

v0.60.1

Sur GitHub

Modifications

  • Both packages gain the NuGet tag to. NuGet search requires every word of a query, and it ignores "to" in a title or description, so searches such as html to pdf and docx to pdf could not find either package. Only a package id or a tag that is exactly to can match that word.

v0.60.0

Sur GitHub

Ajouts

  • Core: Arabic, Persian and Urdu letters take their joined forms in PDF when you pass PdfFontOptions, in DOCX, XLSX and PPTX to PDF (HTML to PDF goes through DOCX). DocToolkit now rewrites each letter into its Unicode presentation form before rendering, so the result no longer depends on the renderer's own shaping. Without fonts nothing changes. - The supplied font must cover Arabic Presentation Forms-B (and -A for Persian letters). The Windows versions of Arial, Tahoma, Segoe UI and Times New Roman do. - A few letters, such as ۃ and ە, have no presentation form, so joining stops next to them. - Copy and search return the base letters, and a word with a lam-alef ligature can come back in visual order. - In XLSX, formulas are calculated before shaping, so =LEN(A1) and =IF(A1="…",…) see the original text. - A worksheet's right-to-left direction is still ignored.

Modifications

  • Core: with PdfFontOptions, a Hebrew line now comes out in reading order in DOCX, XLSX and PPTX to PDF. Before, each word was right but a line of several words printed them in reverse.
  • Core: DocxToPdfPreflight reports one kind of finding, not three. Footnotes and content controls in a table cell render since OfficeIMO 3.5, so the Footnote and ControlInCell findings are gone; NestedTable stays. Code that checks a finding's code for those two strings no longer sees them.
  • Core: a watermark on a merged document now stamps every section.
  • Core: documents OfficeIMO 3.5.3 refuses are repaired and rendered again. A document that renders as it is never takes these repairs. The causes covered: empty hyperlink text, a header taller than a small top margin, tiny percentage table widths, empty table columns, cell padding wider than its column, indents wider than their column, and list-marker tabs past the cell edge.
  • Core: two repairs run on every DOCX to PDF conversion. A bullet level that substitutes a Symbol or Wingdings glyph is drawn in Arial, which has the bullet, and C0/C1 control characters are removed from text.
  • Core: a fixed-width table wider than its section's text area is scaled to fit. A few wide tables still run off the page.
  • Core: each DOCX render runs on its own thread with a 16 MB stack, so the depth a document needs no longer depends on the caller's thread. OfficeIMO 3.5.3's frames are large (about 4 KB each), and .NET 8 on macOS gives a secondary thread only 512 KB; a stack overflow cannot be caught.
  • Both packages carry a NuGet title that names their task: "DocToolkit - HTML to PDF and DOCX to PDF converter for .NET (also XLSX, PPTX, Markdown)" and "DocToolkit dependency injection - HTML to PDF and DOCX to PDF for ASP.NET Core".
  • Dependencies: OfficeIMO 3.5.3 brings OfficeIMO.Html.AngleSharp, OfficeIMO.Html.Core and System.Text.Encoding.CodePages, and AngleSharp 1.8.3. OfficeIMO.Core's licence is now "MIT AND Apache-2.0 AND BSD-3-Clause". THIRD-PARTY-NOTICES.txt lists them, and a new *Vendored code* section carries the MIT notice for the Arabic forms table copied from OfficeIMO.

v0.52.0

Sur GitHub

Ajouts

  • Core: a PDF's words and images can now be read with their positions. PdfEditor.ExtractText answers what a page says; ExtractWords answers where it says it, and ExtractImages returns the pictures it draws. Both return one list per page - [0] is page 1 - matching ExtractText, with byte[], Stream and file-path forms. Three new types carry the results: PdfWord, PdfImage and PdfBounds. Coordinates start at the page's BOTTOM-left, which is the PDF convention rather than a screen one: a word near the top of A4 has a Bottom near 842, not near 0. One point is 1/72 inch. PdfImage.Png is null when the pixels could not be re-encoded, and that is a normal outcome rather than an error - one image in an unusual colour space does not cost you the rest of the document. Check it before use. Those bytes are also a re-encoding, not the embedded file, so they are not byte-identical to an original PNG or JPEG and the byte count usually differs. A page with no text layer yields an empty list. A scanned document is images; OCR remains out of scope. Nothing existing changed or was removed. The dependency-injection mirror follows in the next release: the extensions package builds against the published core.

v0.59.0

Sur GitHub

Modifications

  • Extensions: if you set DocToolkitOptions.Fonts and convert XLSX or PPTX to PDF, this changes your output. IXlsxToPdfConverter and IPptxToPdfConverter ignored the setting until now, because the core converters took no fonts before 0.58.0. They now use yours, read on every call, as IDocxToPdfConverter and IHtmlToPdfConverter already did. Supplied fonts replace the host's fallbacks rather than adding to them, so a list that covers less than your workbooks and presentations use can refuse text the host's fonts used to cover. Supplying fonts also turns on Hebrew and Arabic shaping, with the limits listed under 0.58.0. Clear Fonts if you relied on the host's fonts.
  • Extensions: the package now requires Ank.DocToolkit 0.58.0 or later.

v0.58.0

Sur GitHub

Ajouts

  • Core: XLSX and PPTX to PDF take fonts. XlsxToPdfConverter and PptxToPdfConverter gain Convert(byte[], PdfFontOptions?) and ConvertAsync(Stream, Stream, PdfFontOptions?, CancellationToken), matching DOCX and HTML. Until now a workbook or presentation holding text the renderer's built-in fonts cannot draw — Cyrillic, Hebrew, Arabic, CJK — could be refused with an exception, depending on the host's fonts, and there was no way to supply one. Passing null gives exactly the old render.

Modifications

  • Core: if you already pass PdfFontOptions to DOCX or HTML to PDF, Hebrew and Arabic output changes. Supplying fonts now also turns on the renderer's text shaping, on every path that takes fonts. Each Hebrew or Arabic word now prints in the right letter order, and Arabic letters join; before, the letters of every word were reversed and Arabic did not join. Text with no right-to-left script renders byte-identical to 0.57.3 — measured over 83 real documents.
  • The README, the NuGet package page and the documentation site now name WillowAnk Solution, the company that maintains DocToolkit. PackageProjectUrl points to https://wanksolution.com/; RepositoryUrl still points to GitHub, where issues and source live.

Known limits of right-to-left text, stated here because "shapes Hebrew and Arabic" promises more

  • Words are laid out, lines are not. A line of several right-to-left words prints its words in reverse order, and a number lands on the wrong side. This is the renderer's behaviour, measured from glyph positions; a w:bidi paragraph behaves the same.
  • Persian and Urdu letters are not shaped. A word containing پ چ ژ گ ک ی still renders reversed and unjoined. Arabic-only words in the same text are shaped.
  • A right-to-left sheet is not mirrored. <sheetView rightToLeft="1"> is ignored, so column A prints on the left. Merged cells are honoured.
  • Markdown to PDF takes no fonts, so it gets no shaping.

v0.57.3

Sur GitHub

Corrections

  • lift System.Security.Cryptography.Xml to 10.0.13 past five advisories (C43)

v0.57.2

Sur GitHub

Corrections

  • Neither package's code changed since 0.57.1. This release carries repository tooling only.
  • The Linux container test job now has a .dockerignore, so it can no longer pass by reusing build output copied in from the host.
  • Build and test tooling updated: docfx 2.81.0, Stryker 5.0.0, coverlet 10.1.0 and Microsoft.NET.Test.Sdk 18.10.1. None of these ships inside either package.

v0.57.1

Sur GitHub

Corrections

  • core: count drawing ids in the comments part when inserting an image

v0.57.0

Sur GitHub

Ajouts

  • extensions: mirror document comparison on IDocxCompare (A118-DI)

v0.56.0

Sur GitHub

Ajouts

  • Core: DocxCompare compares two versions of a document and returns the later one with the differences marked as tracked changes. The result is an ordinary .docx carrying revisions, not a report, so Word shows it the way it shows any tracked-changes document and DocxReview reads it back without knowing where it came from — DocxReview.Inspect lists the revisions on the report it returns, and DocxReview.AcceptRevisions / RejectRevisions resolve them.
  • Core: DocxCompare.CompareWithReport returns the same document plus a warning naming every construct that was present but not compared. Read it — HasLoss is the signal that the comparison covers less than the document does.

Known limits of DocxCompare, stated here because the name promises more

  • Paragraph text is what gets compared. Tables are reported, never diffed — a row inserted mid-table is not the same edit as its text appearing elsewhere, and marking it as one would be a wrong answer rather than a coarse one.
  • A formatting-only change is not detected at all, and is not reported as a text change either. A paragraph whose text is unchanged but whose styling differs produces no revision.
  • Paragraphs are paired by position, so a paragraph inserted or removed in the middle shifts every pair after it and its neighbours read as heavily rewritten. That case is reported.
  • Per-run formatting inside a REWRITTEN paragraph is not preserved — the first run's properties are carried onto the rebuilt runs. An unchanged paragraph is left completely alone, so a document compared with itself produces no revisions and keeps every run as it was.

v0.55.0

Sur GitHub

Ajouts

  • Core: DocxFormField now reports a content control's alias. Alias is the display name Word itself shows a human (w:alias). It is not Key, which is whichever name DocxFormKey resolved for matching and is usually the tag - an identifier the template's author chose for code. An application rendering a form wants the alias. Empty when the control has no alias, and also when the key is ambiguous. Word does not require either name to be unique; where one key reaches two controls with different aliases this reports nothing rather than picking one and being silently wrong half the time. DocxForm.Validate already reports that case as DuplicateKey. Two controls sharing a key *and* an alias are not ambiguous about the alias, and it is still reported. Whether a control is LOCKED is still not reported, and that is a deliberate limit rather than an oversight - the underlying library exposes the alias but neither the lock nor the element to read one from. Since 0.54.0 DocxForm.Fill refuses to write a locked control, so a lock is at least safe to discover by attempting the fill.
  • Extensions: IDocxEditor mirrors the Regex overloads of ReplaceText added to the core in 0.54.0 - the byte[] form and its Stream form - so pattern-based find-and-replace is reachable through dependency injection rather than only through the static class. Three things a caller gets wrong without being told, now stated on the interface: the replacement is a template in which $1 expands to a captured group and a literal $ is $$, zero-width matches are skipped, and a Regex built without a match timeout is refused rather than accepted.

v0.54.0

Sur GitHub

⚠ BREAKING CHANGES

  • Core: DocxForm.Fill refuses to fill a content control the document locks. A fill that would change a locked control now throws InvalidOperationException and writes nothing; the document you pass in is untouched, and a Stream overload writes zero bytes to its destination. It previously succeeded - and left the w:lock in place, so the result declared the control protected while its content had been replaced. That file contradicted itself, no reader could see it, and the caller had no way to detect it afterwards. Measured against sdtContentLocked, sdtLocked and contentLocked. What to do: remove the lock in Word, or leave that control out of the values you pass. Filling other controls in a document that also contains a locked one is unaffected and still works - which is the ordinary case for a template that locks its headings. This is why 0.54.0 is a minor bump rather than a patch. See *Migrating* in the README. Locks are not read, reported or removed by this change. DocxFormField still exposes Key and Value alone; a caller cannot yet tell a locked control from an editable one without attempting the fill.

v0.53.0

Sur GitHub

Ajouts

  • Core: DocxEditor.ReplaceText can match a regular expression, not just literal keys. A new overload takes a Regex and a replacement template, with a Stream form beside it, and applies across the body, headers, footers, footnotes and endnotes exactly as the literal overload does. Anything whose shape is known but whose text is not - dates, reference numbers, whitespace - now has an entry point. The replacement is a TEMPLATE, not a literal. $1 and friends expand to captured groups the way Regex.Replace expands them, so a literal $ must be written $$. The pattern must carry a match timeout, and one without is refused with an ArgumentException rather than accepted. A catastrophically backtracking expression has no upper bound on its running time, and a hang is worse than a failure because the caller cannot catch it. Construct it as new Regex(text, RegexOptions.None, TimeSpan.FromSeconds(1)). Formatting behaves exactly as it already did for literal keys: where a match spans several runs, the replacement is written into the run holding its first character and inherits that run's formatting. Zero-width matches are skipped, because one consumes no characters. Nothing existing changed. The literal overload is untouched, and both now share one implementation of the run-splicing step rather than two that could drift.
  • Extensions: IPdfEditor mirrors ExtractWords and ExtractImages from core 0.52.0, with their Stream forms - four members, so the PDF word-position and image extraction added last release is now reachable through dependency injection. Two things a caller gets wrong without being told, and which the interface documentation now states: coordinates are measured from the page's bottom-left, so a word near the top of A4 has a Bottom near 842 rather than near 0; and PdfImage.Png is null when the pixels could not be re-encoded, which is a normal outcome rather than an error.

v0.51.0

Sur GitHub

Ajouts

  • Extensions: the dependency-injection interfaces caught up with everything 0.50.0 added to the core. IDocxEditor gains the eight watermark and bookmark members, IPresentationEditor the four speaker-notes members, and IDocToDocxConverter gains ConvertWithReportAsync — thirteen in all, each a thin wrapper over the core static method of the same name. This release contains no core change. The extensions package references the *published* core, so a mirror can never ship in the same release as the member it wraps; it is structurally one release behind. If you use the static classes directly, there is nothing here for you. Worth knowing if you tracked the gap: ConvertWithReportAsync was the one mirror nobody filed a ticket for. It was found by the interface-completeness test the moment the package floor was bumped, not by anybody remembering.

Versions plus anciennes

Chaque version, avec son SBOM, est sur GitHub.

Toutes les versions sur GitHub