<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>What is Miklos hacking - libreoffice</title><link>https://vmiklos.hu/blog/</link><description/><atom:link href="https://vmiklos.hu/blog/feeds/libreoffice.rss.xml" rel="self"/><lastBuildDate>Wed, 04 Feb 2026 08:42:44 +0100</lastBuildDate><item><title>Improving deleted commented text ranges in Writer's DOCX filter</title><link>https://vmiklos.hu/blog/sw-ranged-comment-delete-docx.html</link><description>&lt;p&gt;If you have a commented text range, which gets deleted while track changes is on and you later save
and load this with Writer's DOCX filter, that works now correctly.&lt;/p&gt;
&lt;p&gt;This work is primarily for &lt;a href="https://www.collaboraonline.com/"&gt;Collabora Online&lt;/a&gt;, but the feature is
available in desktop Writer as well.&lt;/p&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;a class="headerlink" href="#motivation" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;It was already possible to comment on text ranges. Comments were also supported inside deletes when
track changes is enabled. These could be already exported to and imported from DOCX in Writer. But
you could not combine these.&lt;/p&gt;
&lt;p&gt;With the increasing popularity of commenting text ranges (rather than just inserting a comment with
an anchor), not being able to combine these was annoying.&lt;/p&gt;
&lt;h2 id="results-so-far"&gt;Results so far&lt;a class="headerlink" href="#results-so-far" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Here is how a commented text range inside a delete from DOCX now looks like, note the
semi-transparent comment hinting it's deleted:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-ranged-comment-delete-docx/cool-good.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-ranged-comment-delete-docx/cool-good.png"&gt;&lt;figcaption&gt;Commented text range, inside a tracked delete, in DOCX, Collabora Online&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As a side effect, this also fixes the behavior in desktop Writer, which crosses out deleted
comments:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-ranged-comment-delete-docx/desktop-good.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-ranged-comment-delete-docx/desktop-good.png"&gt;&lt;figcaption&gt;Commented text range, inside a tracked delete, in DOCX, desktop&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In the past, the "is this deleted" property was not visible in the render result:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-ranged-comment-delete-docx/cool-bad.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-ranged-comment-delete-docx/cool-bad.png"&gt;&lt;figcaption&gt;Commented text range, inside a tracked delete, in DOCX, Collabora Online, old bad state&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And it was also bad in desktop Writer:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-ranged-comment-delete-docx/desktop-bad.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-ranged-comment-delete-docx/desktop-bad.png"&gt;&lt;figcaption&gt;Commented text range, inside a tracked delete, in DOCX, desktop, old bad state&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This required changes to both DOCX import and export: a comment could be deleted or could have an
anchor which is a text range, but you couldn't have both.&lt;/p&gt;
&lt;h2 id="how-is-this-implemented"&gt;How is this implemented?&lt;a class="headerlink" href="#how-is-this-implemented" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you would like to know a bit more about how this works, continue reading... :-)&lt;/p&gt;
&lt;p&gt;As usual, the high-level problem was addressed by a series of small changes. Core side:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/5d101c9919c7c0798df092bd31b828d0a144abba"&gt;cool#13988 DOCX import: fix missing delete flag on deleted comments with ranges&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/a72506da82d2e0334e23a8c3c1cd07282fdd7ca3"&gt;cool#13988 DOCX export: fix missing delete flag on deleted comments with ranges&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="want-to-start-using-this"&gt;Want to start using this?&lt;a class="headerlink" href="#want-to-start-using-this" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can get a development edition of Collabora Online 25.04 and try it out yourself right now: &lt;a href="https://www.collaboraonline.com/code/"&gt;try
the development edition&lt;/a&gt;.  Collabora intends to continue
supporting and contributing to LibreOffice, the code is merged so we expect all of this work will be
available in TDF's next release too (26.8).&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Miklos Vajna</dc:creator><pubDate>Wed, 04 Feb 2026 08:42:44 +0100</pubDate><guid>tag:vmiklos.hu,2026-02-04:/blog/sw-ranged-comment-delete-docx.html</guid><category>libreoffice</category><category>en</category></item><item><title>Bullet improvements in Impress</title><link>https://vmiklos.hu/blog/sd-bullet-improvements.html</link><description>&lt;p&gt;The bullet support in Impress got a couple of improvements recently, some of this is PPTX support
and others are general UI improvements.&lt;/p&gt;
&lt;p&gt;This work is primarily for &lt;a href="https://www.collaboraonline.com/"&gt;Collabora Online&lt;/a&gt;, but the feature is
available in desktop Impress as well.&lt;/p&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;a class="headerlink" href="#motivation" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Probably the most simple presentations are just a couple of slides, each slide having a title shape
and an outliner shape, containing some bullets, perhaps with some additional images. Images are just
bitmaps, so let's focus on outliner shapes and their outliner / bullet styles.&lt;/p&gt;
&lt;p&gt;What happens if you save these to PPTX and load it back? Can you toggle between a numbering and a
bullet? Can you return to an outliner style after you had direct formatting for your bullet?&lt;/p&gt;
&lt;h2 id="results-so-far"&gt;Results so far&lt;a class="headerlink" href="#results-so-far" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The first case was about bullet editing of this document:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sd-bullet-improvements/sd-bullet-improvements-1.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sd-bullet-improvements/sd-bullet-improvements-1.png"&gt;&lt;figcaption&gt;Outliner shape with 3 outliner styles&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you pressed enter at the end of 'First level', then pressed &lt;code&gt;&amp;lt;tab&amp;gt;&lt;/code&gt; to promote the current
paragraph to the second level, nothing happened. The reason for this was that our PPTX export was
missing the list styles of shapes, except for the very first list style. And the same was missing on
the import side, too. With this, not only the rendering of the bullets are OK, but also adding new
paragraphs and using promoting / demoting to change levels work as expected.&lt;/p&gt;
&lt;p&gt;The second case was about this document, where the second level had a numbering, not a bullet:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sd-bullet-improvements/sd-bullet-improvements-2.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sd-bullet-improvements/sd-bullet-improvements-2.png"&gt;&lt;figcaption&gt;Outliner shape with a numbering on the second level&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We only had UI to first toggle off a numbering to no numbering, then you could toggle on bullets.
Now it's possible to do this change in one step.&lt;/p&gt;
&lt;p&gt;The last case was about styles. Imagine that you had a master page with an outline shape and some
reasonably looking configuration for the first and second levels as outline styles:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sd-bullet-improvements/sd-bullet-improvements-3.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sd-bullet-improvements/sd-bullet-improvements-3.png"&gt;&lt;figcaption&gt;Outliner shape with two outline styles&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Notice how the last paragraph has a slightly inconsistent formatting, due to direct formatting.
Let's fix this.&lt;/p&gt;
&lt;p&gt;Go to the end of the last bullet, which is currently not connected to an outline style, toggle
bullets off and then toggle it on again. Now we clear direct formatting when we turn off the bullet,
so next time you turn bullets on, it'll be again connected to the outline style's bullet
configuration and the content will look better.&lt;/p&gt;
&lt;p&gt;Note how this even improves consistency: Writer was behaving the same way already, when toggling
bullets off and then toggle on again resulted in getting rid of previously applied unwanted direct
formatting.&lt;/p&gt;
&lt;h2 id="how-is-this-implemented"&gt;How is this implemented?&lt;a class="headerlink" href="#how-is-this-implemented" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you would like to know a bit more about how this works, continue reading... :-)&lt;/p&gt;
&lt;p&gt;As usual, the high-level problem was addressed by a series of small changes. Core side:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/6a8b96ddd47af2be3f06e299ee7058438083ba5b"&gt;PPTX export: fix missing non-first level list style for outline shapes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/ccb9e9ef70c4fae3f69b63083cab838794a3d46d"&gt;sd doc model dump: allow invoking this from outside sd/ in a debugger&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/e96f2ef1a299c95d83c6a7945fcc92f8f1833112"&gt;sd doc model xml dump: show styles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/cb108a10479e72b63d32cae020a4ac178e763d14"&gt;tdf#168559 PPTX imp: fix missing custom level list style for outline shapes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/b2c5d52f733cca2656daa0a2cfdd85a1108635f4"&gt;tdf#168559 PPTX imp: fix missing list style for outline shapes on master pages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/f60ee00edcc5b0fdee5227bb695448119cddb013"&gt;tdf#89365 sd UI: fix transitioning from a numbered list to a bulleted list&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/0856eee636f512ae2cffc141b7ab3b5065d8beda"&gt;tdf#169275 sd UI: clear direct format when turning off bullet/num&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/122ff49f6ee6b88386cd30a542a92b04c508e47a"&gt;sd: extract &lt;code&gt;FN_TRANSFORM_DOCUMENT_STRUCTURE&lt;/code&gt; handling to a new function&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/1dc25f541784b5e50210af1d5ffb619ec55220f1"&gt;sd, FuBulletAndPosition: avoid magic number for bullet toggle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/a26e176abcd40438d19e2a9012db1342bdcaba12"&gt;Related: tdf#89365 sd UI, from numbering to bullet: fix defaults&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="want-to-start-using-this"&gt;Want to start using this?&lt;a class="headerlink" href="#want-to-start-using-this" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can get a development edition of Collabora Online 25.04 and try it out yourself right now: &lt;a href="https://www.collaboraonline.com/code/"&gt;try
the development edition&lt;/a&gt;.  Collabora intends to continue
supporting and contributing to LibreOffice, the code is merged so we expect the core of this work
will be available in TDF's next release too (26.2).&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Miklos Vajna</dc:creator><pubDate>Mon, 05 Jan 2026 08:37:39 +0100</pubDate><guid>tag:vmiklos.hu,2026-01-05:/blog/sd-bullet-improvements.html</guid><category>libreoffice</category><category>en</category></item><item><title>Markdown import in Writer: the new template option</title><link>https://vmiklos.hu/blog/sw-markdown-templating.html</link><description>&lt;p&gt;Writer recently got a new markdown import option to take styles from a template, leading to much
prettier output when converting markdown to PDF, DOCX or ODT.&lt;/p&gt;
&lt;p&gt;This work is primarily for &lt;a href="https://www.collaboraonline.com/"&gt;Collabora Online&lt;/a&gt;, but the templating
feature is available in desktop Writer as well.&lt;/p&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;a class="headerlink" href="#motivation" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A &lt;a href="https://vmiklos.hu/blog/sw-markdown-filter.html"&gt;previous post&lt;/a&gt; mentioned recent improvements to the
markdown import/export in Writer.&lt;/p&gt;
&lt;p&gt;But if you convert some markdown to e.g. PDF, all the headings just have the default look, wouldn't
it be nice to take your organization template and add colors and other formatting there,
automatically?&lt;/p&gt;
&lt;p&gt;Also, wouldn't it be nice if you could paste as markdown in COOL or copy the current selection as
markdown? Which would enable all sorts of interesting use-cases, like using an external API to turn
the selection into a summary or translating it to a different language.&lt;/p&gt;
&lt;h2 id="results-so-far"&gt;Results so far&lt;a class="headerlink" href="#results-so-far" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Here is a sample input markdown:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gh"&gt;# heading 1&lt;/span&gt;

body text
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here is how it looks like if you template it using the core.git &lt;code&gt;sw/qa/filter/md/data/template.docx&lt;/code&gt;
sample:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-markdown-templating/templated.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-markdown-templating/templated.png"&gt;&lt;figcaption&gt;PDF result: templated&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;curl invocation for this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-k&lt;span class="w"&gt; &lt;/span&gt;-F&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;data=@/path/to/test.md&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-F&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;template=@/path/to/template.docx&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-F&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;format=pdf&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;out.pdf&lt;span class="w"&gt; &lt;/span&gt;https://localhost:9980/cool/convert-to
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Or example desktop command-line:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;soffice&lt;span class="w"&gt; &lt;/span&gt;--infilter&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Markdown:{&amp;quot;TemplateURL&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&amp;quot;value&amp;quot;:&amp;quot;./template.ott&amp;quot;}}&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;test.md
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;While it would look like this by default:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-markdown-templating/default.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-markdown-templating/default.png"&gt;&lt;figcaption&gt;PDF result: default&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The other part is the PostMessage API of COOL, if you want to copy and paste as markdown. What's
newly possible:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Copy the current selection: set MessageId to &lt;code&gt;Action_Copy&lt;/code&gt; and the value to &lt;code&gt;{"Mimetype": "text/markdown;charset=utf-8"}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Paste at the current cursor position: set MessageId to &lt;code&gt;Action_Paste&lt;/code&gt; and the value to
  something like &lt;code&gt;{"Mimetype": "text/markdown;charset=utf-8", "Data": "foo _bar_ baz"}&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can read more about the PostMessage API in the &lt;a href="https://sdk.collaboraonline.com/docs/postmessage_api.html"&gt;COOL
SDK&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="how-is-this-implemented"&gt;How is this implemented?&lt;a class="headerlink" href="#how-is-this-implemented" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you would like to know a bit more about how this works, continue reading... :-)&lt;/p&gt;
&lt;p&gt;As usual, the high-level problem was addressed by a series of small changes. Core side:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/7462639341c043bf72560e0ddfff06e1e8879859"&gt;tdf#169316 sw markdown import: add a TemplateURL parameter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/6d1312e160ee8c2c0f65b6e0a86333bf3c9c60ce"&gt;tdf#169316 sw markdown import, template: handle non-ODF formats as well&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/64cf69926b7cb6fc94efd792b173ac12aa93cb8f"&gt;cool#13468 sw markdown paste: add UNO command parameter to skip the detection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/5ae32bee8dfe5b3264debc02276a3eeac7f51021"&gt;Related: tdf#169251 sw markdown export: fix crash on OLE with no graphic&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Online side:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/collaboraonline/online/commit/5741a8fe91f9fe2969926cf70c8c51f1dd144ad5"&gt;cool#13419 convert-to template option: handle multiple streams in ConvertToPartHandler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/collaboraonline/online/commit/31109066f2ea2b935cd9d2bc06b5debc6206b41a"&gt;cool#13419 convert-to template option: pass it to doc broker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/collaboraonline/online/commit/3916a7f82fd6454409b86b9915d33f9f2491a348"&gt;cool#13419 convert-to template option: pass it to the kit process&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/collaboraonline/online/commit/b993c314e1b50aea382a1dac7391a3949e65045b"&gt;cool#13419 convert-to template option: more strict param name, generalize filenames&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/collaboraonline/online/commit/852479accd67880934393f14c4101ad72e9ba806"&gt;cool#13419 convert-to template option: add testcase&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/collaboraonline/online/commit/81881d58fd537924091a5e2e41d033e91c98c8be"&gt;cool#13468 PostMessage API: allow copying the current text selection&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="want-to-start-using-this"&gt;Want to start using this?&lt;a class="headerlink" href="#want-to-start-using-this" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can get a development edition of Collabora Online 25.04 and try it out yourself right now: &lt;a href="https://www.collaboraonline.com/code/"&gt;try
the development edition&lt;/a&gt;.  Collabora intends to continue
supporting and contributing to LibreOffice, the code is merged so we expect the core of this work
will be available in TDF's next release too (26.2).&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Miklos Vajna</dc:creator><pubDate>Wed, 03 Dec 2025 09:35:36 +0100</pubDate><guid>tag:vmiklos.hu,2025-12-03:/blog/sw-markdown-templating.html</guid><category>libreoffice</category><category>en</category></item><item><title>Interdependent tracked changes improvements in Writer, part 4: direct accept/reject</title><link>https://vmiklos.hu/blog/sw-interdependent-redline-improvements4.html</link><description>&lt;p&gt;Writer has some support for interdependent (or hierarchical) tracked changes: e.g. the case when you
have a delete on top of an insert. See the &lt;a href="https://vmiklos.hu/blog/sw-interdependent-redline-improvements3.html"&gt;third
post&lt;/a&gt; for background.&lt;/p&gt;
&lt;p&gt;This work is primarily for &lt;a href="https://www.collaboraonline.com/"&gt;Collabora Online&lt;/a&gt;, but the feature is
available in desktop Writer as well.&lt;/p&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;a class="headerlink" href="#motivation" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Interdependent changes mean that the UI shows one type of change on top of another change, e.g.
formatting on top of insert. Writer knows the priority of each type, so in case you have an insert
or delete change and on top of that you have a formatting, then the UI will look "through" the
formatting and work on the underlying insert or delete when you navigate with your cursor to a
position with multiple changes and you press Accept on the Review tab of the notebookbar.&lt;/p&gt;
&lt;p&gt;Usually this is what you mean, but what if you want to work on the formatting at the top, directly?
You can now open the Manage Changes dialog using the Manage button on the Review tab of the
notebookbar and if you go to the formatting change row of the dialog, then pressing Accept there
will accept the formatting change, not the insert or delete change. This is possible, because the dialog
gives you a way to precisely select which tracked change you want to work with, even if a specific
cursor position has multiple tracked changes.&lt;/p&gt;
&lt;h2 id="results-so-far"&gt;Results so far&lt;a class="headerlink" href="#results-so-far" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Here is a sample &lt;code&gt;ins-then-format.docx&lt;/code&gt; document from the core.git testcases, the baseline has an
insertion, and part of that is covered by an additional formatting change on top:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements4/baseline.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements4/baseline.png"&gt;&lt;figcaption&gt;Interdependent tracked change: baseline&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you just go in the middle of the document and press Accept, that will work with the more
important insert change, so the result looks like this:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements4/default-accept-result.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements4/default-accept-result.png"&gt;&lt;figcaption&gt;Interdependent tracked change: default accept result&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;But now you can also open the Manage Changes dialog, to be more specific by directly selecting the
formatting change:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements4/direct-accept.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements4/direct-accept.png"&gt;&lt;figcaption&gt;Interdependent tracked change: direct accept via the dialog&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And when you accept the formatting change directly, the result will be just the insert change:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements4/direct-accept-result.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements4/direct-accept-result.png"&gt;&lt;figcaption&gt;Interdependent tracked change: direct accept result&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can save and load the results in both DOCX and ODT, as usual.&lt;/p&gt;
&lt;h2 id="how-is-this-implemented"&gt;How is this implemented?&lt;a class="headerlink" href="#how-is-this-implemented" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you would like to know a bit more about how this works, continue reading... :-)&lt;/p&gt;
&lt;p&gt;As usual, the high-level problem was addressed by a series of small changes. Core side:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/55640f9f0a4741f8e4b5b98096af822cee71da2c"&gt;tdf#166319 sw interdependent redlines: allow accept/reject for fmt on ins/del&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/d04ab0febcf660e87d19574adc08f9f2af75509f"&gt;tdf#166319 sw interdependent redlines: fix redo of accept for fmt on ins/del&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/1e3b8177aef8cc3a242cd9fd41d492f2fd89d21e"&gt;tdf#166319 sw interdependent redlines: fix redo of direct reject for format&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="want-to-start-using-this"&gt;Want to start using this?&lt;a class="headerlink" href="#want-to-start-using-this" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can get a development edition of Collabora Online 25.04 and try it out yourself right now: &lt;a href="https://www.collaboraonline.com/code/"&gt;try
the development edition&lt;/a&gt;.  Collabora intends to continue
supporting and contributing to LibreOffice, the code is merged so we expect all of this work will be
available in TDF's next release too (26.2).&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Miklos Vajna</dc:creator><pubDate>Tue, 04 Nov 2025 08:11:48 +0100</pubDate><guid>tag:vmiklos.hu,2025-11-04:/blog/sw-interdependent-redline-improvements4.html</guid><category>libreoffice</category><category>en</category></item><item><title>Markdown import/export in Writer</title><link>https://vmiklos.hu/blog/sw-markdown-filter.html</link><description>&lt;p&gt;Writer recently got a Markdown import &amp;amp; export filter and there were a number of improvements to
that.&lt;/p&gt;
&lt;p&gt;This work is primarily for &lt;a href="https://www.collaboraonline.com/"&gt;Collabora Online&lt;/a&gt;, but the feature is
available in desktop Writer as well.&lt;/p&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;a class="headerlink" href="#motivation" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Ujjawal Kumar contributed a markdown import to Writer, as part of Google Summer of Code (GSoC) this
summer. Mike Kaganski of Collabora also created a minimal markdown export in Writer. I looked at the
feature differences between the two, and filled in various gaps in the markdown export. I also added
a few general markdown import/export improvements relevant for normal Writer documents, like
embedded image support.&lt;/p&gt;
&lt;h2 id="results-so-far"&gt;Results so far&lt;a class="headerlink" href="#results-so-far" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Here is a sample case of a document using inline code spans:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-markdown-filter/1-code-baseline.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-markdown-filter/1-code-baseline.png"&gt;&lt;figcaption&gt;Code span: baseline&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Exporting this to markdown &amp;amp; loading back to Writer, the code span was lost:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-markdown-filter/1-code-old.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-markdown-filter/1-code-old.png"&gt;&lt;figcaption&gt;Code span: old result&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And now it's preserved:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-markdown-filter/1-code-new.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-markdown-filter/1-code-new.png"&gt;&lt;figcaption&gt;Code span: new result&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This also works with code blocks.&lt;/p&gt;
&lt;p&gt;Second, here is a document with lists:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-markdown-filter/2-list-baseline.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-markdown-filter/2-list-baseline.png"&gt;&lt;figcaption&gt;Lists: baseline&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Exporting this to markdown &amp;amp; loading back to Writer, the lists were lost:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-markdown-filter/2-list-old.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-markdown-filter/2-list-old.png"&gt;&lt;figcaption&gt;Lists: old result&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And now they are preserved:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-markdown-filter/2-list-new.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-markdown-filter/2-list-new.png"&gt;&lt;figcaption&gt;Lists: new result&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This also works with nested lists.&lt;/p&gt;
&lt;p&gt;Third, here is a document with an image:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-markdown-filter/3-image-baseline.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-markdown-filter/3-image-baseline.png"&gt;&lt;figcaption&gt;Image: baseline&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Exporting this to markdown &amp;amp; loading back to Writer, the image was lost:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-markdown-filter/3-image-old.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-markdown-filter/3-image-old.png"&gt;&lt;figcaption&gt;Image: old result&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And now it's preserved:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-markdown-filter/3-image-new.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-markdown-filter/3-image-new.png"&gt;&lt;figcaption&gt;Image: new result&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This also works with embedded and anchored images.&lt;/p&gt;
&lt;p&gt;Fourth, here is a document with a table:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-markdown-filter/4-table-baseline.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-markdown-filter/4-table-baseline.png"&gt;&lt;figcaption&gt;Table: baseline&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Exporting this to markdown &amp;amp; loading back to Writer, the table was lost:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-markdown-filter/4-table-old.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-markdown-filter/4-table-old.png"&gt;&lt;figcaption&gt;Table: old result&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And now it's preserved:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-markdown-filter/4-table-new.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-markdown-filter/4-table-new.png"&gt;&lt;figcaption&gt;Table: new result&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This also works with table alignments and nested tables (to the extent the markdown markup allows
that).&lt;/p&gt;
&lt;p&gt;Fifth, here is a document with a quote block:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-markdown-filter/5-quote-baseline.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-markdown-filter/5-quote-baseline.png"&gt;&lt;figcaption&gt;Quote: baseline&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Exporting this to markdown &amp;amp; loading back to Writer, the quote's paragraph indentation was lost:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-markdown-filter/5-quote-old.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-markdown-filter/5-quote-old.png"&gt;&lt;figcaption&gt;Quote: old result&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And now it's preserved:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-markdown-filter/5-quote-new.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-markdown-filter/5-quote-new.png"&gt;&lt;figcaption&gt;Quote: new result&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="how-is-this-implemented"&gt;How is this implemented?&lt;a class="headerlink" href="#how-is-this-implemented" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you would like to know a bit more about how this works, continue reading... :-)&lt;/p&gt;
&lt;p&gt;As usual, the high-level problem was addressed by a series of small changes. Core side:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/55393d9cc42b0402362022594b04ab4888257fb7"&gt;desktop lok, doc save: register .md for Markdown&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/959c448e9531a53e068e4cec3a56b0caf0e0d3d1"&gt;sw markdown export: handle code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/bcef97f29a7126cb3469066de4bacafaae30f86a"&gt;tdf#168152 sw markdown export: handle lists&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/fefd59b58c7d87e034fbf1c45cefa6a87ed09976"&gt;tdf#168172 sw markdown export: handle images&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/f073d733568d3b635ac8b2c3a5081afd679b4915"&gt;tdf#167564 sw markdown export: handle tables&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/c94b0c7ace10f5913aa53b593aa0ccd544df3cc3"&gt;sw markdown export: handle block quote&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/85aa1402c670e8c85949c5aaf01f529a0a59c05b"&gt;tdf#168317 sw markdown export: handle code block&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/5d0022c28b149dcc1db22176e442d130ff8d0279"&gt;sw markdown export: handle table cell adjustment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/b7bc0e5f3999950d6b5f0d2bdcda2c6cc2f04e61"&gt;tdf#168341 sw markdown filter: handle links on images&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/f63c14c9e45d795c6d5927103181c8d0ede8a34b"&gt;sw markdown export: handle line breaks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/3a294f97a9b37cc8ff38f76200b5b58879a3a72f"&gt;tdf#168446 sw markdown export: improve image name/description/title handling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/852d8b06bcecc5c68194fced94e4c7af02086c52"&gt;tdf#167564 sw markdown export: handle multi-para table cells&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/c830c9ab824c8086b2124fec44f834a1d0ae4fa5"&gt;tdf#167564 sw markdown export: handle nested table cells&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/7608d96302652eb48863da441e121e0c61350412"&gt;tdf#168617 sw markdown filter: map tasks to checkbox content controls and back&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/169e1f3b914ac590b3719b8129b4f0913d4da228"&gt;sw markdown filter: import images with 'data:' URLs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/8d60fcdac9bc79c7b8956ed3cd9e9f518b28c119"&gt;sw markdown filter: export non-linked inline images&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/3c29e1277bda566b4455123a7a53c8f0fc6eda98"&gt;tdf#168662 sw markdown export: extract inline image export functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/e0601a598977265c5b05ba397bce04d9689fca4b"&gt;tdf#168662 sw markdown export: handle anchored images&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="want-to-start-using-this"&gt;Want to start using this?&lt;a class="headerlink" href="#want-to-start-using-this" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can get a development edition of Collabora Online 25.04 and try it out yourself right now: &lt;a href="https://www.collaboraonline.com/code/"&gt;try
the development edition&lt;/a&gt;.  Collabora intends to continue
supporting and contributing to LibreOffice, the code is merged so we expect all of this work will be
available in TDF's next release too (26.2).&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Miklos Vajna</dc:creator><pubDate>Tue, 07 Oct 2025 08:13:55 +0200</pubDate><guid>tag:vmiklos.hu,2025-10-07:/blog/sw-markdown-filter.html</guid><category>libreoffice</category><category>en</category></item><item><title>Interdependent tracked changes improvements in Writer, part 3</title><link>https://vmiklos.hu/blog/sw-interdependent-redline-improvements3.html</link><description>&lt;p&gt;Writer has some support for interdependent (or hierarchical) tracked changes: e.g. the case when you
have a delete on top of an insert. See the &lt;a href="https://vmiklos.hu/blog/sw-interdependent-redline-improvements2.html"&gt;second
post&lt;/a&gt; for background.&lt;/p&gt;
&lt;p&gt;This work is primarily for &lt;a href="https://www.collaboraonline.com/"&gt;Collabora Online&lt;/a&gt;, but the feature is
available in desktop Writer as well.&lt;/p&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;a class="headerlink" href="#motivation" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With the already mentioned improvements in place, the area of format redlines with character style
or direct formatting changes were still lacking: Writer's original model here was just marking a
text range as "formatted" and then either accept the format redline as-is, or reject reverting back
to the paragraph style (default formatting), losing the old character style or old direct
formatting.&lt;/p&gt;
&lt;h2 id="results-so-far"&gt;Results so far&lt;a class="headerlink" href="#results-so-far" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Here is a sample case of a document where the old character style is Strong (~bold) and the font
size is 24pt, while the new character style is Quote (~italic) and the font size is 36pt. The rest
of the document uses no specific character styles and has the font size of 12pt:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements3/1-baseline.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements3/1-baseline.png"&gt;&lt;figcaption&gt;Interdependent tracked change: improved format, after document load&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Rejecting that format redline resulted in just the defaults, i.e. no character style and 12pt font
size:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements3/2-edit-old.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements3/2-edit-old.png"&gt;&lt;figcaption&gt;Interdependent tracked change: old reject, lost character style / direct format&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;But now we track the old character style &amp;amp; direct format:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements3/3-edit-new.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements3/3-edit-new.png"&gt;&lt;figcaption&gt;Interdependent tracked change: new reject, handled character style / direct format&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This required changes in the DOCX import, ODF import and ODF export, too.&lt;/p&gt;
&lt;h2 id="how-is-this-implemented"&gt;How is this implemented?&lt;a class="headerlink" href="#how-is-this-implemented" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you would like to know a bit more about how this works, continue reading... :-)&lt;/p&gt;
&lt;p&gt;As usual, the high-level problem was addressed by a series of small changes. Core side:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/7aa34659e2b49bf02a95a17f51e78f3ab9683235"&gt;sw: document DocumentRedlineManager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/da3da0635a30f9b61a913bd7553b5e1278bf260e"&gt;sw: document IDocumentRedlineAccess&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/b2919d5b5ee4e057c99219f5541efc388b2d19b7"&gt;sw doc model xml dump: show the item set of a format redline&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/d7bf3a17cb27da1a58163e9db657f0a8d8344901"&gt;tdf#166319 sw interdependent redlines: fix redo of accept of ins-then-fmt's fmt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/f66d63da05dbe2f254ffaf428257684a38523f66"&gt;tdf#166319 sw interdependent redlines: handle deleting a self ins-then-fmt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/1ba53f5ebbd57b7baf72240784d18954688a09b9"&gt;tdf#166319 sw interdependent redlines: fix redo of reject of del-then-fmt's fmt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/e545ada3501780ee6552bbfa19954794e0440d46"&gt;tdf#167194 sw redline reinstate: fix handling of self-inserts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/2db0a779944f9496371b3ba68f7494c635ad431d"&gt;tdf#167761 sw format redline: register the item set in the autostyle pool&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/b78bdc9eb15fedd22ece76aeb1b43df40caf3b82"&gt;tdf#167761 sw format redline: implement ODF export&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/0e21f3b36cbd12787021c3b8ef439aab9a09efdd"&gt;tdf#167761 sw format redline, char props: implement ODF import&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/a6d8608595fd1ecfdff35c2003a28589ea1214ad"&gt;tdf#167761 sw format redline, char style: implement DOCX import&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/0ba6dd9eb3f342345663b12527a29425675d2078"&gt;tdf#167761 sw format redline, char style: implement ODF import&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/43104ad996bc9b292b66d9e605632407cb59c4c6"&gt;tdf#167761 sw format redline, char style: fix missing encode in ODF filter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/c625247680cd5737723154b9a73c45e786611b44"&gt;tdf#167761 sw format redline, char style+direct: add ODT export&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/bbebb3908ff9a9c384a475737ead537906517387"&gt;tdf#167761 sw format redline, char style+direct: add ODT import&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="want-to-start-using-this"&gt;Want to start using this?&lt;a class="headerlink" href="#want-to-start-using-this" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can get a development edition of Collabora Online 25.04 and try it out yourself right now: &lt;a href="https://www.collaboraonline.com/code/"&gt;try
the development edition&lt;/a&gt;.  Collabora intends to continue
supporting and contributing to LibreOffice, the code is merged so we expect all of this work will be
available in TDF's next release too (26.2).&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Miklos Vajna</dc:creator><pubDate>Tue, 09 Sep 2025 08:23:48 +0200</pubDate><guid>tag:vmiklos.hu,2025-09-09:/blog/sw-interdependent-redline-improvements3.html</guid><category>libreoffice</category><category>en</category></item><item><title>Multi-page floating tables in Writer: keep together or not</title><link>https://vmiklos.hu/blog/sw-floattable12.html</link><description>&lt;p&gt;This post is part of a series to describe how Writer now gets a feature to handle tables that are
both floating and span over multiple pages.&lt;/p&gt;
&lt;p&gt;This work is primarily for &lt;a href="https://www.collaboraoffice.com/"&gt;Collabora Online&lt;/a&gt;, but is useful on
the desktop as well. See the &lt;a href="https://vmiklos.hu/blog/sw-floattable11.html"&gt;11th post&lt;/a&gt; for the previous part.&lt;/p&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;a class="headerlink" href="#motivation" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Previous posts described the hardest part of multi-page floating tables: making sure that text can
wrap around them and they can split across pages. In this part, we'll look at a conflicting
requirement. On one hand, headings want their text to not split across pages (and shapes anchored
into paragraphs are considered part of the paragraph, too). On the other hand, it should be OK to
have a floating table at the bottom of a page and the following heading to go to the next page.&lt;/p&gt;
&lt;p&gt;It turns out, Writer gave "keep together" a priority, while Word gave "floating tables are OK to
split to a previous page" a priority.&lt;/p&gt;
&lt;p&gt;Note that if you have a shape (e.g. a triangle) and not a floating table, then both Word and Writer
prevents the move of that shape to a previous page (if the shape is anchored in a heading); this
difference was there just for floating tables.&lt;/p&gt;
&lt;h2 id="results-so-far"&gt;Results so far&lt;a class="headerlink" href="#results-so-far" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Here is how the &lt;a href="https://bugs.documentfoundation.org/show_bug.cgi?id=167222"&gt;tdf#167222&lt;/a&gt; bugdoc
looks like now in Writer:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-floattable12/new.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-floattable12/new.png"&gt;&lt;figcaption&gt;Floating table, followed by heading: new Writer render&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And here is how it used to look like:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-floattable12/old.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-floattable12/old.png"&gt;&lt;figcaption&gt;Floating table, followed by heading: old Writer render&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And here is the reference rendering:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-floattable12/ref.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-floattable12/ref.png"&gt;&lt;figcaption&gt;Floating table, followed by heading: reference render&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This means that we leave layout for shapes unchanged in general: shapes anchored in headings are
still considered to be part of headings and don't split. But for floating tables, we now allow them
to split and use space at a previous page if they fit there.&lt;/p&gt;
&lt;h2 id="how-is-this-implemented"&gt;How is this implemented?&lt;a class="headerlink" href="#how-is-this-implemented" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you would like to know a bit more about how this works, continue reading... :-)&lt;/p&gt;
&lt;p&gt;As usual, the high-level problem was addressed by a series of small changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/77f0dc4347b8802c56121ca1c5ef59209970214a"&gt;tdf#167222 sw floattable: allow split of fly and its keep-together anchor text&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/44c0872bf5f1b658b126d8d928c795e74c0e8ecd"&gt;Related: tdf#167222 sw floattable: fix split of fly and its 'keep' anchor text&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/e1522e2b1985f6ebdbf442bdbd55cbc5f2b85dd6"&gt;Related: tdf#167222 sw floattable: fix split of fly and its heading text w/ ftn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/a5154c0de7679e2abc78b33b351025ea5e54a479"&gt;sw: fix assertion failure in SwFrameShell::Execute()&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/e03da71738c72bbaecb824b4ba356a0a9923a0ff"&gt;Related: tdf#167222 sw floattable: fix split of fly and heading text fit check&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="want-to-start-using-this"&gt;Want to start using this?&lt;a class="headerlink" href="#want-to-start-using-this" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can get a development edition of Collabora Online 25.04 and try it out yourself right now: &lt;a href="https://www.collaboraonline.com/code/"&gt;try
the development edition&lt;/a&gt;.  Collabora intends to continue
supporting and contributing to LibreOffice, the code is merged so we expect all of this work will be
available in TDF's next release too (26.2).&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Miklos Vajna</dc:creator><pubDate>Fri, 15 Aug 2025 08:14:19 +0200</pubDate><guid>tag:vmiklos.hu,2025-08-15:/blog/sw-floattable12.html</guid><category>libreoffice</category><category>en</category></item><item><title>Interdependent tracked changes improvements in Writer, part 2</title><link>https://vmiklos.hu/blog/sw-interdependent-redline-improvements2.html</link><description>&lt;p&gt;Writer has some support for interdependent (or hierarchical) tracked changes: e.g. the case when you
have a delete on top of an insert. See the &lt;a href="https://vmiklos.hu/blog/sw-interdependent-redline-improvements.html"&gt;first
post&lt;/a&gt; for background.&lt;/p&gt;
&lt;p&gt;This work is primarily for &lt;a href="https://www.collaboraonline.com/"&gt;Collabora Online&lt;/a&gt;, but the feature is
available in desktop Writer as well.&lt;/p&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;a class="headerlink" href="#motivation" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With the already mentioned improvements in place, a few areas were still lacking: we didn't have UI
for all cases where the DOCX import was possible already; combining tracked changes (redlines) were
not complete (so you don't have to reject all parts of a logical redline one by one) and some of the
undo/redo code didn't work as expected.&lt;/p&gt;
&lt;h2 id="results-so-far"&gt;Results so far&lt;a class="headerlink" href="#results-so-far" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Here is a sample case where the UI was missing to create something that was possible to import from
DOCX: a format redline on top of an insert redline.&lt;/p&gt;
&lt;p&gt;If you had a document with an insert:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements2/1-baseline.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements2/1-baseline.png"&gt;&lt;figcaption&gt;Interdependent tracked change: just insert&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And you selected BBB to mark those characters as bold, we just updated the existing insert redline
to be bold:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements2/2-edit-old.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements2/2-edit-old.png"&gt;&lt;figcaption&gt;Interdependent tracked change: old, format is not tracked separately&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;But now we track a format change on top of the insert separately:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements2/3-edit-new.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements2/3-edit-new.png"&gt;&lt;figcaption&gt;Interdependent tracked change: new, format is tracked separately&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is also visible if you open the track changes dialog, which explains that now you have part of
the insert redline covered by a format redline:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements2/4-dialog.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements2/4-dialog.png"&gt;&lt;figcaption&gt;Interdependent tracked change: UI dialog now showing multiple redlines &lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="how-is-this-implemented"&gt;How is this implemented?&lt;a class="headerlink" href="#how-is-this-implemented" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you would like to know a bit more about how this works, continue reading... :-)&lt;/p&gt;
&lt;p&gt;As usual, the high-level problem was addressed by a series of small changes. Core side:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/cc2babfa0a960c7d52ea7997aea19dcf10c12d08"&gt;sw interdependent redlines: fix nPamEndtNI -&amp;gt; nPamEndNI typo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/82b24dd9748c6c0a2990e70bda0960ae26415390"&gt;tdf#166319 sw interdependent redlines: combine on reject of del-then-fmt's fmt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/612ba7b2bc5d1d12c10287094263f6d31983a3d8"&gt;tdf#166319 sw interdependent redlines: fix undo of reject of ins-then-del's del&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/eef0dfed817e40cd83e8ba8e290f45c224257f97"&gt;tdf#166319 sw interdependent redlines: add UI to create format inside insert&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/0566e8e1776921ecb26f0ddd0546ec10afeed8e0"&gt;tdf#166319 sw interdependent redlines: undo of creating an ins-then-fmt redline&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/e06eb6b4a6176692d25c758121012473fe638043"&gt;tdf#166319 sw interdependent redlines: redo of creating an ins-then-fmt redline&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/5ed41ca44bee5122a9db4aa946f6e3ecd9432574"&gt;tdf#166319 sw interdependent redlines: fix redo of reject of del-then-fmt's del&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/76c2168a276f0996deeac08ce176525821fb056e"&gt;tdf#166319 sw interdependent redlines: fix bad accept undo action for reject&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="want-to-start-using-this"&gt;Want to start using this?&lt;a class="headerlink" href="#want-to-start-using-this" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can get a development edition of Collabora Online 25.04 and try it out yourself right now: &lt;a href="https://www.collaboraonline.com/code/"&gt;try
the development edition&lt;/a&gt;.  Collabora intends to continue
supporting and contributing to LibreOffice, the code is merged so we expect all of this work will be
available in TDF's next release too (25.8).&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Miklos Vajna</dc:creator><pubDate>Tue, 08 Jul 2025 08:43:10 +0200</pubDate><guid>tag:vmiklos.hu,2025-07-08:/blog/sw-interdependent-redline-improvements2.html</guid><category>libreoffice</category><category>en</category></item><item><title>Interdependent tracked changes improvements in Writer</title><link>https://vmiklos.hu/blog/sw-interdependent-redline-improvements.html</link><description>&lt;p&gt;Writer has some support for interdependent (or hierarchical) tracked changes: e.g. the case when you
have a delete on top of an insert. While there were some working cases, handling of many
combinations were missing. I started to make systematic improvements in this area in the recent
past, this post gives you an overview what's done so far.&lt;/p&gt;
&lt;p&gt;This work is primarily for &lt;a href="https://www.collaboraonline.com/"&gt;Collabora Online&lt;/a&gt;, but the feature is
available in desktop Writer as well.&lt;/p&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;a class="headerlink" href="#motivation" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;DOCX files in Word can often have overlapping tracked changes: Writer tries to split these up to
make sure there is only one tracked change under the cursor at the same time. Still, it's possible
that you have a tracked change with multiple types: e.g. a delete on top of an insert.&lt;/p&gt;
&lt;p&gt;The focus in on 3 combinations which appear in DOCX files a lot: "insert, then delete", "insert,
then format" and "delete, then format".&lt;/p&gt;
&lt;p&gt;This mostly affects the UI and import/export filters of ODT and DOCX.&lt;/p&gt;
&lt;h2 id="results-so-far"&gt;Results so far&lt;a class="headerlink" href="#results-so-far" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Given an insert, then delete:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements/ins-then-del.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements/ins-then-del.png"&gt;&lt;figcaption&gt;Interdependent tracked change: insert, then delete&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Most operations worked nicely here, but in case your cursor was in the middle of AAA and you did a
reject, followed by an undo, proper handling of that was missing, now implemented.&lt;/p&gt;
&lt;p&gt;But then given an insert, then a format:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements/ins-then-fmt.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements/ins-then-fmt.png"&gt;&lt;figcaption&gt;Interdependent tracked change: insert, then format&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then a handling of more actions were missing:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;DOCX import is now implemented.&lt;/li&gt;
&lt;li&gt;ODT import is now implemented.&lt;/li&gt;
&lt;li&gt;Accepting when you're inside AAA is now implemented: the insert is accepted for BBB but the
   format stays unchanged.&lt;/li&gt;
&lt;li&gt;Rejecting when you're inside AAA is now implemented: the insert is rejected and BBB is also
   removed, together with the format on top of it.&lt;/li&gt;
&lt;li&gt;Accepting the BBB now correctly operates on the insert type, so the format type remains after
   accept.&lt;/li&gt;
&lt;li&gt;If you accept BBB, now the surrounding AAA and CCC also get accepted as well, as expected.&lt;/li&gt;
&lt;li&gt;Now if you reject BBB, then it gets removed from the document, since you rejected an insert.&lt;/li&gt;
&lt;li&gt;When you reject BBB, the surrounding AAA and CCC also get rejected.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The combined implementation of these should give you a smooth feeling in case you're used to how
Word works: if there is a format redline combined with an insert, then the operations act on the
insert type, and format is only accepted/rejected when there is no insert "under" the format.&lt;/p&gt;
&lt;p&gt;Similarly: it's a bit of an implementation detail that Writer splits redlines on DOCX import: so if
you e.g. accept AAA then we combine that with BBB and CCC when it makes sense, so you need to click
a lot less.&lt;/p&gt;
&lt;p&gt;Finally, given a delete, then a format:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements/del-then-fmt.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-interdependent-redline-improvements/del-then-fmt.png"&gt;&lt;figcaption&gt;Interdependent tracked change: delete, then format&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then again handling of some actions were missing:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;DOCX import is now implemented.&lt;/li&gt;
&lt;li&gt;ODT import is now implemented.&lt;/li&gt;
&lt;li&gt;ODT export is now implemented.&lt;/li&gt;
&lt;li&gt;Accepting AAA now correctly operates on the delete type of BBB.&lt;/li&gt;
&lt;li&gt;Rejecting AAA now correctly operates on the delete type of BBB.&lt;/li&gt;
&lt;li&gt;Accepting BBB now correctly works with the delete type.&lt;/li&gt;
&lt;li&gt;Accepting BBB now correctly tries to also accept AAA and CCC, too.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The current state is not yet complete, but it's a big improvement over what we had in the past,
which was mostly focusing on just "insert, then delete".&lt;/p&gt;
&lt;p&gt;You may wonder what about some other cases: if you insert some content with change tracking, that
always creates a new tracked change, so "insert" is never on top of something else. Similarly,
format is always on top of something. Finally the same type is never on top of itself.&lt;/p&gt;
&lt;h2 id="how-is-this-implemented"&gt;How is this implemented?&lt;a class="headerlink" href="#how-is-this-implemented" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you would like to know a bit more about how this works, continue reading... :-)&lt;/p&gt;
&lt;p&gt;As usual, the high-level problem was addressed by a series of small changes. Core side:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/096a40b27d07603880bbf120440ac169a87fe115"&gt;tdf#166319 sw interdependent redlines: fix undo of del on top of ins&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/ca7a6a57ad1e8d7aadffbbf3fe28d9aabed31286"&gt;tdf#166319 sw interdependent redlines: handle format on top of insert&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/8e85d559a68f980d99af4ded6a91b7f0458048b9"&gt;tdf#166319 sw interdependent redlines: handle accept of insert under format&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/3c039cb31239ba01e3d3b56c526bdb7ba6446032"&gt;tdf#166319 sw interdependent redlines: handle reject of insert under format&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/96faaaf83a1c8b897ce675d175b4d8756d0ea0df"&gt;tdf#166319 sw interdependent redlines: handle accept of delete under format&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/97066d4f5a89ad89d81a45c0b20ce404f9712fc7"&gt;tdf#166319 sw interdependent redlines: fix DOCX export of delete under format&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/d659f4b12a24e275e38ec5aa7406c32c9fa08c48"&gt;tdf#166319 sw interdependent redlines: handle reject of delete under format&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/ff110bb17b7e003bd205438af94badabeca007c6"&gt;tdf#166319 sw interdependent redlines: handle ODF import of insert under format&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/1a340196237ed075b337e6a0ac9f8a45132053bb"&gt;tdf#166319 sw interdependent redlines: handle ODF export of delete under format&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/08acfb815745e7f43ca43557feefcb68607d26c1"&gt;tdf#166319 sw interdependent redlines: handle ODF import of delete under format&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/8cabdef0b34210d026ea7a8229f321e272a49109"&gt;tdf#166319 sw interdependent redlines: handle accept of ins-then-fmt's fmt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/2292bda37378d7f782abbda42c026affd3fa59e5"&gt;tdf#166319 sw interdependent redlines: combine on accept of ins-then-fmt's fmt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/b6cba0119f8028b426f5eee55be9761971dbfdee"&gt;tdf#166319 sw interdependent redlines: handle reject of ins-then-fmt's fmt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/15bd73a093f1f944d504cf555918ca9e60d75c03"&gt;tdf#166319 sw interdependent redlines: combine on reject of ins-then-fmt's fmt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/5fedce78c8d79a3e86307523c3d74c7df98668f7"&gt;tdf#166319 sw interdependent redlines: handle accept of del-then-fmt's fmt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/98f0b23a48246507ced6de5b54d327d95f1725f9"&gt;tdf#166319 sw interdependent redlines: combine on accept of del-then-fmt's fmt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/569eb476bbdf83aab0f377da5cb7d2e8c77192b8"&gt;tdf#166319 sw interdependent redlines: handle reject of del-then-fmt's fmt&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="want-to-start-using-this"&gt;Want to start using this?&lt;a class="headerlink" href="#want-to-start-using-this" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can get a development edition of Collabora Online 25.04 and try it out yourself right now: &lt;a href="https://www.collaboraonline.com/code/"&gt;try
the development edition&lt;/a&gt;.  Collabora intends to continue
supporting and contributing to LibreOffice, the code is merged so we expect all of this work will be
available in TDF's next release too (25.8).&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Miklos Vajna</dc:creator><pubDate>Mon, 02 Jun 2025 13:54:44 +0200</pubDate><guid>tag:vmiklos.hu,2025-06-02:/blog/sw-interdependent-redline-improvements.html</guid><category>libreoffice</category><category>en</category></item><item><title>Reinstate for tracked changes in Writer</title><link>https://vmiklos.hu/blog/sw-redline-reinstate.html</link><description>&lt;p&gt;Writer has the concept of rejecting tracked changes: if a proposed insertion or deletion is not
wanted, then one can reject it to push back on the proposal. So far such an action left no trace in
the document, which is sometimes not wanted. Calling reinstate on a change behaves like reject, but
with history: it reinstates the original state, with the rejected change preserved in the document.&lt;/p&gt;
&lt;p&gt;This work is primarily for &lt;a href="https://www.collaboraonline.com/"&gt;Collabora Online&lt;/a&gt;, but the feature is
available in desktop Writer as well.&lt;/p&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;a class="headerlink" href="#motivation" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When Alice works on a document to insert e.g. new conditions for a contract, then perhaps Bob is not
happy with the proposal. But just rejecting the change "silently" would not be polite: the tracked
change then disappears, so possibly Alice thinks it was accepted and Bob didn't communicate the
pushback explicitly in the resulting document, either.&lt;/p&gt;
&lt;p&gt;Reinstate is meant to improve this interaction: if an insert is reinstated, then an explicit delete
is created on top of the insert, so Alice can see that Bob was not happy with the proposal. Or in
case Alice proposed a delete, Bob can reinstate that by adding the same content again to the
document, without typing the text manually after the delete.&lt;/p&gt;
&lt;p&gt;This is a UI feature: the resulting model still only contains inserts and deletes, so it works even with
DOCX files.&lt;/p&gt;
&lt;h2 id="results-so-far"&gt;Results so far&lt;a class="headerlink" href="#results-so-far" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Given an insert:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-redline-reinstate/insert.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-redline-reinstate/insert.png"&gt;&lt;figcaption&gt;Reinstate: an insert&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now you can easily create a delete on top of the insert:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-redline-reinstate/insert-after.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-redline-reinstate/insert-after.png"&gt;&lt;figcaption&gt;Reinstate: a reinstated insert&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And given a delete:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-redline-reinstate/delete.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-redline-reinstate/delete.png"&gt;&lt;figcaption&gt;Reinstate: a delete&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now you can easily create an insert right after the delete, preserving complex content:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://share.vmiklos.hu/blog/sw-redline-reinstate/delete-after.png"&gt;&lt;figure&gt;&lt;img src="https://share.vmiklos.hu/blog/sw-redline-reinstate/delete-after.png"&gt;&lt;figcaption&gt;Reinstate: a reinstated delete&lt;/figcaption&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As you can see, this creates the opposite of the original change as a new tracked change, so it will
in the end still reject the change, but without deleting the original change.&lt;/p&gt;
&lt;h2 id="how-is-this-implemented"&gt;How is this implemented?&lt;a class="headerlink" href="#how-is-this-implemented" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you would like to know a bit more about how this works, continue reading... :-)&lt;/p&gt;
&lt;p&gt;As usual, the high-level problem was addressed by a series of small changes. Core side:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/7af8b3d3305fe8344cb9339269c5dc3f1cd44650"&gt;cool#11357 sw redline reinstate: implement this for a single insert&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/1df71464588d4cfcba708cf00ef7b6ac94574c8f"&gt;cool#11357 sw redline reinstate: handle inserts in selection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/e312cf46fe840f04b729600db9efe89d5f58d6fe"&gt;cool#11357 sw redline reinstate: handle a single delete&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/db541619cb1ca83598ec479eb9f52e559a8fe72d"&gt;cool#11357 sw redline reinstate: handle a single rich delete&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/157c00922959adc8fd2e0203ed94dfd847479c54"&gt;cool#11357 sw redline reinstate: handle deletes in selection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/447935fba57f1b0f88c0b56cccf5bf971fb1e819"&gt;cool#11357 sw redline reinstate: simplify ReinstateRedlinesInSelection()&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/9c2c98ac7668e4a3a2e3a70cc54b632de5f79621"&gt;cool#11357 sw redline reinstate: add command state&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/1926105b47df7b15dd34a8c1135f83b936bf9926"&gt;cool#11357 sw redline reinstate: add a reinstate-and-next command&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/4535698e0b16bf003e8a3705e28f7347f509eb12"&gt;cool#11357 sw redline reinstate: add a reinstate-all command&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/01311bb1e4c2404354cce8934d36991d91d527b2"&gt;cool#11357 sw redline reinstate: avoid unwanted multi- or table selection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/fbf9465e2bc9f878723674d1eff13e0c69656057"&gt;cool#11357 sw redline reinstate: fix undo string for a single redline&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/7d702ebbfcda41ce2972e30b2a1e493c320df67c"&gt;cool#11357 sw redline reinstate: fix undo count &amp;amp; string for multiple redlines&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.libreoffice.org/core/commit/dcd3427149c33852428b4198c22f6f858125c294"&gt;cool#11357 sw redline reinstate: add to the context menu for text&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Online side:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/collaboraonline/online/commit/3d7933974241fe5d015a9d80f2cc8bde1c1d352e"&gt;cool#11357 sw redline reinstate: add UI for this&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="want-to-start-using-this"&gt;Want to start using this?&lt;a class="headerlink" href="#want-to-start-using-this" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can get a development edition of Collabora Online 25.04 and try it out yourself right now: &lt;a href="https://www.collaboraonline.com/code/"&gt;try
the development edition&lt;/a&gt;.  Collabora intends to continue
supporting and contributing to LibreOffice, the code is merged so we expect all of this work will be
available in TDF's next release too (25.8).&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Miklos Vajna</dc:creator><pubDate>Thu, 08 May 2025 08:44:48 +0200</pubDate><guid>tag:vmiklos.hu,2025-05-08:/blog/sw-redline-reinstate.html</guid><category>libreoffice</category><category>en</category></item></channel></rss>