ODT footnote import

Previous topic - Next topic

chalavi

Hi, I'm an old user of Scribus (thank's for the team) and always has problems with footnotes.
With Claude, we have made some modifications to the code (odt2im) and a footnote system is running. Not perfect of course but usuable even for big document.
Ask for the modified files (importodt.cpp and importodt.h) if you want to compile Scribus with this adapted version (ask for version Scribus 1.6.6 or Scribus 1.7.3)
Here is the story in english and in french.

Vic

----------------------------------------------------------------------------
# [EN] ODT footnote import: why we dropped Scribus's native notes system

I'm developing, with valuable help from Claude (Anthropic), an addition to the ODT import plugin (`odt2im`) to handle footnotes — until now completely ignored on import (`text:note` simply wasn't recognized). Use case: historical booklets made of about ten articles per issue, each imported from a `.odt` file written in LibreOffice by a different author, with footnotes used regularly.

## First approach: going through Scribus's notes system

The first version converted each ODT note into a real Scribus `Mark`/`TextNote` object, attached to a `NotesStyle` configured as an endnote (simpler to auto-materialize than a classic footnote). It worked... up to a point.

On realistic documents (several hundred pages, 1000+ notes), we ran into several distinct instabilities in a row, all located in Scribus's native notes-handling code (not in our plugin):

- `PageItem_NoteFrame::layout()` crashes (SIGSEGV) on an unguarded dereference of `m_masterFrame`, when automatic width adjustment is enabled on an endnotes-type style with no master frame.
- Same issue in `ScribusDoc::updateNotesFramesSettings()`, this time with automatic welding (`AutoWeld`).
- Switching from endnotes to footnotes from the Notes Styles editor enters an infinite loop on a large document (`PageItem_NoteFrame::layout()` and `ScribusDoc::updateMarks()` repeatedly calling into each other without ever converging) — confirmed by two `gdb` snapshots taken a few minutes apart, with strictly identical call stacks.
- Superscripts (ordinal suffixes like "XIVe siècle") inside note bodies end up visibly, excessively shrunk: the source ODT already encodes a reduced font size for those characters, and Scribus applies its own automatic superscript scaling on top of that — a compounding effect that doesn't happen the same way in the main body text.

Each of these was individually worked around on the plugin side (disabling options on the `NotesStyle`, etc.), but taken together they raised a real question: is this system, as it currently stands, reliable at this scale?

## Second, simpler approach: plain-text notes

We ended up dropping the `Mark`/`TextNote`/`NotesStyle` system entirely. Now:

- The note reference in the main text is just a superscript number, written as ordinary text (the same formatting mechanism as any other superscript in the document — so no more compounded size reduction).
- Each note's content is collected while parsing, then appended at the end of the article as a numbered list, by directly reusing the plugin's existing functions for the main body text (`parseTextParagraph`/`parseTextSpan`) — so the same formatting fidelity (fonts, character styles, superscripts...), with no separate conversion code to maintain.
- Note text is appended right after the main text, in the same frame — the plugin never creates a page or frame itself. Any overflow is left to Scribus's native features (automatic text frames / unlinking frames with automatic text flow) rather than reimplementing pagination logic ourselves.

## The trade-off, stated plainly

This approach loses two things the native system provided:
- **Automatic renumbering**: numbers are frozen at import time. Reordering notes afterward in Scribus means renumbering by hand.
- The **footnote/endnote toggle** built into the Notes Styles editor — which no longer applies here, obviously.

For our workflow (import once per article, then layout/proofreading, with no later re-editing of the notes themselves), that's a clearly acceptable trade-off given the robustness gained.

## Why post this

Two reasons for sharing this here rather than keeping it to ourselves:
1. If anyone else is developing or maintaining an import/export feature touching Scribus's notes system, these instabilities (already reported separately on the tracker, with GDB traces) might be worth knowing about before relying on it at scale.
2. If anyone has already run into — and possibly worked around differently — these same limitations of the native notes system, I'd welcome any feedback before taking this plugin further.

---

# [FR] Import des notes de bas de page ODT : pourquoi on a abandonné le système de notes natif de Scribus

Je développe, avec l'aide précieuse de Claude (Anthropic), un ajout au plugin d'import ODT (`odt2im`) pour gérer les notes de bas de page — jusqu'ici totalement ignorées à l'import (`text:note` n'était simplement pas reconnu). Le cas d'usage : des cahiers historiques composés d'une dizaine d'articles par numéro, chacun importé depuis un fichier `.odt` rédigé sous LibreOffice par un auteur différent, avec un usage courant des notes de bas de page.

## Première approche : passer par le système de notes de Scribus

La première version convertissait chaque note ODT en un vrai objet `Mark`/`TextNote` Scribus, rattaché à un `NotesStyle` configuré en note de fin (endnote — plus simple à matérialiser automatiquement qu'une note de bas de page classique). Ça fonctionnait... jusqu'à un certain point.

Sur des documents réalistes (plusieurs centaines de pages, 1000+ notes), on a enchaîné plusieurs instabilités bien distinctes, toutes situées dans le code natif de gestion des notes de Scribus (pas dans notre plugin) :

- `PageItem_NoteFrame::layout()` plante (SIGSEGV) sur un déréférencement de `m_masterFrame` non protégé, quand l'ajustement automatique de largeur est actif sur un style de notes de fin sans cadre maître.
- Même chose côté `ScribusDoc::updateNotesFramesSettings()`, avec le soudage automatique (`AutoWeld`) cette fois.
- La bascule notes de fin → notes de bas de page, depuis l'éditeur de styles de notes, entre dans une boucle infinie sur un document volumineux (`PageItem_NoteFrame::layout()` ↔ `ScribusDoc::updateMarks()` qui se rappellent mutuellement sans jamais converger) — confirmé par deux instantanés `gdb` strictement identiques à quelques minutes d'écart.
- Les exposants (ordinaux type « XIVe siècle ») dans le corps des notes ressortent visuellement rétrécis à l'excès : l'ODT source encode déjà une taille de police réduite pour ces caractères, et Scribus applique par-dessus sa propre mise à l'échelle automatique de l'exposant — un cumul qui ne se produit pas de la même façon dans le texte principal.

Chacun de ces points a été contourné individuellement côté plugin (désactivation d'options sur le `NotesStyle`, etc.), mais leur accumulation a fini par poser une vraie question de fond : est-ce que ce système, dans son état actuel, est fiable à cette échelle ?

## Deuxième approche, plus simple : des notes en texte plein

On a fini par abandonner entièrement le système `Mark`/`TextNote`/`NotesStyle`. Désormais :

- L'appel de note dans le texte principal est un simple chiffre en exposant, écrit comme du texte normal (même mécanisme de mise en forme que n'importe quel autre exposant du document — donc plus de double réduction de taille).
- Le contenu de chaque note est accumulé pendant le parsing, puis ajouté en fin d'article sous forme de liste numérotée, en réutilisant **directement** les fonctions existantes du plugin qui gèrent déjà le texte principal (`parseTextParagraph`/`parseTextSpan`) — donc la même richesse de mise en forme (polices, styles de caractères, exposants...), sans code de conversion séparé à maintenir.
- Le texte des notes est ajouté à la suite du texte principal, dans le même cadre — pas de création de page ou de cadre par le plugin. En cas de débordement, on s'appuie sur les fonctionnalités natives de Scribus (cadres de texte automatiques / délier avec découpe automatique du texte) plutôt que de réimplémenter une gestion de pagination.

## Le compromis assumé

Cette approche perd deux choses que le système natif offrait :
- La **renumérotation automatique** : les numéros sont figés au moment de l'import. Si on modifie l'ordre des notes après coup dans Scribus, il faut renuméroter à la main.
- La **bascule footnote/endnote** intégrée à l'éditeur de styles de notes — qui n'a plus de sens ici, forcément.

Pour notre flux de travail (import une fois par article, puis mise en page/relecture, sans réédition ultérieure des notes elles-mêmes), c'est un compromis largement acceptable au regard du gain en robustesse.

## Pourquoi ce message

Deux raisons de le partager ici plutôt que de garder ça pour nous :
1. Si quelqu'un d'autre développe ou maintient un import/export touchant aux notes de Scribus, ces instabilités (déjà remontées sur le tracker séparément, avec traces GDB) sont peut-être utiles à connaître avant de s'appuyer dessus à grande échelle.
2. Si quelqu'un a déjà rencontré — et éventuellement contourné autrement — ces mêmes limites du système de notes natif, je suis preneur de retours avant d'aller plus loin sur ce plugin.