View Issue Details

IDProjectCategoryView StatusLast Update
0014597ScribusScripterpublic2026-07-01 20:00
ReporterJLuc Assigned Toale  
PrioritynormalSeverityfeatureReproducibilityN/A
Status closedResolutionfixed 
PlatformLinuxOSUbuntuOS Version14.04
Fixed in Version1.7.4.svn 
Summary0014597: [PATCH] Script command to get preflight errors or warnings
DescriptionProvide scripter a command
to get preflight errors or warnings
or to export them to a file
so as to manage them in some not interactive way
Additional InformationEither get them all according to the document preferences for preflight check
or enable the scripter function to receive a parameter being a specific preflight check option as : check image resolution / or / check text overflow ...
TagsNo tags attached.
PatchYes

Activities

ale

2025-11-26 21:55

manager   ~0053308

I'm working on a way to get the scripter to export the information from the preflight verifier to json.

JLuc

2025-12-23 11:19

developer   ~0053402

That'd be great @ale !

ale

2026-02-15 19:51

manager   ~0053496

Here is my proposal...
scripter-export-preflight.diff (9,860 bytes)   
From 3f96675c8faa0738fa41ab0bbc0e3ff73b6f5288 Mon Sep 17 00:00:00 2001
From: ale rimoldi <ale@graphicslab.org>
Date: Sun, 15 Feb 2026 20:42:00 +0100
Subject: scripter command to export preflight information


diff --git a/scribus/plugins/scriptplugin/cmddoc.cpp b/scribus/plugins/scriptplugin/cmddoc.cpp
index 00b63cd7e..ef858d963 100644
--- a/scribus/plugins/scriptplugin/cmddoc.cpp
+++ b/scribus/plugins/scriptplugin/cmddoc.cpp
@@ -6,6 +6,7 @@ for which a new license (GPL+exception) is in place.
 */
 #include "cmddoc.h"
 #include "cmdutil.h"
+#include "documentchecker.h"
 #include "documentinformation.h"
 #include "pyesstring.h"
 #include "scribuscore.h"
@@ -14,6 +15,11 @@ for which a new license (GPL+exception) is in place.
 #include "units.h"
 
 #include <QApplication>
+#include <qdebug.h>
+#include <qjsonarray.h>
+#include <qjsondocument.h>
+#include <qjsonobject.h>
+#include <qobject.h>
 
 /*
 newDocument(size, margins, orientation, firstPageNumber,
@@ -562,6 +568,172 @@ PyObject* scribus_applymasterpage(PyObject* /* self */, PyObject* args)
 	Py_RETURN_NONE;
 }
 
+PyObject* scribus_exportdocumentcheck(PyObject* /* self */, PyObject* args, PyObject* kw)
+{
+	PyESString targetFilenameArg;
+	PyESString checkProfileNameArg;
+	bool showNonPrintingLayerErrors = false;
+	char *kwargs[] = {const_cast<char*>("jsonFilename"), const_cast<char*>("checkProfile"),
+		const_cast<char*>("nonPrintingLayers"), nullptr};
+	if (!PyArg_ParseTupleAndKeywords(args, kw, "|es$esp", kwargs,
+			"utf-8", targetFilenameArg.ptr(), "utf-8", checkProfileNameArg.ptr(),
+			&showNonPrintingLayerErrors))
+		return nullptr;
+
+	if (!checkHaveDocument())
+		return nullptr;
+	const QString targetFileName(targetFilenameArg.c_str());
+	const QString checkProfileName(checkProfileNameArg.c_str());
+
+	ScribusDoc* currentDoc = ScCore->primaryMainWindow()->doc;
+
+	if (checkProfileName.isEmpty())
+		DocumentChecker::checkDocument(currentDoc);
+	else
+		DocumentChecker::checkDocument(currentDoc, checkProfileName);
+
+	// "Standard" Errors
+	// (Taken from PreflightError in scribusstruct.h)
+	QMap<PreflightError, QString> errorsList = {
+		{PreflightError::MissingGlyph, "MissingGlyph"},
+		{PreflightError::TextOverflow, "TextOverflow"},
+		{PreflightError::ObjectNotOnPage, "ObjectNotOnPage"},
+		{PreflightError::MissingImage, "MissingImage"},
+		{PreflightError::ImageDPITooLow, "ImageDPITooLow"},
+		{PreflightError::Transparency, "Transparency"},
+		{PreflightError::PDFAnnotField, "PDFAnnotField"},
+		{PreflightError::PlacedPDF, "PlacedPDF"},
+		{PreflightError::ImageDPITooHigh, "ImageDPITooHigh"},
+		{PreflightError::ImageIsGIF, "ImageIsGIF"},
+		{PreflightError::BlendMode, "BlendMode"},
+		{PreflightError::WrongFontInAnnotation, "WrongFontInAnnotation"},
+		{PreflightError::NotCMYKOrSpot, "NotCMYKOrSpot"},
+		{PreflightError::DeviceColorsAndOutputIntent, "DeviceColorsAndOutputIntent"},
+		{PreflightError::FontNotEmbedded, "FontNotEmbedded"},
+		{PreflightError::EmbeddedFontIsOpenType, "EmbeddedFontIsOpenType"},
+		{PreflightError::OffConflictLayers, "OffConflictLayers"},
+		{PreflightError::PartFilledImageFrame, "PartFilledImageFrame"},
+		{PreflightError::MarksChanged, "MarksChanged"},
+		{PreflightError::AppliedMasterDifferentSide, "AppliedMasterDifferentSide"},
+		{PreflightError::EmptyTextFrame, "EmptyTextFrame"},
+		{PreflightError::ImageHasProgressiveEncoding, "ImageHasProgressiveEncoding"},
+	};
+	// Custom Errors
+	// "DocumentModifiedAfterMarksUpdate"
+
+	QJsonObject json;
+
+	if (currentDoc->notesChanged())
+	{
+		json["marks"] = QJsonObject{{"", "DocumentModifiedAfterMarksUpdate"}};
+	}
+	else
+	{
+		json["marks"] = QJsonObject{};
+	}
+
+	QJsonArray jsonLayers;
+	for (const auto& [layerId, layerErrors]: currentDoc->docLayerErrors.asKeyValueRange())
+	{
+		for (const auto& [key, errorLevel]: layerErrors.asKeyValueRange())
+		{
+			jsonLayers.push_back(QJsonObject{{"layer", currentDoc->layerName(layerId)}, {"error", errorsList[key]}});
+		}
+	}
+	json["layers"] = jsonLayers;
+
+	QMap<int, QVector<QPair<QString, QString>>> pagesWithErrors;
+
+	for (auto [pageItem, itemError]: currentDoc->masterItemErrors.asKeyValueRange())
+	{
+		const int pageNumber = pageItem->OwnPage;
+		for (auto [errorCode, errorLevel]: itemError.asKeyValueRange())
+		{
+			if (!showNonPrintingLayerErrors && !currentDoc->layerPrintable(pageItem->m_layerID))
+				continue;
+
+			if (!pagesWithErrors.contains(pageNumber))
+				pagesWithErrors[pageNumber] = {};
+
+			pagesWithErrors[pageNumber].push_back({pageItem->itemName(), errorsList[errorCode]});
+		}
+	}
+
+	QJsonObject jsonMasterPages;
+	for (auto [pageNumber, value]: pagesWithErrors.asKeyValueRange())
+	{
+		QJsonArray pageItems;
+		for (const auto& [item, error]: value)
+		{
+			pageItems.push_back(QJsonObject{{{"item", item}, {"error", error}}});
+		}
+		jsonMasterPages[currentDoc->MasterPages.at(pageNumber)->pageName()] = pageItems;
+	}
+	json["masterPages"] = jsonMasterPages;
+
+
+	pagesWithErrors.clear();
+
+	for (auto [pageNumber, pageErrors]: currentDoc->pageErrors.asKeyValueRange())
+	{
+		pagesWithErrors[pageNumber] = {};
+
+		for (auto [errorCode, value]: pageErrors.asKeyValueRange())
+		{
+			pagesWithErrors[pageNumber].push_back({"", errorsList[errorCode]});
+		}
+	}
+	QJsonArray jsonFreeItems;
+	for (auto [pageItem, itemErrors]: currentDoc->docItemErrors.asKeyValueRange())
+	{
+		if (!showNonPrintingLayerErrors && !currentDoc->layerPrintable(pageItem->m_layerID))
+			continue;
+		const int pageNumber = pageItem->OwnPage;
+		if (!pagesWithErrors.contains(pageNumber))
+			pagesWithErrors[pageNumber] = {};
+		for (auto [errorCode, errorLevel]: itemErrors.asKeyValueRange())
+		{
+			pagesWithErrors[pageNumber].push_back({pageItem->itemName(), errorsList[errorCode]});
+		}
+		if (currentDoc->OnPage(pageItem) == -1)
+		{
+			jsonFreeItems.push_back(pageItem->itemName());
+		}
+	}
+
+	QJsonObject jsonPages;
+	for (auto [pageNumber, value]: pagesWithErrors.asKeyValueRange())
+	{
+		QJsonArray pageItems;
+		for (const auto& [item, error]: value)
+		{
+			pageItems.push_back(QJsonObject{{{"item", item}, {"error", error}}});
+		}
+		jsonPages[QString::number(pageNumber + 1)] = pageItems;
+	}
+	json["pages"] = jsonPages;
+
+	json["freeItems"] = jsonFreeItems;
+
+	currentDoc->pageErrors.clear();
+	currentDoc->docItemErrors.clear();
+	currentDoc->masterItemErrors.clear();
+	currentDoc->docLayerErrors.clear();
+
+	if (targetFileName.isEmpty())
+		return PyUnicode_FromString(QJsonDocument(json).toJson());
+
+	QFile saveFile(targetFileName);
+	if (!saveFile.open(QIODevice::WriteOnly))
+	{
+		PyErr_SetString(ScribusException, QObject::tr("Failed to open the file '%1' for writing","python error").arg(targetFileName).toUtf8().constData());
+		return nullptr;
+	}
+	saveFile.write(QJsonDocument(json).toJson());
+
+	Py_RETURN_NONE;
+}
+
 /*! HACK: this removes "warning: 'blah' defined but not used" compiler warnings
 with header files structure untouched (docstrings are kept near declarations)
 PV */
diff --git a/scribus/plugins/scriptplugin/cmddoc.h b/scribus/plugins/scriptplugin/cmddoc.h
index 8a01a35e5..6638b2a0c 100644
--- a/scribus/plugins/scriptplugin/cmddoc.h
+++ b/scribus/plugins/scriptplugin/cmddoc.h
@@ -385,6 +385,49 @@ Apply master page masterPageName on page pageNumber.\n\
 "));
 PyObject* scribus_applymasterpage(PyObject* self, PyObject* args);
 
+PyDoc_STRVAR(scribus_exportdocumentcheck__doc__,
+QT_TR_NOOP("exportDocumentCheck([jsonFilePath, checkProfile=\"\", nonPrintingLayers=False])\n\
+\n\
+Export the result of the preflight verifier into a JSON string or a JSON file.\n\
+\n\
+jsonFilePath: the path to the json file to be written. If empty, a JSON string \n\
+is returned.\n\
+checkProfileName is the name of an existing preflight verifier profile.\n\
+\n\
+The resulting JSON always has five sections:\n\
+- freeItems: a list of page items that are in no page;\n\
+- layers: a list of errors in layers;\n\
+- marks: errors relating the the marks;\n\
+- masterPages: list of erroneous page items for each master page;\n\
+- pages: list of erroneous page items for each page.\n\
+\n\
+The errors are strings, mostly names from the PreflightError enum in scribusstruct.h:\n\
+- MissingGlyph\n\
+- TextOverflow\n\
+- ObjectNotOnPage\n\
+- MissingImage\n\
+- ImageDPITooLow\n\
+- Transparency\n\
+- PDFAnnotField\n\
+- PlacedPDF\n\
+- ImageDPITooHigh\n\
+- ImageIsGIF\n\
+- BlendMode\n\
+- WrongFontInAnnotation\n\
+- NotCMYKOrSpot\n\
+- DeviceColorsAndOutputIntent\n\
+- FontNotEmbedded\n\
+- EmbeddedFontIsOpenType\n\
+- OffConflictLayers\n\
+- PartFilledImageFrame\n\
+- MarksChanged\n\
+- AppliedMasterDifferentSide\n\
+- EmptyTextFrame\n\
+- ImageHasProgressiveEncoding\n\
+- DocumentModifiedAfterMarksUpdate\n\
+"));
+PyObject* scribus_exportdocumentcheck(PyObject* self, PyObject* args, PyObject* kw);
+
 #endif
 
 
diff --git a/scribus/plugins/scriptplugin/scriptplugin.cpp b/scribus/plugins/scriptplugin/scriptplugin.cpp
index fabb7350a..bc790d097 100644
--- a/scribus/plugins/scriptplugin/scriptplugin.cpp
+++ b/scribus/plugins/scriptplugin/scriptplugin.cpp
@@ -326,6 +326,7 @@ PyMethodDef scribus_methods[] = {
 	{ "deselectAll", (PyCFunction) scribus_deselectall, METH_NOARGS, tr(scribus_deselectall__doc__)},
 	{ "docChanged", scribus_docchanged, METH_VARARGS, tr(scribus_docchanged__doc__)},
 	{ "editMasterPage", scribus_editmasterpage, METH_VARARGS, tr(scribus_editmasterpage__doc__)},
+	{ "exportDocumentCheck", (PyCFunction) scribus_exportdocumentcheck, METH_VARARGS|METH_KEYWORDS, tr(scribus_exportdocumentcheck__doc__)},
 	{ "fileDialog", (PyCFunction) scribus_filedialog, METH_VARARGS|METH_KEYWORDS, tr(scribus_filedialog__doc__)},
 	{ "fileQuit", scribus_filequit, METH_VARARGS, tr(scribus_filequit__doc__)},
 	{ "flipObject", scribus_flipobject, METH_VARARGS, tr(scribus_flipobject__doc__)},
scripter-export-preflight.diff (9,860 bytes)   

JLuc

2026-06-24 09:27

developer   ~0053889

@ale, would you provide an example on how to use this new feature ?

ale

2026-06-24 15:57

manager   ~0053890

here it is

print(scribus.exportDocumentCheck())


typing

help(exportDocumentCheck)


in the Scripter console will give you the help message with the signature and a few more details.

JLuc

2026-06-25 07:27

developer   ~0053894

Oh thats pretty simple, thanks.
Have to wait for updated appimage so as to give it a go now.

ale

2026-06-25 07:44

manager   ~0053895

The Appimage on Gitlab should have it.
(I have it locally, and I get my code through the Gitlab repository)

JLuc

2026-06-25 13:54

developer   ~0053901

Last edited: 2026-06-25 13:57

I searched quite a while and found it here : https://gitlab.com/scribus/scribus/-/artifacts

For who might find this thread, the help reads as : « Help on built-in function exportDocumentCheck in module scribus:

exportDocumentCheck(...)
    exportDocumentCheck([jsonFilePath, checkProfileName="", nonPrintingLayers=False])
    Export the result of the preflight verifier into a JSON string or a JSON file.
    jsonFilePath: the path to the json file to be written. If empty, a JSON string is returned. checkProfileName is the name of an existing preflight verifier profile.
    The resulting JSON always has five sections:
    - freeItems: a list of page items that are in no page;
    - layers: a list of errors in layers;
    - marks: errors relating to the marks;
    - masterPages: list of erroneous page items for each master page;
    - pages: list of erroneous page items for each page.
    The errors are strings, mostly names from the PreflightError enum in scribusstruct.h: - MissingGlyph - TextOverflow - ObjectNotOnPage - MissingImage - ImageDPITooLow - Transparency - PDFAnnotField - PlacedPDF - ImageDPITooHigh - ImageIsGIF - BlendMode - WrongFontInAnnotation - NotCMYKOrSpot - DeviceColorsAndOutputIntent - FontNotEmbedded - EmbeddedFontIsOpenType - OffConflictLayers - PartFilledImageFrame - MarksChanged - AppliedMasterDifferentSide - EmptyTextFrame - ImageHasProgressiveEncoding - DocumentModifiedAfterMarksUpdate
»

Great !!!!

Rq : i guess the function, or its help, should declare an empty default value for jsonFilePath argument.

ale

2026-06-25 14:46

manager   ~0053902

The direct link to the latest Appimage created on Gitlab is:

https://gitlab.com/scribus/scribus/-/jobs/artifacts/master/raw/Scribus-nightly-x86_64.AppImage?job=appimage%3Alinux

You can find on impagina.org , which I should really update. it's the last download link the Download section.
And also update the Scripter API documentation in there.

If somebody wants to help, just a ring a bell.
The task is to move the current theme to the Hugo SSG...

Issue History

Date Modified Username Field Change
2017-01-29 19:16 JLuc New Issue
2017-01-29 19:21 JLuc Additional Information Updated
2017-01-30 23:18 jghali Severity minor => feature
2025-11-26 21:55 ale Note Added: 0053308
2025-11-26 21:55 ale Assigned To => ale
2025-11-26 21:55 ale Status new => assigned
2025-11-26 21:55 ale Status assigned => acknowledged
2025-12-23 11:19 JLuc Note Added: 0053402
2026-02-15 19:51 ale Note Added: 0053496
2026-02-15 19:51 ale File Added: scripter-export-preflight.diff
2026-02-15 19:51 ale Summary Script command to get preflight errors or warnings => [PATCH] Script command to get preflight errors or warnings
2026-02-15 19:51 ale Patch No => Yes
2026-06-16 20:10 cbradney Status acknowledged => resolved
2026-06-16 20:10 cbradney Resolution open => fixed
2026-06-16 20:10 cbradney Fixed in Version => 1.7.4.svn
2026-06-24 09:27 JLuc Note Added: 0053889
2026-06-24 15:57 ale Note Added: 0053890
2026-06-25 07:27 JLuc Note Added: 0053894
2026-06-25 07:44 ale Note Added: 0053895
2026-06-25 13:54 JLuc Note Added: 0053901
2026-06-25 13:55 JLuc Note Edited: 0053901
2026-06-25 13:56 JLuc Note Edited: 0053901
2026-06-25 13:57 JLuc Note Edited: 0053901
2026-06-25 14:46 ale Note Added: 0053902
2026-07-01 20:00 cbradney Status resolved => closed