| 11.5.05 November 2026 |
| |
New defaults and other breaking changes
|
|
Changed
|
Tables, hyperlinks and table cell styles are now converted by default, and text in the automatic color is no longer forced to black. With the 11.4 defaults, a table row became a plain paragraph and a hyperlink kept its text but had no link element. Code that styles or post-processes the output may need changes:
- ConvertTables now defaults to true.
- ConvertHyperlinks now defaults to true. Only http, https and mailto links are written.
- ConvertCellStyles now defaults to true: cell borders, and vertical-align:top on top-aligned cells. It takes effect only with tables on.
- DefaultFontColor now defaults to empty: text in the automatic color gets no CSS color and inherits the page's text color (it was color:#000000). Explicit black is still #000000.
|
|
Changed
|
A hyperlink whose text changes formatting is now one link around its text, as in ScroogeXHTML for Object Pascal, instead of one link per formatted part. Screen readers, keyboard navigation and post-processing now see one link. A link with uniform formatting keeps its shape. A PostProcessListener that expects one link per text run may need changes.
|
|
Improved
|
Nested tables stay off by default. With tables on, the text of a nested table goes into the enclosing cell, and each nested cell now ends with a tab, as in ScroogeXHTML for Object Pascal (the cells ran together before).
|
| |
Security
|
|
Security
|
As a defense in depth, a careless head setting can no longer break the head markup: with HTML5 output, a style sheet text containing </style is escaped; style sheet links must be relative or use http or https, others are dropped and logged; characters that XML does not allow are removed from the title, meta values, style sheet links and style text (they failed every conversion on Java 21 and later).
|
| |
Deprecated
|
|
Deprecated
|
Header and footer conversion will be removed in 12.0 (HeaderFooterConfiguration and getHeaderFooterConfiguration()). From 12.0 on, RTF headers and footers are always skipped, as they are by default today. The option was experimental and off by default.
|
|
Deprecated
|
Footnote conversion will be removed in 12.0 (setConvertFootnotes() and isConvertFootnotes()). From 12.0 on, RTF footnotes are always skipped, as they are by default today. With the option on, footnote text was mixed into the body text.
|
| |
Tables
|
|
Improved
|
Cell styles and nested tables are no longer experimental, and setting them no longer logs a warning. The output is unchanged.
|
|
✓ Fixed
|
A centered or right-aligned table is now centered or aligned right, as in ScroogeXHTML for Object Pascal.
|
|
✓ Fixed
|
Tables whose cell edges differ from row to row, such as tables with merged cells, now follow the HTML table model; the Nu HTML Checker reported errors for them before.
|
|
✓ Fixed
|
Text right after the end of a table cell no longer loses its character formatting.
|
|
✓ Fixed
|
List items in several cells of a row no longer all go into the first cell, and a list right before or after a table no longer continues into or out of it.
|
|
✓ Fixed
|
A malformed table row with more or fewer cells than cell definitions no longer loses all its cell borders.
|
| |
Hyperlinks and bookmarks
|
|
✓ Fixed
|
A link no longer loses its target after a formatted part of the link text; fields inside a link, such as page numbers in a table of contents, keep the link around them.
|
|
✓ Fixed
|
A link to a bookmark whose name has spaces or other characters not allowed in an id now reaches its anchor.
|
|
✓ Fixed
|
A bookmark name used twice, two names that map to the same id, or an empty name no longer produce duplicate or empty ids.
|
| |
Text, lists and other content
|
|
✓ Fixed
|
Nothing in a skipped page header, footer or footnote reaches the body any more: a link target in a page header became a link around the next body text, a header picture appeared at the top of the body, and a footnote of several paragraphs split the body paragraph.
|
|
✓ Fixed
|
Documents from LibreOffice no longer start with stray text from a page header, such as its page number.
|
|
✓ Fixed
|
Text in a language that is not in the language table, such as WordPad's invalid \lang255, no longer gets lang="en"; it gets no lang attribute.
|
|
✓ Fixed
|
Simplified Chinese text (GB2312 character set) is decoded correctly instead of as unreadable Latin characters.
|
|
✓ Fixed
|
Text in the Symbol font after a group inside the Symbol text is mapped to Greek letters and symbols too.
|
|
✓ Fixed
|
Double-underlined text (\uldb) is underlined.
|
|
✓ Fixed
|
Lists from old OpenOffice and StarWriter versions get the right list type, and with the list table off, list paragraphs from Word and TRichView keep their indent and spacing.
|
|
✓ Fixed
|
With header and footer conversion on, first-page, left-page and right-page footers get their class attribute.
|
| |
Other changes
|
|
Improved
|
Switching on any experimental option now logs a warning, and the documentation marks every experimental option and the complimentary example code.
|
|
Improved
|
The license has a new section with the terms for the free 30-day evaluation of the Jar Edition.
|
|
✓ Fixed
|
The installers show the product name and version in the window title and default folder instead of unresolved placeholders.
|
|
✓ Fixed
|
The ScroogeXHTML-Addons and ScroogeXHTML-Pictures POMs no longer put JUnit on the runtime classpath of projects that use them.
|
|
Ⓘ Unresolved
|
A truncated document, one that ends while RTF groups are still open, loses its last table if the table is the last content. Earlier versions behave the same with tables enabled; complete documents are not affected. In strict mode, truncated input is rejected as before.
|
| 11.4.019 October 2026 |
| |
Hardening against malformed and adversarial RTF
|
|
New
|
New output limits in SecurityConfiguration: maximum element count (default 1,000,000) and maximum output size (default 64 Mi characters). A conversion that would exceed them aborts with a ConversionException, so a small input cannot expand into a huge document. The defaults are far above real documents, and the checks cost no measurable throughput.
|
|
New
|
New strict mode, enabled with getSecurityConfig().setStrictMode(true): the first structural defect in the RTF, such as a truncated document or table markup outside a table, aborts the conversion with a StructuralViolationException that names the defect. The default stays lenient.
|
|
Security
|
Values from the RTF that appear in log messages, such as a rejected hyperlink target or font name, are escaped and can no longer forge log entries on line-oriented log systems.
|
|
Security
|
No RTF content can reach the generated head element (title, style, link, meta): this is now verified by tests and documented as a trust boundary.
|
|
Security
|
Escapes for characters that XML does not allow, such as a null character or an unpaired surrogate, are dropped. On Java 21 and later they caused the whole conversion to fail; on earlier versions they were written as character references that are not allowed in HTML. Strict mode rejects them.
|
|
Improved
|
In the default lenient mode, the first occurrence of each kind of structural defect is logged as a warning, without document content.
|
|
✓ Fixed
|
A very long run of text in a single paragraph no longer takes quadratic time; conversion of ordinary documents is a few percent faster too.
|
|
✓ Fixed
|
Malformed tables no longer cause the whole conversion to fail; such rows are converted as plain cells.
|
|
✓ Fixed
|
Lists whose level jumps by more than one and then drops back, and some characters in the Symbol font, no longer cause the conversion to fail.
|
|
✓ Fixed
|
Conversions running at the same time in separate ScroogeXHTML instances no longer reconfigure a shared XML transformer factory.
|
| |
Lists
|
|
✓ Fixed
|
Multilevel lists from Word, TRichView and WPTools were nested one paragraph off and got the number format of the wrong level, because these programs write the list before the level.
|
|
✓ Fixed
|
Two different lists at the same level, with no plain paragraph between them, are no longer merged into one list; neither are bullet and numbered items of old-style (Word 6.0/95) lists.
|
| |
Tables
|
|
Improved
|
Nested tables get their column widths, row heights, cell borders and cell backgrounds.
|
|
Improved
|
With cell styles enabled, top-aligned cells get vertical-align:top, as browsers center table cells by default.
|
|
✓ Fixed
|
Nested tables written by Word and LibreOffice could lose all rows.
|
|
✓ Fixed
|
Column spans were lost in tables with a left indent (seen in LibreOffice exports), and merged cells did not take columns of other rows into account.
|
|
✓ Fixed
|
After a nested table row, the outer row's definition no longer adds a wrong column to the nested table.
|
|
✓ Fixed
|
A last table cell ended by \row instead of \cell (Word 2003) no longer loses its text to the paragraph after the table.
|
|
✓ Fixed
|
A cell background color no longer applies to every following cell of the row.
|
|
✓ Fixed
|
A cell after a merged cell gets its own style instead of the merged cell's.
|
|
✓ Fixed
|
A cell no longer loses its bottom border when diagonal cell borders follow it, as written by Google Docs.
|
| |
Text and fonts
|
|
Improved
|
The RTF quote keywords (\lquote, \rquote, \ldblquote, \rdblquote) are converted to typographic quotes instead of straight ones.
|
|
✓ Fixed
|
\plain resets the font to the document's default font instead of Times.
|
|
✓ Fixed
|
An empty color table entry after a defined one gets the default color instead of the previous entry's color.
|
|
✓ Fixed
|
Font names with a leading @ (vertical-writing variants such as @Arial Unicode MS) now match the font without the @.
|
|
✓ Fixed
|
A whitespace character after the font or color table no longer produces a spurious text span.
|
|
✓ Fixed
|
Text in Syriac and Divehi gets a lang attribute, and text whose language reverts to the document default no longer keeps the previous lang attribute.
|
|
✓ Fixed
|
Swedish text gets lang="sv" instead of "se" (the code of Northern Sami).
|
| |
Other changes
|
|
Improved
|
convert(Path, Path) and convert(Path, Path, Charset) now require AddOuterHTML = true, like the other methods that write a file, and throw UnsupportedOperationException otherwise. They wrote an HTML fragment before.
|
|
Improved
|
Update SLF4J to version 2.0.20.
|
| 11.3.014 September 2026 |
| |
Hardening against malformed and adversarial RTF
|
|
New
|
New SecurityConfiguration, available via getSecurityConfig(), with configurable limits: maximum group nesting depth, total binary (\bin) data size, size per embedded picture, and entries per font/color table.
|
|
Security
|
Malformed or abusive input now always terminates with a ConversionException. StackOverflowError, OutOfMemoryError, silent hangs and infinite loops are treated as defects.
|
|
Security
|
Hyperlink targets are restricted to an explicit URL scheme allow-list (http, https, mailto and relative references). Other schemes, such as javascript: and data:, are dropped.
|
|
Security
|
Image sources follow the same allow-list, plus data:image/... (excluding SVG, which can carry script).
|
|
Security
|
Font-family names used in generated inline styles are validated; a name that could break out of the style attribute is rejected.
|
|
Security
|
The XML DocumentBuilder used to build the result document is hardened (secure processing enabled, external entities and DOCTYPE declarations disabled).
|
|
Security
|
Invalid hexadecimal escapes and unbalanced groups are handled deterministically and no longer leave the reader in an inconsistent state.
|
|
✓ Fixed
|
A truncated document inside certain table keywords no longer hangs in an infinite loop.
|
|
✓ Fixed
|
Out-of-range color-table values no longer cause a conversion to fail unexpectedly.
|
| |
Other changes
|
|
Improved
|
Update SLF4J to version 2.0.19.
|
|
Improved
|
Update dependencies.
|
| 11.0.001 January 2025 |
| |
System requirements
|
|
New
|
Increase minimum required Java Runtime Environment version from Java SE 8 to Java SE 11.
|
| |
Character property conversion
|
|
Improved
|
The property FontSizeUnit moved. It can now be set using getCharPropConvConfig().setFontSizeUnit().
|
|
Improved
|
The signature of FontReplacing#replace changed. It now longer takes a ScroogeXHTMLBase instance as first parameter. The default implementation has been updated accordingly.
|
| |
Paragraph property conversion
|
|
Improved
|
The default value for property ConvertEmptyParagraphs changed. It is now enabled by default.
|
| |
List conversion
|
|
Improved
|
Improve support for RTF listtable and listoverridetable processing. It is now enabled by default.
|
|
Improved
|
Remove property SupportMultiLevel, as multi-level lists are now handled when SupportListTable is enabled.
|
|
Improved
|
Removed property ConvertFields, as it is currently unused. Field result text will always be emitted in the conversion.
|
| |
Font size units
|
|
Improved
|
Rename class FontSizeUnit to LengthUnit.
|
|
Improved
|
Change internal font size handling from points to half-points for higher precision.
|
|
Improved
|
Remove support for 'ex' font size unit, and improve support for 'em' and 'px' unit.
|
|
Improved
|
The default font size unit is now 'em'.
|
|
Improved
|
The allowed font size units are now 'em', 'point' and 'px'.
|
| |
Pictures
|
|
Improved
|
The default maximum size for data URI in the complimentary picture adapter MemoryPictureAdapterDataURI class has been increased from 32 to 256 kilobytes.
|
|
Improved
|
The PictureFormat PICT is no longer enabled by default in MemoryPictureAdapterDataURI.
|
|
Improved
|
Remove unused 'setBase' method from PictureAdapter classes.
|
| |
Tables
|
|
Improved
|
Switch to LengthUnit for table width configuration.
|
| |
Other changes
|
|
Improved
|
Adjusted default font replacements to use 'Arial,sans-serif' and 'Courier New,monospace' instead of 'Arial,Helvetica,sans-serif' and 'Courier,monospace'.
|
|
Improved
|
The value of the DefaultLanguage property will be used for the lang attribute on the HTML5 root element (even if it is empty).
|
|
Improved
|
Enforce that HTML5 uses UTF-8 by throwing an exception when a different encoding is set.
|
|
Improved
|
ResultBuilderException will no longer be thrown. The class has been removed.
|
|
Improved
|
Update IzPack Maven Plugin to version 5.2.3.
|
|
New
|
Update license text.
|
| |
Known issues with experimental features
|
|
Ⓘ Unresolved
|
Complimentary MemoryPictureAdapterDataURI fails to convert from PICT to PNG.
|
|
Ⓘ Unresolved
|
Nested table conversion fails for RTF document created by LibreOffice 7.x.
|
| 10.5.0released 04 February 2024 |
|
New
|
Reach 98% code line coverage for the core library tests
|
|
New
|
Add pixel unit support to font size in CssBuilder
|
|
New
|
Optimize border style handling in ScroogeXHTML
|
|
New
|
Replace logging with assertions in TableCellMerger class
|
|
New
|
Replace error handling with assertion in Table and TableRowHolder class
|
|
New
|
Refactor code in MultilevelNumberingSupport and add tests
|
|
New
|
Refactor ListLevel and NumberType classes
|
|
New
|
Refactor setProperty function in ScroogeXHTMLMain.java
|
|
New
|
Refactor RTFReader and add unit tests
|
|
New
|
Convert the Elements class to an enum and rename it to HtmlElement
|
|
New
|
Convert the Attributes class to an enum and rename it to Attribute
|
|
New
|
Update the handling of NoSuchElementException in RTFReader.java to throw a ConversionException instead.
|
|
New
|
Simplify toBrowserHexValue method
|
|
New
|
Add UnicodeConverter tests and expose methods for charset handling
|
|
New
|
Add tests for null octet and form feed octet in the RTF code
|
|
New
|
Rename test classes for experimental features
|
|
New
|
Remove unused DG_FIELD case in ScroogeXHTMLMain.java
|
|
New
|
Comment out trace logging in searchToken method
|
| 10.4.0released 23 December 2023 |
|
New
|
Add experimental support for nested tables
|
|
New
|
Add five languages to installer
|
|
New
|
Add test testConvertParagraphMarginsSpaceBefore and testConvertParagraphMarginsSpaceAfter
|
|
New
|
Add test testHtmlHeadMetaHeaders()
|
|
New
|
Add test for a minimal table
|
|
New
|
Add itap to paragraph properties
|
|
New
|
Add example code for document lang attribute
|
|
New
|
Add example code for meta date
|
|
New
|
Add logging and toString() method to Table class
|
|
New
|
Use ATTR_STYLE instead hard coded "style"
|
|
New
|
Use a Deque for Table Rows property
|
|
New
|
Use a Deque for StyledTexts
|
|
New
|
Use a stack structure for tables
|
|
New
|
Refactor away intable field
|
|
✓ Fixed
|
Fix "nonesttables" to set DG_IGNORE for nested tables
|
|
✓ Fixed
|
Bump slf4j from 2.0.7 to 2.0.9
|
|
✓ Fixed
|
Bump com.twelvemonkeys.imageio:imageio-pict from 3.9.4 to 3.10.0
|
| 10.3.0released 18 June 2023 |
|
New
|
Cleanup and refactor Table class
|
|
New
|
Remove unnecessary try ... catch in class ScroogeXHTMLMain
|
|
New
|
Refactor constant PX in class CssBuilder into FontSizeUnit enum
|
|
New
|
Simplify anchor conversion in XMLDOMWriter#addAnchor: always create a div node
|
|
New
|
Remove unnecessary unit px from DEFAULT_CSS in class DefaultConfiguration
|
|
New
|
Remove unused method Node getColGroup() in interface TableWriter
|
|
New
|
Add itap property to TableWriter
|
|
New
|
Add experimental support for font size based on the relative unit 'vw'.
|
|
New
|
Add tests for 'empty' input string and for minimal RTF string
|
|
New
|
Refactor away flag dummyRowNeeded
|
|
New
|
Refactor flag inTableRow
|
|
New
|
Refactor flag inTableRowDefinition
|
|
New
|
Refactor flag RowPropertiesAlreadySeenAtBeginOfRow (was RowPropertiesComplete)
|
|
New
|
Refactor method finishColGroup()
|
|
New
|
Refactor method finishTableNode()
|
|
New
|
Add logging and defensive code in class TableRowHolder
|
|
New
|
Rename isInRow to isInTableRowDefinition
|
|
New
|
Rename tableRowStarts to tableRowDefinitionStarts
|
|
New
|
Remove unused field inNestedTableProperties
|
|
New
|
Extract TableSupportBase class
|
|
New
|
Treat \nestcell and \nestrow tokens as \cell and \row
|
|
New
|
Remove unused method getCurrentPageWidth
|
|
✓ Fixed
|
Suppress warning UnnecessaryUnicodeEscape
|
|
✓ Fixed
|
Add workaround for missing colgroup
|
|
✓ Fixed
|
Add workaround for missing cellXs
|
|
✓ Fixed
|
Fixed PMD warnings
|
| 10.0.0released 22 October 2022 |
|
New
|
Move all properties related to conversion of characters, paragraphs and HTML head section to nested properties
|
|
New
|
Introduce an enum based configuration for experimental conversion options
|
|
New
|
Introduce the ConvertParagraphBorders property
|
|
New
|
Target Java SE 11 and newer
|
|
New
|
Use <meta charset='...'> instead of <meta http-equiv='Content-Type' content='text/html; charset=...'>
|
|
New
|
Bump slf4j from 1.7.36 to 2.0.3
|
|
✓ Fixed
|
Remove indirect write access from interface ConversionConfiguration
|
|
✓ Fixed
|
Remove deprecated statistics support
|
|
✓ Fixed
|
Remove deprecated configuration methods
|
|
✓ Fixed
|
Remove deprecated interface FontStatisticsCollecting
|
|
✓ Fixed
|
Remove deprecated class MemoryPictureAdapterBase64
|
|
✓ Fixed
|
Remove method nameAndVersion
|
| 9.5.0released 25 June 2022 |
|
✓ Fixed
|
unit test failure on newer JDK versions, which now write BR elements as <br /> instead of <br/>
|
|
New
|
Properties related to character attribute conversion, paragraph attribute conversion and HTML head section options have been deprecated in favour of the new HtmlHeadConfiguration, CharPropsConfig and ParaPropConfig properties, which will be the only API to set these properties in the next major version
|
|
New
|
New method HtmlHeadConfiguration#addStyleSheetLink(String)
|
|
New
|
The method HtmlHeadConfiguration#getStyleSheetLinks() returns an unmodifiable collection
|
|
New
|
SLF4J dependency updated to 1.7.36
|
|
New
|
Tested with Eclipse Temurin JDK 8, 11, 17 and 18
|
|
New
|
Tested with more JDK versions (Amazon Coretto, Eclipse Temurin, IBM Semeru)
|
|
New
|
Internal code maintenance
|
| 9.3.0released 29 May 2021 |
|
✓ Fixed
|
Fallback to the original picture dimensions if the RTF does not specify the desired picture dimensions
|
|
New
|
Added complimentary code for WMF picture conversion using an external converter (not included) to the complimentary class MemoryPictureAdapterDataURI.
|
|
New
|
Added example code for plain text extraction from a XHTML document (using XSLT).
|
|
New
|
Added property ImgAltAttribute to class com.scroogexhtml.pictures.EmbeddedPicture, which contains the value of the IMG tag attribute 'alt'. Its default value is 'picture' for backwards compatibility.
|
|
New
|
Moved class com.scroogexhtml.fonts.FontDef to the Example artifact, as it is used only there.
|
|
New
|
Deprecated the complimentary class MemoryPictureAdapterBase64. The new class MemoryPictureAdapterDataURI may be used instead.
|
|
New
|
Updated the documentation for an experimental feature which is enabled implicitly when the ConvertTables property is set to true.
|
|
New
|
Updated tutorials and documentation
|
|
New
|
Added JUnit tests
|
|
New
|
Fixed QA hints and warnings
|
|
New
|
Minor code improvements (see JavaDoc)
|
| 7.2.0 |
|
New
|
Added support for vertical alignment in table cells
|
|
New
|
Standalone XHTML documents begin with a XML declaration if the charset is not UTF-8
|
|
New
|
Table conversion uses the class="table table-bordered" attribute (instead of border="1") to indicate that the table is bordered. This fixes the W3C HTML validator warning "The border attribute on the table element is presentational markup". Applications which still require the border="1" attribute may enable it with setOutputProperty(ConversionKeys.USE_TABLE_BORDER_ATTRIBUTE, "yes");
|
|
New
|
Removed the enclosing <!-- ... --> around the CSS code within the <style> element for standalone documents
|
|
New
|
Removed the attribute type="text/css" for the <style> element for standalone HTML5 documents. This fixes the W3C HTML validator warning: "The type attribute for the style element is not needed and should be omitted".
|
|
New
|
Changed BODY {... to lowercase body {... in auto-generated CSS code
|
|
New
|
The <style> element includes comments before auto-generated and custom styles
|
|
✓ Fixed
|
Fixed Findbugs warnings for non-transient non-serializable instance fields in MemoryPictureAdapter and ListHeaderInfo class
|
|
✓ Fixed
|
Fixed Findbugs warnings for reliance on default encoding in com.habarisoft.scroogexhtml.ScroogeXHTML.convert
|
|
✓ Fixed
|
Fixed Findbugs warnings for casting and passing to ceil in com.habarisoft.scroogexhtml.converter.AbstractWriter.getFontSizeStyle
|
|
✓ Fixed
|
Fixed Findbugs warnings for casting and passing to ceil in com.habarisoft.scroogexhtml.pictures.EmbeddedPicture.getHGoalPx and getWGoalPx
|
|
✓ Fixed
|
Fixed Findbugs warnings with medium severity
|
| 7.0.0released 28 October 2017 |
|
New
|
Added option to disable paragraph border conversion
|
|
New
|
Improved algorithm for ConvertEmptyParagraphs
|
|
New
|
Improved Unicode support for Japanese text
|
|
New
|
Improved initialization speed of DOM tree transformation
|
|
New
|
Improved detection of for outer table border
|
|
New
|
Experimental support for a multilevel numbering writer
|
|
New
|
Experimental support for uppercase and lowercase roman numbers
|
|
New
|
Experimental support for \*\pn paragraph numbering
|
|
New
|
ConvertFootnotes default value changed to false
|
|
New
|
Experimental UseListTable property is deprecated, use setOutputProperty(ConversionKeys.SUPPORT_LIST_TABLE}, 'yes');
|
|
New
|
UseListTable property default changed to false
|
|
New
|
Removed ProgressListener properties
|
|
New
|
Removed detection of hyperlinks based on blue/underlined text format
|
|
New
|
Removed MetaDateAuto property
|
|
New
|
Removed default creation of post process listeners
|
|
New
|
Added ScroogeXHTMLMain.addDefaultListeners() method for backward compatibility
|
|
✓ Fixed
|
Always hide all hidden text (even if ConvertFontStyle is false)
|