SuperPrint Application web professionnelle de PAO (Publication Assistée par Ordinateur) Professional web-based Desktop Publishing (DTP) application
Architecture
Architecture
Structure des fichiers
File Structure
SUPERPRINT12master/ ├── index.html ─ SPA principale (~3 000 lignes), modales, toolbar, sidebars ├── documentation.html ─ Ce fichier / This file ├── ai-proxy.php ─ Proxy serveur pour les APIs IA (CORS + clés) ├── service-worker.js ─ PWA offline caching (network-first) ├── manifest.webmanifest ─ PWA manifest ├── robots.txt / sitemap.xml ├── JS/ │ ├── main.js ─ Logique applicative complète (81 481 lignes) │ ├── simple-pen-tool.js ─ Module outil plume standalone │ ├── mobile-widgets.js ─ Widgets mobiles │ ├── fabric.min.js ─ Fabric.js 5.3.0 │ ├── jspdf.umd.min.js ─ Génération PDF │ ├── jszip.min.js ─ Gestion ZIP (IDML, ODT, Print-to-Web) │ ├── pdf.min.js ─ PDF.js (import PDF) │ ├── paper-full.min.js ─ Paper.js (opérations booléennes) │ ├── mammoth.min.js ─ Conversion DOCX → HTML │ ├── hypher.js ─ Moteur de césure │ └── hyphenation-*.js ─ Dictionnaires césure (fr, en, de, es, it) ├── CSS/ │ ├── main.css ─ Feuille de styles principale │ └── mobile-widgets.css ─ Styles mobiles ├── SP/ ─ Assets & templates └── icons/ ─ Icônes PWA
Stack technique
Technical Stack
| Bibliothèque | Library | Version | Rôle | Role |
|---|---|---|---|---|
| Fabric.js | 5.3.0 | Moteur de rendu canvas (objets, texte, images, événements) | Canvas rendering engine (objects, text, images, events) | |
| jsPDF | 2.x | Génération PDF multi-pages avec fond perdu | Multi-page PDF generation with bleed | |
| JSZip | 3.x | Gestion fichiers ZIP (import IDML/ODT, export Print-to-Web) | ZIP file handling (IDML/ODT import, Print-to-Web export) | |
| PDF.js | 3.x | Rendu PDF pour import page par page | PDF rendering for page-by-page import | |
| Paper.js | 0.12 | Opérations booléennes de tracés (Pathfinder) | Boolean path operations (Pathfinder) | |
| Mammoth.js | 1.x | Conversion DOCX → HTML | DOCX to HTML conversion | |
| Hypher | 0.2 | Moteur de césure (5 langues) | Hyphenation engine (5 languages) |
Partie 1 — Catalogue des fonctions 475+
Part 1 — Function Catalog 475+
3.1 Gestion des pages 3.1 Page Management 16
| # | Fonction | Function | Ligne | Type | Paramètres | Params | Description FR | Description EN |
|---|---|---|---|---|---|---|---|---|
| 1 | createNewPage | 13339 | decl | — | Crée une page vierge et l'ajoute au document | Creates a new blank page and appends it | ||
| 2 | renderAllPages | 7255 | decl | — | Détruit les canvas existants et recrée tous les conteneurs de pages | Destroys existing canvases and re-creates all page containers | ||
| 3 | createPageCanvas | 7531 | decl | container, index, width, height, position | Crée un canvas Fabric pour une page simple | Creates a Fabric canvas for a single page | ||
| 4 | goToPage | 1623 | decl | pageIndex | Fait défiler la vue vers une page spécifique | Scrolls viewport to a specific page | ||
| 5 | updatePage | 36893 | decl | — | Met à jour l'affichage de la page courante | Updates the current page display/indicator | ||
| 6 | changePage | 36899 | decl | delta | Navigue en avant/arrière de delta pages | Navigate forward/backward by delta pages | ||
| 7 | updatePageIndicator | 20907 | decl | — | Met à jour le badge de numéro de page dans l'UI | Updates the page number UI badge | ||
| 8 | getCurrentPageIndex | 23049 | decl | — | Retourne l'index de la page active | Returns the index of the currently active page | ||
| 9 | getActiveCanvas | 13307 | decl | — | Retourne le canvas Fabric actuellement actif | Returns the currently active Fabric canvas | ||
| 10 | drawMargins | 13346 | decl | canvas, pageWidth, pageHeight | Dessine les repères de marge et de fond perdu | Draws margin/bleed guide lines on a canvas | ||
| 11 | saveAllPages | 11095 | decl | — | Sérialise tous les canvas en JSON | Serializes all page canvases to JSON | ||
| 12 | applySelectionHighlightAfterRender | 7517 | decl | — | Surligne la page active en mode planche après le rendu | Highlights the active spread page after render | ||
| 13 | duplicateObject | 20870 | decl | — | Duplique l'objet sélectionné | Duplicates the currently selected object | ||
| 14 | calculateImposition | 23064 | decl | numPages | Calcule l'ordre d'imposition (cahier) | Calculates imposition (booklet) page order | ||
| 15 | closeImpositionModal | 23172 | decl | — | Ferme la modale d'imposition | Closes the imposition configuration modal | ||
| 16 | closeManualModal | 23202 | decl | — | Ferme la modale d'imposition manuelle | Closes the manual imposition modal |
3.2 Canvas / Fabric.js Core 3.2 Canvas / Fabric.js Core 25
| # | Fonction | Function | Ligne | Type | Params | Description FR | Description EN |
|---|---|---|---|---|---|---|---|
| 1 | setupCanvasEvents | 7862 | decl | canvas, index | Attache tous les gestionnaires d'événements Fabric à un canvas | Attaches all Fabric event handlers to a canvas | |
| 2 | setupCrossBlockDragSelection | 9896 | IIFE | — | Active la sélection de texte par glissement cross-textbox | Enables cross-textbox text drag selection | |
| 3 | renderVerticalHandle | 2214 | decl | ctx, left, top, styleOverride, fabricObject | Rend une poignée de redimensionnement verticale | Renders a vertical resize control | |
| 4 | renderHorizontalHandle | 2239 | decl | ctx, left, top, styleOverride, fabricObject | Rend une poignée de redimensionnement horizontale | Renders a horizontal resize control | |
| 5 | renderCornerHandle | 2263 | decl | ctx, left, top, styleOverride, fabricObject | Rend une poignée de coin | Renders a corner resize control | |
| 6 | getCanvasPoint | 2287 | decl | canvas, eventData | Convertit un événement souris/touch en coordonnées canvas | Converts mouse/touch event to canvas coordinates | |
| 7 | createTextboxControls | 2821 | decl | — | Crée les contrôles de redimensionnement personnalisés des Textbox | Creates custom Fabric textbox resize controls | |
| 8 | actionHandlerML/MR/MT/MB | 1301–1450 | decl | eventData, transformData, x, y | Gestionnaires de redimensionnement par poignée (gauche, droite, haut, bas) | Resize handle action handlers (left, right, top, bottom) | |
| 9 | createCornerHandler | 2737 | decl | cornerType | Fabrique de gestionnaires de coin | Factory for corner resize handlers | |
| 10 | commonMouseUpHandler | 2767 | decl | eventData, transformData | Gestionnaire commun après toute transformation | Common handler after any transform completes | |
| 11 | getObjectBounds | 2411 | decl | obj | Retourne le bounding box d'un objet Fabric | Returns bounding box of a Fabric object | |
| 12 | setObjectFromBounds | 2470 | decl | obj, bounds | Positionne/dimensionne un objet depuis un bounding box | Sets object position/size from bounding box | |
| 13 | optimizedRender | 6694 | decl | canvas, delay=0 | Rendu canvas avec debounce/pooling | Debounced/pooled canvas render | |
| 14 | serializeObject | 11114 | decl | obj | Sérialise un objet Fabric en JSON | Serializes a single Fabric object to JSON | |
| 15 | onCanvasLoaded | 13842 | decl | — | Initialisation post-chargement du canvas | Post-load canvas initialization | |
| 16 | _postLoadCanvas | 13858 | decl | fabricCanvas, isSpread | Traitement des objets après chargement JSON | Processes objects after canvas JSON load | |
| 17 | spApplySmartControls | 3017 | window | textbox | Applique les contrôles de redimensionnement précis à une Textbox | Applies precise resize controls to a textbox | |
| 18 | deepCleanupCanvas | 7146 | decl | fabricCanvas | Nettoyage profond du canvas (GPU, mémoire, listeners) | Deep cleanup of canvas GPU/memory |
3.3 Zoom 6
| # | Function | Line | Type | Params | Description FR | Description EN |
|---|---|---|---|---|---|---|
| 1 | applyZoom | 26042 | decl | — | Applique le niveau de zoom via CSS transform + MàJ DPR | Applies zoom level via CSS transform + DPR update |
| 2 | setInitialZoom | 26144 | decl | — | Calcule et applique le zoom initial adapté au viewport | Calculates and sets zoom to fit viewport |
| 3 | normalizeZoomLevel | 26036 | decl | — | Clamp le zoom dans la plage valide | Clamps zoom to valid min/max range |
| 4 | _updateCanvasDPRForZoom | 25981 | decl | — | Ajuste le DPR des canvas selon le zoom pour un texte net | Adjusts canvas DPR based on zoom for sharp text |
| 5 | handleWheelZoom | 26495 | arrow | event | Gestionnaire zoom molette (Ctrl+scroll) | Mouse wheel zoom handler (Ctrl+scroll) |
| 6 | handleZoomShortcut | 23293 | decl | e | Raccourcis clavier de zoom (Ctrl+/Ctrl-) | Keyboard zoom shortcuts (Ctrl+/Ctrl-) |
3.4 Historique / Undo-Redo 3.4 History / Undo-Redo 11
| # | Function | Line | Type | Params | Description FR | Description EN |
|---|---|---|---|---|---|---|
| 1 | saveState | 13559 | decl | action | Sauvegarde l'état courant dans l'historique d'annulation | Saves current state to undo history |
| 2 | saveStateFromPages | 13621 | decl | action | Sauvegarde l'état directement depuis le tableau pages | Saves state from pages array directly |
| 3 | undo | 13655 | decl | — | Annule la dernière action | Undo last action |
| 4 | redo | 13665 | decl | — | Rétablit la dernière action annulée | Redo last undone action |
| 5 | restoreState | 13683 | decl | state | Restaure un état sauvegardé | Restores a saved history state |
| 6 | _doRestoreState | 13719 | decl | state | Logique interne de restauration d'état | Internal state restoration logic |
| 7 | _fastRestoreCanvases | 13808 | decl | — | Restauration rapide des canvas sans re-rendu complet | Fast canvas restoration without full re-render |
| 8 | updateHistoryPanel | 14017 | decl | — | Met à jour le panneau UI d'historique | Updates the undo/redo history UI panel |
| 9 | debouncedSaveState | 1477 | decl | action | Sauvegarde d'état avec debounce (évite les sauvegardes rapides) | Debounced state save (avoids rapid saves) |
| 10 | _spRestoreSaveHistory | 7039 | decl | — | Restaure l'historique de sauvegarde depuis IndexedDB | Restores save history from IndexedDB |
| 11 | _spRestoreSaveHistoryFallback | 7091 | decl | — | Restauration de secours en cas d'erreur | Fallback history restoration on error |
3.5 Texte / Typographie 3.5 Text / Typography 48
| # | Function | Line | Type | Params | Description FR | Description EN |
|---|---|---|---|---|---|---|
| 1 | forceTextRecalc | 2294 | decl | target | Force le recalcul de la mise en page du texte | Forces text layout recalculation |
| 2 | spLockTextboxDimensions | 2346 | decl | textObj | Verrouille les dimensions d'une textbox | Locks textbox width/height to prevent resize |
| 3 | spGraphemeSplit | 3165 | decl | str | Découpe une chaîne par clusters de graphèmes | Splits string by grapheme clusters |
| 4 | getFontDecl | 3174 | decl | obj | Retourne la déclaration CSS de police | Gets CSS font declaration string |
| 5 | getMaxFontSizeFromStyles | 3185 | decl | obj | Retourne la taille de police max depuis les styles inline | Gets max font size from inline styles |
| 6 | measureRawWithFont | 3308 | decl | obj, text, fontSize, fontWeight, fontFamily | Mesure la largeur du texte avec une police explicite | Measures text width with explicit font params |
| 7 | fallbackHyphenate | 3472 | decl | word | Césure basique par syllabes (fallback) | Basic syllable-based hyphenation fallback |
| 8 | spForceInlineStyleRewrap | 5521 | decl | textbox | Force le ré-enveloppement avec styles inline | Forces rewrap respecting inline styles |
| 9 | spForceTextboxRewrap | 5633 | decl | textbox | Force un ré-enveloppement complet de la textbox | Forces complete textbox rewrap |
| 10 | addSpecialTextObjectsToCanvas | 5849 | decl | fabricCanvas, pageIndex, position | Ajoute les numéros de page automatiques | Adds auto page numbers to canvas |
| 11 | restoreTextboxAfterLoad | 6276 | decl | obj | Restaure les propriétés SP d'une textbox après chargement JSON | Restores textbox SP properties after JSON load |
| 12 | applyTextboxClipPath | 6361 | decl | textbox | Applique un clip path pour masquer le débordement | Applies clip path to hide overflow |
| 13 | applyTextStyleToSelection | 47828 | decl | style, value | Applique un style de texte à la sélection | Applies a text style to current selection |
| 14 | toggleButton | 47892 | decl | style | Bascule gras/italique/souligné | Toggles bold/italic/underline |
| 15 | applyHyphenation | 29205 | decl | mode | Définit le mode de césure (auto/manuel/aucun) | Sets hyphenation mode (auto/manual/none) |
| 16 | toggleScript | 29500 | decl | type | Bascule exposant/indice | Toggles superscript/subscript |
| 17 | transformCase | 29524 | decl | mode | Transforme la casse (MAJ/min/Titre) | Transforms text case (upper/lower/title) |
| 18 | addText | 16172 | decl | — | Active l'outil de création de texte (dessiner-pour-créer) | Activates text creation tool (draw-to-create) |
| 19 | createSimpleTextBox | 16409 | decl | canvas, left, top, width, height | Crée une zone de texte à la position/taille donnée | Creates a text box at given position/size |
| 20 | applyFixedHeightProtection | 16368 | decl | textbox | Empêche la textbox de grandir automatiquement en hauteur | Prevents textbox from auto-growing height |
| 21 | applyCrossBlockStyle | 21918 | decl | styleProps | Applique un style à la sélection cross-block | Applies style to cross-block text selection |
| 22 | ensureCrispText | 17578 | decl | tb | Assure un rendu texte net au sous-pixel | Ensures crisp subpixel text rendering |
| 23 | softHyphenateWord | 30732 | decl | word | Insère des césures optionnelles dans un mot | Soft-hyphenates a single word |
| 24 | forceFontRefresh | 25010 | decl | obj, canvas | Force le rechargement de la police d'un objet | Forces font refresh for an object |
3.6 Système de chaînage de texte 3.6 Text Chaining System 60+
| # | Function | Line | Type | Params | Description FR | Description EN |
|---|---|---|---|---|---|---|
| 1 | checkTextOverflow | 16818 | decl | canvas | Vérifie le débordement de toutes les textbox du canvas | Checks all textboxes on canvas for overflow |
| 2 | updateOverflowIndicator | 16957 | decl | textbox, canvas | Affiche/masque l'indicateur de débordement | Shows/hides overflow indicator on textbox |
| 3 | propagateBaseStyleToChain | 17087 | decl | obj, styleProps | Propage le style de base à toute la chaîne | Propagates base style to all chain blocks |
| 4 | cleanupChainOnBlockDelete | 17162 | decl | obj | Nettoie les liens de chaîne lors de la suppression d'un bloc | Cleans chain links when a block is deleted |
| 5 | _redistributeWithStyles | 17332 | decl | chain, fullText, allStyles | Redistribue le texte+styles à travers la chaîne | Redistributes text+styles across chain |
| 6 | redistributeLinkedTextChain | 17448 | decl | obj | Redistribue le texte dans tous les blocs liés | Reflows text across all linked blocks |
| 7 | getFittingTextIndex | 17591 | decl | textbox, fullText | Trouve combien de texte tient dans une textbox | Finds how much text fits in a textbox |
| 8 | flowTailAcrossPages | 17763 | async | tailText, sourceObj, sourceCanvas, pageIndex | Distribue le texte excédentaire sur les pages suivantes | Flows overflow text to new pages |
| 9 | autoFlowTextToNextPage | 17838 | decl | textObj, canvas, pageIndex | Auto-flow du débordement vers la page suivante | Auto-flows overflow to next page |
| 10 | createLinkedTextBlock | 17863 | decl | sourceObj, sourceCanvas, targetCanvas, targetPageIdx | Crée un nouveau bloc lié sur la page cible | Creates a new linked block on target page |
| 11 | findFirstBlockInChain | 21132 | decl | textObj | Remonte au premier bloc d'une chaîne | Walks backward to first block in chain |
| 12 | buildLinkedChain | 21187 | decl | firstBlock | Construit le tableau ordonné de tous les blocs d'une chaîne | Builds ordered array of all chain blocks |
| 13 | findBlockById | 21219 | decl | textLinkId | Trouve une textbox par son textLinkId | Finds a textbox by its textLinkId |
| 14 | addOrUpdateChainBadge | 21231 | decl | tb, color | Ajoute/met à jour le badge d'index de chaîne | Adds/updates chain index badge on textbox |
| 15 | updateLinkArrowsForChain | 21295 | decl | startObj | Redessine les flèches de liaison pour toute la chaîne | Redraws link arrows for entire chain |
| 16 | drawCrossBlockHighlight | 21569 | decl | tb, fromChar, toChar | Dessine la surbrillance sur une plage de texte cross-bloc | Draws highlight overlay on a block range |
| 17 | getCrossBlockSelectedText | 21798 | decl | — | Retourne le texte sélectionné à travers les blocs | Returns selected text across blocks |
| 18 | breakTextLink | 22167 | decl | — | Rompt un lien entre deux blocs connectés | Breaks a link between two connected blocks |
| 19 | autoLinkTextBlocks | 22359 | decl | — | Lie automatiquement les textbox sélectionnées dans l'ordre | Auto-links selected textboxes in order |
| 20 | createThreeColumnLinkedText | 22671 | decl | — | Crée une mise en page à 3 colonnes liées | Creates a 3-column linked text layout |
3.7 Import / Export 3.7 Import / Export 35
| # | Function | Line | Type | Params | Description FR | Description EN |
|---|---|---|---|---|---|---|
| 1 | importSVG | 15406 | decl | — | Importe un fichier SVG via sélecteur de fichier | Imports SVG file via file picker |
| 2 | flowHtmlIntoPages | 30600 | async | html, startPageIndex | Importe du contenu HTML dans les pages | Imports HTML content into pages |
| 3 | importWordDocument | 70173 | async | file, startPageIndex | Importe un document Word .docx | Imports Word .docx document |
| 4 | extractOdtHtml | 31080 | decl | arrayBuffer | Extrait le HTML d'un fichier ODT | Extracts HTML from ODT file |
| 5 | importScribusFile | 31546 | decl | xmlStr | Importe un fichier .sla (format PAO XML open source) | Imports a .sla file (open-source DTP XML format) |
| 6 | processIdmlZip | 31949 | async | file | Traite un fichier IDML (archive ZIP) | Processes an IDML file (ZIP archive) |
| 7 | parseIdmlAndBuild | 32193 | async | zip, fontsMap, imagesMap | Parse la structure IDML et construit les pages | Parses IDML structure and builds pages |
| 8 | importPDFPages | 70277 | async | pageNumbers, recadrageMode | Importe des pages PDF sélectionnées | Imports selected pages from a PDF |
| 9 | showPDFImportModal | 69788 | async | file | Affiche la modale d'import PDF avec aperçus | Shows the PDF import dialog with previews |
| 10 | renderPageToImageWithBleed | 42741 | async | pageIndex, position, quality, bleed, ... | Rend une page en image pour l'export (avec fond perdu) | Renders a page to image for export (with bleed) |
| 11 | confirmExport | 37208 | async | — | Confirme et exécute l'export PDF | Confirms and executes standard PDF export |
| 12 | exportImposedPDF | 38846 | async | — | Exporte un PDF imposé (cahier/livret) | Exports imposed/booklet PDF |
| 13 | confirmD4Export | 36741 | async | — | Export D4/Print-to-Web (mini-site HTML en ZIP) | D4/Print-to-Web export (HTML mini-site in ZIP) |
| 14 | saveProjectLocal | 77028 | window | — | Sauvegarde le projet en JSON local | Saves project to local JSON file |
| 15 | saveProjectWeb3 | 77086 | async | — | Sauvegarde le projet sur Web3/IPFS | Saves project to Web3/IPFS |
| 16 | saveProjectSP | 77319 | window | — | Sauvegarde au format .sp (JSON) | Saves project in .sp format (JSON) |
| 17 | loadProjectSP | 77522 | window | fileContent | Charge un fichier projet .sp | Loads a .sp project file |
3.8 Interface / Panneaux 3.8 UI / Panels 35
| # | Function | Line | Type | Params | Description FR | Description EN |
|---|---|---|---|---|---|---|
| 1 | toggleSidebar | 314 | decl | side | Bascule la barre latérale gauche/droite | Toggles left/right sidebar collapse |
| 2 | showPageLoader | 1522 | decl | message | Affiche l'overlay de chargement | Shows loading overlay with message |
| 3 | hidePageLoader | 1545 | decl | — | Masque l'overlay de chargement | Hides loading overlay |
| 4 | updateLayersPanel | 20774 | decl | — | Met à jour le panneau couches/objets | Updates the layers/objects panel UI |
| 5 | updateTransformPanel | 14068 | decl | — | Met à jour le panneau de propriétés de transformation | Updates the transform properties panel |
| 6 | applyTransform | 14503 | decl | — | Applique les valeurs de transformation depuis les inputs | Applies transform values from panel inputs |
| 7 | applyColors | 14595 | decl | — | Applique les couleurs fond/contour depuis le panneau | Applies fill/stroke colors from panel |
| 8 | rgbToCMYK | 26951 | decl | hex | Convertit une couleur hex RGB en valeurs CMYK | Converts hex RGB to CMYK values |
| 9 | setupShapesDropdown | 14891 | decl | — | Initialise le menu déroulant des formes | Initializes shapes dropdown menu |
| 10 | setupImportDropdown | 15007 | decl | — | Initialise le menu déroulant d'import | Initializes import dropdown menu |
| 11 | initNumberSpinners | 895 | decl | root | Initialise les inputs numériques avec boutons +/- | Initializes numeric spinner inputs |
| 12 | showTooltipAt | 18668 | decl | x, y, text | Affiche un tooltip à une position écran | Shows tooltip at screen position |
| 13 | enablePerformanceMode | 25006 | decl | enabled | Active/désactive le mode haute performance | Toggle performance mode UI |
3.9 Pages maîtresses 3.9 Master Pages 3
| # | Function | Line | Type | Params | Description FR | Description EN |
|---|---|---|---|---|---|---|
| 1 | applyMasterToPage | 46918 | decl | pageIndex, masterId | Applique un gabarit à une page | Applies a master page template to a page |
| 2 | openMasterEditor | 46988 | decl | masterId | Ouvre l'éditeur de page maîtresse | Opens the master page editor |
| 3 | closeMasterEditor | 47103 | decl | — | Ferme l'éditeur de page maîtresse | Closes the master page editor |
3.10 Mode planche (Spread) 3.10 Spread Mode 22
| # | Function | Line | Type | Params | Description FR | Description EN |
|---|---|---|---|---|---|---|
| 1 | createSpreadCanvas | 11336 | decl | container, leftIdx, rightIdx, w, h | Crée un canvas double-page (planche) | Creates a double-page spread canvas |
| 2 | loadSpreadContent | 11553 | decl | fabricCanvas, leftIdx, rightIdx | Charge le contenu des pages dans la planche | Loads page content into spread |
| 3 | setupSpreadEventHandlers | 11700 | decl | fabricCanvas, leftIdx, rightIdx | Attache les gestionnaires d'événements spécifiques au spread | Attaches spread-specific event handlers |
| 4 | saveSpreadContent | 11951 | decl | fabricCanvas, leftIdx, rightIdx | Sauvegarde le contenu du spread dans le tableau pages | Saves spread content back to pages array |
| 5 | addSpreadGuides | 12192 | decl | fabricCanvas, w, h, bleedPx, forceRecreate | Ajoute les repères de marge/gouttière au spread | Adds margin/gutter guides to spread |
| 6 | convertSpreadToSingle | 12465 | decl | — | Convertit la vue planche en pages simples | Converts spread view back to single pages |
| 7 | handleSpreadPageOverflow | 12551 | decl | canvas, pageIdx, obj | Gère le débordement d'objets au-delà de la limite du spread | Handles object crossing spread boundary |
| 8 | createSpreadMirrorObject | 12688 | decl | sourceObj, sourceCanvas, ... | Crée un miroir d'objet sur la page adjacente | Creates mirror of object on adjacent page |
| 9 | syncMirrorWithSource | 13066 | decl | sourceObj | Synchronise l'objet miroir avec sa source | Syncs mirror object with its source |
| 10 | checkAllObjectsForSpreadOverflow | 13209 | decl | — | Re-vérifie tous les objets pour le débordement de spread | Re-checks all objects for spread overflow |
3.11 Outils (Dessin, Formes, Images, Masques, Recadrage, Booléens) 3.11 Tools (Drawing, Shapes, Images, Masks, Crop, Booleans) 80+
Dessin & Outil plume
Drawing & Pen Tool
| # | Function | Line | Params | Description FR | Description EN |
|---|---|---|---|---|---|
| 1 | activateFreeformDrawing | 15321 | — | Active le mode dessin libre (pinceau) | Activates freeform brush drawing mode |
| 2 | activatePenTool | 15426 | — | Active l'outil plume Bézier | Activates the Bézier pen tool |
| 3 | penMouseDown / penMouseMove / penMouseUp | 10365–10500 | e | Gestionnaires souris de l'outil plume | Pen tool mouse handlers |
| 4 | buildSVGPath | 15787 | points, closePath | Construit une chaîne SVG path à partir de points | Builds SVG path string from points |
| 5 | finalizePenPath | 15834 | closePath | Finalise le tracé plume en objet Fabric | Finalizes pen path into Fabric object |
| 6 | editExistingPenPath | 15912 | pathObject | Entre en mode édition d'un tracé existant | Enters edit mode for existing path |
Formes
Shapes
| # | Function | Line | Params | Description FR | Description EN |
|---|---|---|---|---|---|
| 1 | addRect | 14759 | — | Ajoute un rectangle | Adds a rectangle |
| 2 | addCircle | 14793 | — | Ajoute un cercle/ellipse | Adds a circle/ellipse |
| 3 | addStar | 14837 | — | Ajoute une étoile | Adds a star shape |
Images & Masquage
Images & Masking
| # | Function | Line | Params | Description FR | Description EN |
|---|---|---|---|---|---|
| 1 | addImage | 18054 | — | Ouvre le sélecteur de fichier pour ajouter une image | Opens file picker to add an image |
| 2 | importImageIntoShape | 17968 | shapePath, canvas | Importe une image dans un masque de forme | Imports image into a shape mask |
| 3 | applyImageMaskToShape | 18987 | shapeObj, imageObj, canvas, url | Applique une image comme remplissage masqué | Applies image as fill to shape mask |
| 4 | fitImageToShape | 19328 | shapeObj, canvas, mode, options | Adapte l'image à la forme (cover/contain) | Fits image to shape (cover/contain) |
| 5 | openCropModal | 19795 | imageObjOverride | Ouvre la modale de recadrage | Opens the crop modal |
| 6 | applyCrop | 20555 | — | Applique le recadrage en cours | Applies current crop to image |
| 7 | replaceImageForObject | 18452 | imageObj, opts | Remplace la source d'image d'un objet | Replaces image source for an object |
| 8 | restoreImageMasksAfterLoad | 18698 | canvas | Restaure les masques d'image après chargement JSON | Restores image masks after JSON load |
Opérations booléennes (Pathfinder)
Boolean Operations (Pathfinder)
| # | Function | Line | Params | Description FR | Description EN |
|---|---|---|---|---|---|
| 1 | uniteShapes | 70676 | objects | Union booléenne de formes | Boolean unite (union) of shapes |
| 2 | subtractShapes | 70680 | objects | Soustraction booléenne | Boolean subtract of shapes |
| 3 | intersectShapes | 70684 | objects | Intersection booléenne | Boolean intersect of shapes |
| 4 | excludeShapes | 70688 | objects | Exclusion booléenne (XOR) | Boolean exclude (XOR) of shapes |
| 5 | applyPathfinderOperation | 70365 | operation | Applique l'opération Pathfinder sélectionnée | Applies selected pathfinder boolean op |
Épreuvage écran (Soft Proofing)
Soft Proofing
| # | Function | Line | Params | Description FR | Description EN |
|---|---|---|---|---|---|
| 1 | applySoftProof | 15246 | proof | Applique un profil ICC d'épreuvage aux canvas | Applies ICC soft proof to canvases |
| 2 | updateActiveSoftProof | 15283 | — | Met à jour le profil d'épreuvage actif | Updates which soft proof is active |
3.12 Sélection / Alignement 3.12 Selection / Alignment 8
| # | Function | Line | Params | Description FR | Description EN |
|---|---|---|---|---|---|
| 1 | alignSelectedObjects | 48405 | direction | Aligne plusieurs objets sélectionnés | Aligns multiple selected objects |
| 2 | alignObject | 20714 | align | Aligne un objet sur le plan de travail | Aligns single object on artboard |
| 3 | centerObjectOnArtboard | 60557 | axis | Centre l'objet sur le plan de travail (H/V/les deux) | Centers object on artboard (H/V/both) |
| 4 | altDuplicateSingle | 10266 | canvas, target | Duplication Alt+glisser (objet unique) | Alt+drag duplicate single object |
| 5 | handleCrossPageDrag | 10475 | e, sourceCanvas | Gère le glisser d'objets entre pages | Handles drag of object across page boundaries |
| 6 | moveObjectToPage | 10991 | obj, sourceCanvas, sourceIdx, targetIdx | Déplace un objet vers une autre page | Moves object to another page |
3.13 i18n / Localization 5
| # | Function | Line | Params | Description FR | Description EN |
|---|---|---|---|---|---|
| 1 | _t | 56815 | sel, key | Traduit le contenu texte d'un élément | Translates text content of element |
| 2 | _tt | 56820 | sel, key | Traduit le tooltip d'un élément | Translates tooltip of element |
| 3 | _th | 56825 | sel, key | Traduit le innerHTML d'un élément | Translates innerHTML of element |
| 4 | _npUpdateLabels | 56975 | — | Met à jour les labels de la modale Nouveau projet | Updates new project modal labels |
| 5 | filterAssetsByLang | 63002 | lang | Filtre les assets par langue | Filters assets panel by language |
3.14 IndexedDB / Stockage 3.14 IndexedDB / Storage 21
| # | Function | Line | Params | Description FR | Description EN |
|---|---|---|---|---|---|
| 1 | openDB | 71142 | — | Ouvre/crée la base IndexedDB (SuperPrintDB V2) | Opens/creates IndexedDB database |
| 2 | autoSaveProject | 71162 | — | Sauvegarde automatique dans IndexedDB | Auto-saves project to IndexedDB |
| 3 | loadAutoSavedProject | 71253 | — | Charge le projet auto-sauvegardé | Loads auto-saved project from IndexedDB |
| 4 | clearAutoSave | 71271 | — | Supprime la sauvegarde automatique | Clears auto-save data |
| 5 | pushSaveHistory | 71307 | type | Ajoute une entrée dans l'historique de sauvegarde | Pushes save entry to history |
| 6 | saveSessionHistory | 71406 | — | Sauvegarde l'historique undo/redo de session | Saves undo/redo session history |
| 7 | loadSessionHistory | 71469 | — | Charge l'historique undo/redo de session | Loads undo/redo session history |
| 8 | startAutoSave | 71487 | — | Démarre le timer de sauvegarde automatique | Starts auto-save interval timer |
| 9 | uploadToIPFS | 70824 | apiKey, jsonData | Upload le projet sur IPFS via Pinata | Uploads project to IPFS via Pinata |
| 10 | loadWeb3Save | 70851 | hash | Charge un projet depuis IPFS par hash | Loads project from IPFS by hash |
3.15 Nouveau projet 3.15 New Project 12
| # | Function | Line | Params | Description FR | Description EN |
|---|---|---|---|---|---|
| 1 | newProject | 71552 | — | Propose de sauvegarder puis lance un nouveau projet | Prompts to save then starts new project |
| 2 | openNewProjectModal | 71567 | — | Ouvre la modale de nouveau projet | Opens the new project modal |
| 3 | createNewProjectFromModal | 76541 | — | Crée le projet avec les paramètres de la modale | Creates project with modal settings |
| 4 | npSelectFormat | 76485 | btn | Sélectionne un format de page prédéfini | Selects a page format preset |
| 5 | npUpdatePreview | 76504 | — | Met à jour l'aperçu de format | Updates the format preview thumbnail |
| 6 | npSetViewMode | 76534 | mode | Définit le mode de vue (simple/planche) | Sets view mode (single/spread) |
3.16 Performance / Cleanup 11
| # | Function | Line | Params | Description FR | Description EN |
|---|---|---|---|---|---|
| 1 | enableHighPerformance | 6796 | — | Active le mode rendu haute performance | Enables high-performance rendering mode |
| 2 | deepCleanupCanvas | 7146 | fabricCanvas | Nettoyage profond du canvas (GPU/mémoire/listeners) | Deep cleanup of canvas GPU/memory/listeners |
| 3 | preloadFonts | 6815 | — | Précharge toutes les polices disponibles | Preloads all available fonts |
| 4 | optimizeForTypography | 6864 | — | Désactive temporairement les animations pour les opérations texte | Temporarily disables animations for text ops |
| 5 | _spReleaseMemoryPressure | 581 | aggressive | Libère la pression mémoire GPU/RAM | Releases GPU/memory pressure |
| 6 | init | 6883 | — | Initialisation principale de l'application | Main application initialization |
3.17 Utilitaires 3.17 Utilities 27
| # | Function | Line | Params | Description FR | Description EN |
|---|---|---|---|---|---|
| 1 | mmToPx | 6706 | mm | Conversion millimètres → pixels (72 DPI) | Millimeters to pixels (72 DPI) |
| 2 | pxToMm | 6707 | px | Conversion pixels → millimètres | Pixels to millimeters |
| 3 | pxToCm / cmToPx | 3284–3303 | val | Conversion pixels ↔ centimètres | Pixels ↔ centimeters conversion |
| 4 | inToPx / pxToIn | 3304–3305 | val | Conversion pixels ↔ pouces | Pixels ↔ inches conversion |
| 5 | getPxToUnitFn | 6757 | — | Retourne la fonction de conversion pour l'unité en cours | Returns conversion fn for current unit |
| 6 | getPageCenter | 1579 | canvas | Retourne le centre de la page active | Gets center point of active page |
| 7 | toNumber | 52861 | v, defVal | Convertit en nombre avec fallback | Converts value to number with fallback |
| 8 | clamp | 52865 | n, min, max | Borne un nombre dans un intervalle | Clamps number to range |
| 9 | sanitizeColor | 52867 | c, def | Assainit une chaîne couleur | Sanitizes color string |
| 10 | setupEventListeners | 25210 | — | Configuration maître de tous les écouteurs clavier/souris | Master keyboard/mouse event listener setup |
| 11 | startSystemMonitoring | 515 | — | Démarre le monitoring des ressources système | Starts system resource monitoring |
3.18 Grilles / Repères 3.18 Grids / Guides 9
| # | Function | Line | Params | Description FR | Description EN |
|---|---|---|---|---|---|
| 1 | setSnapToGuidesEnabled | 33538 | next | Active/désactive l'aimantation aux repères | Toggles snap-to-guides |
| 2 | getGridSettings | 33551 | — | Retourne les paramètres de grille actuels | Returns current grid settings |
| 3 | buildLayoutGridForArea | 33604 | canvas, area, settings | Construit la grille de colonnes/rangées | Builds column/row layout grid |
| 4 | buildBaselineGridForArea | 33645 | canvas, area, settings | Construit la grille de ligne de base typographique | Builds typographic baseline grid |
| 5 | applyGridToCanvas | 33663 | canvas, settings | Applique les paramètres de grille à un canvas | Applies grid settings to a canvas |
| 6 | rebuildGridAll | 33725 | — | Reconstruit la grille sur toutes les pages | Rebuilds grid on all pages |
3.19 Caractères spéciaux / Glyphes 3.19 Special Characters / Glyphs 8
| # | Function | Line | Params | Description FR | Description EN |
|---|---|---|---|---|---|
| 1 | spInsertSpecialChar | 59488 | charToInsert | Insère un caractère spécial au curseur | Inserts a special character at cursor |
| 2 | openGlyphsModal | 59603 | — | Ouvre la modale de glyphes/caractères spéciaux | Opens the glyphs/special chars modal |
| 3 | populateGlyphsGrid | 59659 | — | Remplit la grille de glyphes pour la police active | Populates the glyph grid for current font |
| 4 | glyphsInsertChar | 59762 | — | Insère le glyphe sélectionné dans le texte | Inserts selected glyph into text |
3.21 Mobile Helpers 12
| # | Function | Line | Params | Description FR | Description EN |
|---|---|---|---|---|---|
| 1 | initMobileBurgerMenu | 78617 | — | Initialise le menu hamburger mobile | Initializes mobile hamburger menu |
| 2 | initMobileTouchContextMenu | 78738 | — | Initialise le menu contextuel tactile | Initializes mobile touch context menu |
| 3 | spMobileSelectAll | ~42479 | — | Tout sélectionner (mobile) | Select all objects (mobile) |
| 4 | spMobileCopy / Paste / Delete | ~42501–42583 | — | Copier / Coller / Supprimer (mobile) | Copy / Paste / Delete (mobile) |
3.22 ⚡ GPU Acceleration 3
| # | Fonction | Function | Ligne | Line | Type | Type | Paramètres | Parameters | Description | Description |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | detectGPU | ~953 | decl | — | Interroge WebGL (WEBGL_debug_renderer_info) et retourne {supported, vendor, renderer, name}. Libère le contexte via WEBGL_lose_context. | Queries WebGL (WEBGL_debug_renderer_info) and returns {supported, vendor, renderer, name}. Frees context via WEBGL_lose_context. | ||||
| 2 | applyGpuAcceleration | ~988 | decl | enabled (bool) | Active/désactive la promotion de couche CSS (will-change, translateZ) sur tous les canvas et bascule objectCaching Fabric.js par type d'objet. Persiste en localStorage et déclenche un re-rendu immédiat. | Enables/disables CSS layer promotion (will-change, translateZ) on all canvases and toggles Fabric.js objectCaching per object type. Persists to localStorage and triggers an immediate re-render. | ||||
| 3 | initOnboarding | ~42538 | IIFE | — | Wizard de premier lancement (4 étapes). Gardé par sp_onboarding_done. L'étape GPU appelle detectGPU() et connecte applyGpuAcceleration() en direct sur la case à cocher. | First-launch wizard (4 steps). Guarded by sp_onboarding_done. The GPU step calls detectGPU() and wires applyGpuAcceleration() live to the checkbox. | ||||
Partie 2 — Patches Fabric.js Part 2 — Fabric.js Prototype Patches 19
| # | Méthode prototype | Prototype Method | Ligne | Description FR | Description EN |
|---|---|---|---|---|---|
| 1 | fabric.Text.prototype._spDrawInvisibleMarkers | 879 | Dessine les marqueurs de caractères invisibles (espaces, tabs, retours) | Draws invisible character markers (spaces, tabs, returns) | |
| 2 | fabric.Text.prototype._renderText | 917 | Rendu texte overridé avec support des invisibles | Overridden text render with invisibles support | |
| 3 | fabric.Canvas.prototype.renderTop | 938 | Rendu de la couche supérieure (curseur, sélection) | Overridden top-layer render | |
| 4 | fabric.Object.prototype.drawControls | 962 | Dessin des contrôles personnalisés | Custom control drawing (precise handles) | |
| 5 | fabric.IText.prototype._renderSelection | 1791 | Rendu personnalisé de la sélection texte | Custom text selection rendering | |
| 6 | fabric.Textbox.prototype.toObject | 1860 | Sérialisation personnalisée avec SP_CUSTOM_PROPS | Custom serialization with SP_CUSTOM_PROPS | |
| 7 | fabric.Textbox.prototype.initDimensions | 2110 | Init des dimensions avec support styles inline | Dimension init with inline style support | |
| 8 | fabric.Textbox.prototype._splitTextIntoLines | 2125 | Découpage en lignes overridé | Line splitting override | |
| 9 | fabric.Textbox.prototype.enlargeSpaces | 2195 | Justification avancée des espaces (word/letter spacing, glyph scaling) | Advanced space justification (word/letter spacing, glyph scaling) | |
| 10 | fabric.Textbox.prototype._renderTextLine | 2316 | Rendu par ligne avec tracking et justification | Per-line rendering with tracking and justification | |
| 11 | fabric.Textbox.prototype._wrapLine | 2409 | Enveloppement de ligne avec césure (5 langues) | Line wrapping with hyphenation (5 languages) | |
| 12 | fabric.IText.prototype.renderCursor | 2702 | Rendu du curseur personnalisé | Custom cursor rendering | |
| 13 | fabric.Image.prototype.toObject | 3293 | Sérialisation d'image avec propriétés SP | Custom image serialization with SP props | |
| 14 | fabric.IText.prototype.setSelectionStyles | 42094 | Override des styles de sélection | Selection styles override | |
| 15 | fabric.Textbox.prototype.set | 42109 | set() patché pour ré-enveloppement intelligent | Patched set() for smart rewrap | |
| 16 | fabric.Textbox.prototype.initialize | 42152 | initialize() patché avec défauts SP | Patched initialize with SP defaults |
Variables globales & Constantes Global Variables & Constants
État du document (Lignes 664–740)
Document State (Lines 664–740)
| Variable | Type | Défaut | Default | Description FR | Description EN |
|---|---|---|---|---|---|
canvases | Array | [] | Tableau de toutes les instances Fabric.Canvas | Array of all Fabric.js canvas instances | |
pages | Array | [] | Tableau des données de pages sérialisées (JSON) | Array of serialized page data (JSON) | |
currentPageIndex | Number | 0 | Index de la page actuellement active | Index of the currently active page | |
pageFormat | Object | {width:210, height:297} | Dimensions de la page en mm | Page dimensions in mm | |
margin | Number | 20 | Marge de la page en mm | Page margin in mm | |
bleed | Number | 3 | Zone de fond perdu en mm | Bleed area in mm | |
history | Array | [] | Pile d'historique undo/redo | Undo/redo state history stack | |
historyStep | Number | -1 | Position courante dans l'historique | Current position in history | |
viewMode | String | 'single' | Mode de vue : 'single' ou 'spread' | View mode: 'single' or 'spread' | |
textLinks | Object | {} | Carte des connexions de chaînage texte | Map of text link connections | |
masterPages | Object | {} | Gabarits de pages maîtresses {id: {name, objects}} | Master page templates {id: {name, objects}} | |
pageMasterAssignments | Object | {} | Assignations page→gabarit {pageIdx: masterId} | Page-to-master assignments {pageIdx: masterId} |
Constantes
Constants
| Constante | Ligne | Valeur / Description | Value / Description |
|---|---|---|---|
DEBUG_MODE | 678 | false — Active le logging console | false — Enables console logging |
ENABLE_LINKED_TEXT | 681 | true — Active le chaînage de texte style PAO pro | true — Enables professional DTP-style text chaining |
PASTEBOARD_PX | 804 | Calculé — Taille du table de montage horizontal (réduit en mode planche) | Computed — Horizontal pasteboard size (reduced in spread mode) |
PASTEBOARD_V_PX | 805 | 200 — Taille du table de montage vertical en px | 200 — Vertical pasteboard size in px |
SP_CUSTOM_PROPS | 688 | 20+ propriétés personnalisées sauvegardées avec chaque objet Fabric | 20+ custom properties saved with each Fabric object |
Fonctionnalités Features
📄 Document
- Formats A4, A5, Letter, personnalisé
- A4, A5, Letter, Custom formats
- Dimensions, marges, fond perdu personnalisés (mm)
- Custom dimensions, margins, bleed (mm)
- Modes page simple + planche (spread)
- Single page + Spread view modes
- Table de montage (pasteboard)
- Pasteboard (work area around pages)
- Réorganisation drag-and-drop des pages
- Drag-and-drop page reordering
🔤 Typographie
- 9 polices intégrées + chargement .ttf/.otf
- 9 built-in fonts + custom .ttf/.otf loading
- Césure en 5 langues (FR, EN, DE, ES, IT)
- Hyphenation in 5 languages (FR, EN, DE, ES, IT)
- Justification avancée (word/letter spacing, glyph scaling)
- Advanced justification (word/letter spacing, glyph scaling)
- Chaînage de texte cross-page (style PAO pro)
- Text chaining across pages (professional DTP-style)
- Exposant, indice, capitales, petites capitales, barré
- Superscript, subscript, all caps, small caps, strikethrough
✏️ Dessin
- Rectangle, Cercle/Ellipse, Étoile, Pinceau libre
- Rectangle, Circle/Ellipse, Star, Freeform brush
- Outil plume Bézier professionnel avec édition de poignées
- Professional Bézier pen tool with curve handle editing
- Import SVG
- SVG import
- Opérations booléennes (Union, Soustraction, Intersection, Exclusion)
- Boolean operations (Unite, Subtract, Intersect, Exclude)
🖼️ Images
- Import, drag-and-drop, collage presse-papiers
- Import, drag-and-drop, clipboard paste
- Masquage d'image dans forme avec ajustement position/échelle
- Image-in-shape masking with position/scale adjustment
- Modale de recadrage complète avec poignées et préréglages
- Full crop modal with handles and presets
- 9 filtres style Instagram
- 9 Instagram-style filters
🎨 Couleur
- Sélecteurs couleur fond/contour, transparence
- Fill/stroke color pickers, transparency
- Mode RGB/CMYK
- RGB/CMYK mode toggle
- 30+ couleurs Pantone
- 30+ Pantone spot colors
- Nuancier avec dégradés (linéaire/radial)
- Swatch system with gradients
- Épreuvage écran CMYK (couché, mat, simulation papier)
- CMYK soft proofing (coated, matte, paper simulation)
📤 Export / Import
- PDF multi-pages (72/150/300 DPI, fond perdu, repères, barres couleur)
- PDF multi-page (72/150/300 DPI, bleed, trim marks, color bars)
- PDF imposé (cahier/livret)
- Imposed PDF (booklet imposition)
- Import : JSON, PDF, TXT, DOCX, ODT, IDML, .sla, SVG
- Import: JSON, PDF, TXT, DOCX, ODT, IDML, .sla, SVG
- Print-to-Web (mini-site HTML en ZIP)
- Print-to-Web (HTML mini-site in ZIP)
- Format .sp (JSON propriétaire)
- .sp format (proprietary JSON)
🤖 IA & Moderne
- OpenAI (GPT-6 Astra / Sol / Luna), Anthropic (Claude Opus 5.5 / Sonnet 5 / Fable 5.1), DeepSeek V4.1 Flash
- OpenAI (GPT-6 Astra / Sol / Luna), Anthropic (Claude Opus 5.5 / Sonnet 5 / Fable 5.1), DeepSeek V4.1 Flash
- 14 prompts de template + entrée libre
- 14 template prompts + free-form
- PWA (offline, installable)
- PWA (offline, installable)
- Sauvegarde Web3/IPFS via Pinata
- Web3/IPFS save via Pinata
- 3 langues UI : FR, EN, JA
- 3 UI languages: FR, EN, JA
Plug-ins — en créer un Plug-ins — write one
Un plug-in SuperPrint est un fichier .plugin.js que l'utilisateur installe depuis le bouton Plug-ins, en bas de la barre de droite. Il reçoit une API hôte, décrit ses réglages, et peut ajouter des objets au document. Deux plug-ins sont livrés : Global Refactor, qui règle d'un coup les styles, tailles, marges et couleurs du document entier, et Motif, qui habille une page ou un bloc d'un motif répété, d'une rosace, d'un kaléidoscope ou d'un chaos réglable — à partir de formes géométriques ou d'un mélange d'images. Depuis la 1.7.687, chaque plug-in allumé affiche de nouveau son icône dans la barre du haut, et un clic ouvre directement son panneau : la bibliothèque n'est plus qu'un détour pour découvrir et installer.
A SuperPrint plug-in is a .plugin.js file the user installs from the Plug-ins button, at the bottom of the right bar. It receives a host API, declares its settings, and can add objects to the document. Two plug-ins ship with the app: Global Refactor, which sets the styles, sizes, margins and colours of the whole document in one pass, and Vector Pattern, which fills a page or a block with a repeated pattern, a rosette, a kaleidoscope or an adjustable chaos — from geometric shapes or a mix of images. From 1.7.687, every enabled plug-in shows its icon in the top bar again, and one click opens its panel directly: the library is now only a place to discover and install.
Deux surfaces : la bibliothèque et la trappe
Two surfaces: the library and the trap
Le bouton Plug-ins ouvre la bibliothèque : une pop-in qui liste ce qui est installé — avec la date d'installation de chaque fichier — une zone de dépôt et une corbeille par plug-in venu de l'extérieur. Aucun filtre : la liste tient à l'écran, et un tri qui ne trie presque rien ne fait qu'ajouter une décision avant chaque coup d'œil. Le bouton Utiliser ouvre ensuite la trappe du plug-in — le panneau latéral qui pousse l'interface au lieu de la recouvrir, donc la page reste visible pendant qu'on la règle. Appliquer laisse la trappe ouverte pour enchaîner les essais ; Bibliothèque y revient. Une seule trappe est ouverte à la fois : lancer Global Refactor referme celle d'un plug-in, et l'inverse est vrai aussi.
The Plug-ins button opens the library: a pop-in listing what is installed — with each file's installation date — a drop zone and a bin for every plug-in from outside. No filters: the list fits on screen, and a sort that barely sorts only adds a decision before every glance. Use then opens the plug-in's trap — the side panel that pushes the interface instead of covering it, so the page stays visible while you set it. Apply keeps the trap open so you can iterate; Library goes back. Only one trap is open at a time: launching Global Refactor closes a plug-in's trap, and the reverse holds too.
Activer, désactiver, désinstaller
Enable, disable, uninstall
Chaque plug-in porte un interrupteur à côté de Utiliser. Un plug-in désactivé reste installé — il est simplement mis en sommeil : son nom s'affiche en gris, la pastille désactivé apparaît, et Utiliser s'éteint. C'est le bon geste pour un outil qu'on ne veut pas voir sans pour autant jeter le fichier. Le registre refuse de toute façon l'exécution d'un plug-in éteint, même appelé autrement que par l'interface. Désactiver referme aussi la trappe du plug-in si elle était ouverte : laisser à l'écran un outil que la bibliothèque déclare hors service serait trompeur.
Every plug-in carries a switch next to Use. A disabled plug-in stays installed — it is simply put to sleep: its name is greyed out, a disabled badge appears, and Use is switched off. That is the right gesture for a tool you do not want to see without throwing the file away. The registry refuses to run a disabled plug-in in any case, even when called from somewhere other than the interface. Disabling also closes the plug-in's trap if it was open: leaving on screen a tool the library declares out of service would be misleading.
La corbeille, elle, n'apparaît que sur les plug-ins venus de l'extérieur : un plug-in intégré fait partie du produit, le retirer supprimerait une fonction et non une extension. C'est pour cela que l'interrupteur existe pour tous, et la corbeille seulement pour les fichiers que vous avez déposés. Désinstaller efface aussi la préférence d'activation, sinon une réinstallation ramènerait le plug-in éteint sans que personne ne l'ait demandé.
The bin, by contrast, only appears on plug-ins from outside: a built-in plug-in is part of the product, removing it would delete a feature rather than an extension. That is why the switch exists for all, and the bin only for the files you dropped in. Uninstalling also clears the activation preference — otherwise reinstalling would bring the plug-in back switched off with nobody having asked for it.
Installer, c'est déposer un fichier
Installing means dropping a file
Glissez un .plugin.js n'importe où : sur la bibliothèque ou directement sur le plan de travail — le fichier est reconnu et installé dans les deux cas. La zone de dépôt de la bibliothèque reste le chemin le plus explicite, et un clic dessus ouvre le sélecteur de fichiers. Tout fichier qui n'est pas un .plugin.js est refusé avec le message exact, jamais importé par erreur comme une image. La corbeille retire le plug-in de SuperPrint ; le fichier, lui, reste où il est.
Drag a .plugin.js anywhere: onto the library or straight onto the canvas — the file is recognised and installed either way. The library's drop zone remains the most explicit route, and clicking it opens the file picker. Anything that is not a .plugin.js is refused with the precise message, never mistakenly imported as an image. The bin removes the plug-in from SuperPrint; the file stays where it is.
Un plug-in peut apporter sa propre trappe
A plug-in can bring its own trap
La plupart des plug-ins décrivent des options et SuperPrint construit le formulaire. Mais un outil qui a déjà son panneau — c'est le cas de Global Refactor, avec son aperçu en direct, son Annuler et son Valider — n'a rien à gagner à être réécrit dans un formulaire générique. Son manifeste déclare alors trappe: 'maquettePanel', et son run() ouvre le panneau qu'il possède : la bibliothèque se contente de l'exécuter, sans construire de formulaire. Le champ n'est honoré que pour un plug-in intégré : un fichier déposé par l'utilisateur ne peut pas réclamer un panneau du produit.
Most plug-ins declare options and SuperPrint builds the form. But a tool that already has its own panel — Global Refactor, with its live preview, its Cancel and its Apply — gains nothing from being rewritten into a generic form. Its manifest therefore declares trappe: 'maquettePanel', and its run() opens the panel it owns: the library simply runs it, without building a form. The field is only honoured for a built-in plug-in: a file dropped by the user cannot claim a panel of the product.
La forme d'un plug-in
The shape of a plug-in
SPPluginAPI({
id: 'mon-plug-in', // minuscules, chiffres, point, tiret
name: L('Mon plug-in', 'My plug-in', 'マイプラグイン'),
version: '1.0.0',
author: 'Votre nom',
icon: '◆', // un caractère, affiché dans la liste
icone: ' ',// facultatif : le dessin de la barre du haut (cf. plus bas)
description: L(
'Ce qu\'il fait, en une phrase.',
'What it does, in one sentence.',
'何をするのか、一文で。'
),
options: [ // les réglages — le panneau les rend
{ key: 'pas', label: L('Pas (mm)', 'Step (mm)', '間隔 (mm)'), type: 'number', defaut: 8, min: 1, max: 80 },
{ key: 'couleur', label: 'Couleur', type: 'color', defaut: '#1a1a1a' }
],
// trappe: 'maquettePanel', // intégrés seulement : le panneau que le run() ouvre
run: function (api, o) {
// o.pas, o.couleur : les valeurs saisies
var r = new api.fabric.Rect({
left: 0, top: 0,
width: api.document.largeur,
height: api.document.hauteur,
fill: o.couleur
});
api.add(r, { libelle: 'Mon plug-in' });
}
});
Le panneau construit lui-même le formulaire à partir de options. Un plug-in ne fabrique donc jamais son propre DOM : il ne peut pas casser l'interface, et il hérite automatiquement du thème clair et du thème sombre.
The panel builds the form from options itself. A plug-in therefore never creates its own DOM: it cannot break the interface, and it automatically inherits both the light and dark theme.
Écrire un plug-in en trois langues
Writing a plug-in in three languages
SuperPrint parle français, anglais et japonais. Un plug-in doit en faire autant, sinon ses réglages restent dans une langue au milieu d'une interface traduite. La fonction L(fr, en, ja) déclare un libellé dans les trois : elle est disponible telle quelle dans votre fichier, et aussi par api.L.
SuperPrint speaks French, English and Japanese. A plug-in must do the same, or its settings stay in one language in the middle of a translated interface. The L(fr, en, ja) function declares a label in all three: it is available as-is in your file, and through api.L.
name: L('Motif', 'Pattern', 'パターン'),
options: [{
key: 'symetrie', label: L('Symétrie', 'Symmetry', '対称'), type: 'select',
choix: [
{ value: 'aucune', label: L('Aucune', 'None', 'なし') },
{ value: 'kaleido', label: L('Kaléidoscope 8', 'Kaleidoscope 8', '万華鏡 8') }
]
}],
run: function (api, o) {
if (!api.selection().length) {
throw new Error(api.t(L(
'aucun bloc sélectionné', 'no block selected', 'ブロックが選択されていません'
)));
}
}
api.t() au moment de déclarer vos réglages — écrivez L(…) et laissez le registre résoudre. api.t() sert aux messages d'exécution, ceux qui naissent dans run().api.t() when declaring your settings — write L(…) and let the registry resolve. api.t() is for runtime messages, the ones born inside run().L(fr, en, ja) : le japonais manquant retombe sur l'anglais, l'anglais manquant sur le français. Vous pouvez donc traduire progressivement — un libellé non traduit ne laisse jamais un trou à l'écran. Une chaîne ordinaire reste acceptée partout : un plug-in monolingue continue de fonctionner tel quel.L(fr, en, ja): a missing Japanese falls back to English, a missing English to French. You can therefore translate gradually — an untranslated label never leaves a hole on screen. A plain string is still accepted everywhere: a monolingual plug-in keeps working as-is.L'icône de la barre du haut
The top-bar icon
Un plug-in allumé apparaît dans la barre du haut, à côté des outils du document : un clic ouvre directement sa trappe, sans repasser par la bibliothèque. Éteignez-le, l'icône s'en va. Elle est dessinée par le champ facultatif icone, qui contient le contenu d'un <svg> — les formes seulement, sans la balise <svg> elle-même.
An enabled plug-in appears in the top bar, beside the document's own tools: one click opens its trap directly, without going back through the library. Turn it off and the icon goes away. It is drawn by the optional icone field, which holds the content of an <svg> — the shapes only, without the <svg> tag itself.
icone: '<line x1="3.5" y1="6.5" x2="20.5" y2="6.5"/><circle cx="9" cy="6.5" r="2.3"/>'
fill="none" stroke="currentColor" stroke-width="1.8" et un viewBox="0 0 24 24" : une icône pleine aurait la même couleur mais beaucoup plus d'encre, et paraîtrait plus sombre que les icônes voisines. Peser le même poids se mesure : une icône de cette zone fait 410 à 430 pixels opaques sur un rendu 48 × 48 (loupe 421, étoile IA 411). Un dessin chargé — trois réglettes sur toute la largeur — pesait 732 et se lisait comme un carré noir. Comptez large : peu de traits, courts. Liste blanche de formes : path, circle, rect, line, polyline, polygon, ellipse, g. Tout le reste est refusé — script, image, use, href, style=, on…=, javascript:, url( — et le plug-in retombe alors sur son icon. Ce n'est pas une erreur : c'est un repli.fill="none" stroke="currentColor" stroke-width="1.8" and a viewBox="0 0 24 24": a solid icon would have the same colour but far more ink, and would look darker than its neighbours. Matching the weight is measurable: an icon in this zone carries 410 to 430 opaque pixels on a 48 × 48 render (magnifier 421, AI star 411). A heavy drawing — three full-width sliders — weighed 732 and read as a black square. Draw sparingly: few strokes, short. Shape whitelist: path, circle, rect, line, polyline, polygon, ellipse, g. Everything else is refused — script, image, use, href, style=, on…=, javascript:, url( — and the plug-in falls back to its icon. That is not an error: it is a fallback.Types de réglage
Setting types
| Type | Type | Rendu | Rendered as | Clés utiles | Useful keys |
|---|---|---|---|---|---|
'text' | champ texte | text field | defaut | ||
'number' | champ numérique | number field | min, max, pas | ||
'range' | curseur, avec sa valeur affichée à droite du libellé | slider, with its value shown right of the label | min, max, pas, unite | ||
'color' | sélecteur de couleur | colour picker | defaut en #rrggbb | ||
'select' | liste déroulante | dropdown | choix : tableau de valeurs ou de {value,label} | ||
'checkbox' | case à cocher | checkbox | defaut booléen | ||
'image' | import d'image (donne une dataURL) | image import (yields a dataURL) | — | ||
'images' | mixeur : un tableau de dataURL, avec vignettes, ajout et retrait | mixer: an array of dataURLs, with thumbnails, add and remove | — | ||
'apercu' | grande toile d'aperçu, dessinée par votre plug-in | large preview canvas, drawn by your plug-in | ratio (hauteur / largeur, 1 par défaut) |
unite et les tirettes. Un curseur rend un nombre nu : « 8 » ne dit pas s'il s'agit de millimètres, de degrés ou de pourcents. unite: ' mm' affiche 8 mm à droite du libellé, et la valeur suit le curseur en direct. Utilisez des pourcentages (0–100) plutôt que des fractions (0–1) quand le réglage est destiné à être tâtonné : un curseur se lit en entier, pas en décimales.unite and sliders. A slider yields a bare number: "8" does not say whether it means millimetres, degrees or percent. unite: ' mm' renders 8 mm right of the label, and the value follows the slider live. Prefer percentages (0–100) to fractions (0–1) when the setting is meant to be felt out: a slider is read in whole numbers, not decimals.Afficher un grand aperçu
Showing a large preview
Déclarez un champ 'apercu', puis dessinez dedans avec api.toileApercu(). La toile est un rond de 210 px, centré et détaché de 15 px du haut ; sa résolution interne est le double, pour rester nette sur un écran à densité doublée. C'est à vous de la remplir — et de découper au cercle : un rond n'a pas de coin, donc un dessin carré s'arrête net sur la diagonale et paraît rogné. Un motif ne se juge pas sur une vignette : montrez la répétition, pas une seule forme.
Declare an 'apercu' field, then draw into it with api.toileApercu(). The canvas is a circle 210 px across, centred and set 15 px from the top; its internal resolution is doubled, to stay sharp on a double-density screen. Filling it is up to you — and so is clipping to the circle: a circle has no corner, so a square drawing stops dead on the diagonal and looks cropped. A pattern cannot be judged from a thumbnail: show the repetition, not a single shape.
options: [
{ key: 'apercu', label: 'Aperçu', type: 'apercu', ratio: 1 }, /* rond */
{ key: 'taille', label: 'Taille', type: 'range', defaut: 4, min: 0.4, max: 60, pas: 0.2, unite: ' mm' }
],
run: function (api, o) {
var tuile = /* … votre canvas hors écran … */ null;
var t = api.toileApercu(); /* null si aucun champ 'apercu' */
if (t && tuile) {
var W = t.largeur, H = t.hauteur;
t.ctx.clearRect(0, 0, W, H);
t.ctx.save();
/* Le découpage au cercle : sans lui, le dessin s'arrête sur la
diagonale du carré et le rond paraît rogné au lieu d'être rempli. */
t.ctx.beginPath();
t.ctx.arc(W / 2, H / 2, Math.min(W, H) / 2, 0, Math.PI * 2);
t.ctx.clip();
var pas = W / 3; /* trois répétitions : on voit le rythme */
/* On part d'un pas AVANT le bord : le débord circulaire est couvert. */
for (var y = -pas; y < H + pas; y += pas) {
for (var x = -pas; x < W + pas; x += pas) {
t.ctx.drawImage(tuile, x, y, pas, pas);
}
}
t.ctx.restore();
}
}
Mixer plusieurs images
Mixing several images
Le champ 'images' vous rend un tableau de dataURL — l'utilisateur en ajoute autant qu'il veut, chacune se retire par sa croix. C'est à vous de décider comment elles se composent : superposées avec un mode de fusion, découpées en bandes, alternées d'une cellule à l'autre. Le plug-in Motif les empile dans la tuile avec globalCompositeOperation.
The 'images' field yields an array of dataURLs — the user adds as many as they like, each removable through its cross. How they combine is up to you: stacked with a blend mode, sliced into bands, alternated from cell to cell. The Vector Pattern plug-in stacks them in the tile using globalCompositeOperation.
/* Charger une fois, dessiner souvent : `cellule()` peut être appelée
des centaines de fois par tuile — un `new Image()` à chaque fois
ferait un chargement par copie. */
var chargees = [];
function chargerImages(liste) {
return Promise.all((liste || []).map(function (url) {
return new Promise(function (res) {
var im = new Image();
im.onload = function () { res(im); };
im.onerror = function () { res(null); };
im.src = url;
});
})).then(function (l) { chargees = l.filter(Boolean); });
}
function dessinerImages(g, taillePx, melange, opacite) {
if (!chargees.length) return false;
chargees.forEach(function (im) {
g.save();
g.globalCompositeOperation = melange; /* 'multiply', 'screen'… */
g.globalAlpha = opacite;
g.drawImage(im, -taillePx / 2, -taillePx / 2, taillePx, taillePx);
g.restore();
});
return true; /* des images ont été posées */
}
toDataURL() et ne redimensionnez pas d'image dans le chemin d'aperçu : construisez une petite tuile et répétez-la. C'est la différence entre un réglage qu'on tâtonne et une interface qui saccade.toDataURL(), and do not resize images on the preview path: build a small tile and repeat it. That is the difference between a setting you feel out and an interface that stutters.L'API hôte
The host API
| Appel | Call | Ce qu'il donne | What it gives |
|---|---|---|---|
api.fabric | le moteur graphique (Fabric 5.1) | the graphics engine (Fabric 5.1) | |
api.mm(v) / api.px(v) | millimètres ↔ points | millimetres ↔ points | |
api.document | largeur, hauteur, page, pages, fond perdu, marges | width, height, page, pages, bleed, margins | |
api.selection() | les objets sélectionnés | the selected objects | |
api.canvases() | tous les plans de travail (une page = un canvas) — pour retirer ses propres objets partout | every canvas (one page = one canvas) — to remove your own objects everywhere | |
api.version | la version de l'API hôte — à comparer si votre plug-in dépend d'un comportement précis | the host API version — compare it if your plug-in relies on a precise behaviour | |
api.add(obj, opts) | ajoute au plan de travail — annulable par Ctrl+Z. opts : libelle, envoyerEnArriere, verrouille | adds to the canvas — undoable with Ctrl+Z. opts: libelle, envoyerEnArriere, verrouille | |
api.addMany(liste) | ajoute plusieurs objets en une action | adds several objects as one action | |
api.remove(obj) | retire un objet, ou un tableau d'objets, du plan actif | removes an object, or an array of objects, from the active canvas | |
api.apercu | true quand la trappe vous exécute pour un aperçu — voir plus bas | true when the trap runs you for a preview — see below | |
api.toileApercu() | la grande toile d'aperçu de la trappe : { canvas, ctx, largeur, hauteur }, ou null. Vous y dessinez vous-même le résultat — voir plus bas | the trap's large preview canvas: { canvas, ctx, largeur, hauteur }, or null. You draw the result into it yourself — see below | |
api.sync() | synchronise pages[] sans écrire d'historique | syncs pages[] without a history entry | |
api.commit(libelle) | écrit l'entrée d'historique (sans effet en aperçu) | writes the history entry (no-op during preview) | |
api.imageDataUrl() | ouvre un sélecteur, rend une dataURL | opens a file picker, yields a dataURL | |
api.t(v) | résout un libellé L(fr, en, ja) dans la langue de l'interface — pour les messages d'exécution | resolves an L(fr, en, ja) label into the interface language — for runtime messages | |
api.alert(msg) / api.prompt(q, def) | dialogues de la DA SuperPrint | SuperPrint-styled dialogs | |
api.store.get/set | un stockage persistant, propre au plug-in | persistent storage, scoped to the plug-in | |
api.log(msg) | écrit dans la console du navigateur | writes to the browser console |
L'aperçu en direct, et pourquoi run() est appelé plusieurs fois
Live preview, and why run() is called several times
La trappe n'attend pas que vous cliquiez : chaque mouvement de tirette relance votre run(), 140 ms après le dernier changement. C'est ce qui fait qu'un plug-in se règle en le regardant. Trois conséquences, et elles sont toutes à votre charge :
The trap does not wait for a click: every slider movement re-runs your run(), 140 ms after the last change. That is what lets a plug-in be adjusted by watching it. Three consequences, and all three are your responsibility:
- Votre
run()doit être rejouable. Il sera appelé dix, trente fois de suite avec des réglages différents. Retirez donc vos objets précédents avant d'en poser de nouveaux — c'est ce que fait le plug-in Motif avecapi.canvases()et son marqueur_spMotifPlugin. - N'écrivez rien de lourd sans regarder
api.apercu. En aperçu, l'historique n'est pas écrit par le registre :api.add()se contente de synchroniser. Vous pouvez donc tout faire, sauf ce qui coûte cher pour rien — unapi.alert()à chaque mouvement serait insupportable. - Une seule entrée d'historique par session de réglage. C'est la validation (Enregistrer, ou la fermeture de la trappe) qui l'écrit. Mesuré : dix mouvements de tirette produisent zéro entrée, et le bouton Enregistrer exactement une.
- Your
run()must be replayable. It will be called ten, thirty times in a row with different settings. So remove your previous objects before placing new ones — that is what the Vector Pattern plug-in does withapi.canvases()and its_spMotifPluginmarker. - Do nothing heavy without checking
api.apercu. During preview the registry does not write history:api.add()only syncs. So you may do anything, except what costs a lot for nothing — anapi.alert()on every movement would be unbearable. - One history entry per tuning session. Validation (Save, or closing the trap) writes it. Measured: ten slider movements produce zero entries, and the Save button exactly one.
run: function (api, o) {
/* 1. Enlever ce que la fois précédente a posé — SURTOUT en aperçu. */
api.canvases().forEach(function (cv) {
cv.getObjects().slice().forEach(function (obj) {
if (obj && obj._monPlugIn) cv.remove(obj);
});
if (cv.requestRenderAll) cv.requestRenderAll();
});
/* 2. Construire et poser. `api.add` gère l'aperçu tout seul :
pas d'historique pendant le réglage, une entrée à la validation. */
var r = new api.fabric.Rect({ left: 0, top: 0,
width: api.document.largeur, height: api.document.hauteur, fill: o.couleur });
r._monPlugIn = true; // votre marque, pour l'étape 1
api.add(r, { libelle: 'Mon plug-in', envoyerEnArriere: true });
}
Un plug-in complet, à copier dans un fichier
A complete plug-in, copy it into a file
Enregistrez ce texte sous cadre-photo.plugin.js, puis glissez le fichier sur la bibliothèque. Il dessine un cadre et y pose un titre, avec trois réglages et un aperçu en direct.
Save this text as cadre-photo.plugin.js, then drop the file onto the library. It draws a frame and places a title inside it, with three settings and a live preview.
SPPluginAPI({
id: 'cadre-photo',
name: 'Cadre photo',
version: '1.0.0',
author: 'Vous',
icon: '❏',
description: 'Un cadre, un titre, des marges : la base d\'une couverture.',
options: [
{ key: 'marge', label: 'Marge (mm)', type: 'number', defaut: 12, min: 0, max: 60, pas: 1 },
{ key: 'epaisseur', label: 'Épaisseur du filet (mm)', type: 'range', defaut: 0.6, min: 0.1, max: 6, pas: 0.1 },
{ key: 'titre', label: 'Titre', type: 'text', defaut: 'Titre' },
{ key: 'couleur', label: 'Couleur', type: 'color', defaut: '#1a1a1a' }
],
run: function (api, o) {
var f = api.fabric;
/* Rejouable : on retire ce que la fois précédente a posé. */
api.canvases().forEach(function (cv) {
cv.getObjects().slice().forEach(function (obj) {
if (obj && obj._cadrePhoto) cv.remove(obj);
});
if (cv.requestRenderAll) cv.requestRenderAll();
});
var L = api.document.largeur, H = api.document.hauteur;
var m = api.mm(Math.max(0, Number(o.marge) || 0));
var cadre = new f.Rect({
left: m, top: m, width: L - m * 2, height: H - m * 2,
fill: 'transparent', stroke: o.couleur,
strokeWidth: api.mm(Math.max(0.1, Number(o.epaisseur) || 0.6))
});
cadre._cadrePhoto = true;
api.add(cadre, { libelle: 'Cadre photo' });
var titre = new f.Textbox(String(o.titre || ''), {
left: m, top: m + m * 0.5, width: L - m * 2,
fontFamily: 'Montserrat', fontSize: H * 0.07, fontWeight: '700',
fill: o.couleur, textAlign: 'center'
});
titre._cadrePhoto = true;
api.add(titre, { libelle: 'Cadre photo' });
}
});
Ce que le registre vérifie avant d'installer
What the registry checks before installing
Le fichier est évalué une première fois, à vide. S'il échoue, rien n'est installé et le message dit exactement ce qui manque :
The file is evaluated once, empty. If it fails, nothing is installed and the message says exactly what is missing:
| Message | Message | Cause | Cause |
|---|---|---|---|
« le plug-in n'appelle pas SPPluginAPI({ … }) » | "the plug-in does not call SPPluginAPI({ … })" | le fichier s'exécute sans déclarer de manifeste | the file runs without declaring a manifest |
| « identifiant de plug-in invalide » | "invalid plug-in identifier" | id absent, ou hors de [a-z0-9._-], 2 à 64 caractères | id missing, or outside [a-z0-9._-], 2–64 characters |
| « nom du plug-in manquant » | "plug-in name missing" | name absent — attention, c'est name, pas nom | name missing — note it is name, not nom |
| « le plug-in a échoué au chargement : … » | "the plug-in failed to load: …" | une exception est levée pendant l'évaluation du fichier | an exception is thrown while the file is evaluated |
| « ce plug-in n'a pas de fonction run() » | "this plug-in has no run() function" | run absent — le plug-in s'installe mais ne peut rien faire | run absent — it installs but can do nothing |
id, name, version, author, icon, description, options, run. Chaque option porte key, label, type, defaut, min, max, pas, choix, aide. Écrire nom ou label à la place de name est la première erreur de tout premier plug-in — et le message vous le dit.id, name, version, author, icon, description, options, run. Each option carries key, label, type, defaut, min, max, pas, choix, aide. Writing nom or label instead of name is every first plug-in's first mistake — and the message tells you so.Partager un plug-in
Sharing a plug-in
Un plug-in est un seul fichier. Il n'y a rien à compiler, rien à empaqueter : envoyez le .plugin.js, le destinataire le glisse sur sa bibliothèque. Pour qu'il soit repris par d'autres, donnez-lui un id stable et incrémentez version à chaque correction — c'est ce que la bibliothèque affiche, et c'est ce qui permet de reconnaître une ancienne copie à l'œil. Un plug-in intégré au produit, lui, peut déclarer trappe pour ouvrir un panneau existant ; ce champ est ignoré pour un fichier déposé, par sécurité.
A plug-in is a single file. Nothing to compile, nothing to package: send the .plugin.js, the recipient drops it onto their library. To make it reusable, give it a stable id and bump version with every fix — that is what the library displays, and what lets an old copy be recognised at a glance. A built-in plug-in may declare trappe to open an existing panel; that field is ignored for a dropped file, for safety.
Où les plug-ins sont rangés
Where plug-ins live
Clé localStorage | Contenu | Key | Content |
|---|---|---|---|
sp_plugins_v1 | le code source de chaque plug-in installé (y compris les intégrés), avec sa date d'installation | the source of every installed plug-in (built-ins included), with its install date | |
sp_plugins_actifs_v1 | l'état allumé/éteint, { "mon-plug-in": false } | the on/off state, { "my-plugin": false } | |
sp_plugin_data_<id> | ce que le plug-in écrit lui-même avec api.store.set(…) — un espace par plug-in, jamais partagé | what the plug-in writes itself with api.store.set(…) — one space per plug-in, never shared |
Les deux sont propres au navigateur et au profil : un plug-in installé sur un poste ne l'est pas sur un autre. C'est voulu — un plug-in est du code exécutable, il ne doit pas voyager avec un document. Pour la même raison, aucun .sp ne contient de plug-in : ce qu'un plug-in a produit est enregistré comme des objets ordinaires, mais le plug-in lui-même reste chez vous.
Both are per-browser and per-profile: a plug-in installed on one machine is not installed on another. That is deliberate — a plug-in is executable code and must not travel inside a document. For the same reason no .sp contains a plug-in: what a plug-in produced is saved as ordinary objects, but the plug-in itself stays with you.
Le plug-in de référence : Motif
The reference plug-in: Vector Pattern
Livré avec SuperPrint, Motif est le plus gros plug-in du produit et sert de modèle : 29 réglages dont 13 tirettes, 15 formes, 7 symétries du groupe du carré (D4), un tirage pseudo-aléatoire à graine — donc reproductible —, une super-tuile de N×N cellules pour casser la répétition, un mode kaléidoscope de page qui reflète un quadrant sur les quatre, et un mode crazy qui tire forme, angle, échelle et couleur à chaque copie. Son mixeur empile jusqu'à huit images avec un mode de fusion. Ouvrez-le dans un éditeur : c'est le meilleur exemple de ce que l'API permet — le grand aperçu (api.toileApercu()), les champs 'apercu' et 'images', l'aperçu en direct et le retrait de ses propres objets d'un rendu à l'autre.
Shipped with SuperPrint, Vector Pattern is the product's largest plug-in and serves as the model: 29 settings including 13 sliders, 15 shapes, 7 symmetries of the square group (D4), a seeded pseudo-random draw — hence reproducible —, an N×N super-tile to break up repetition, a page kaleidoscope mode that mirrors one quadrant onto all four, and a crazy mode that draws shape, angle, scale and colour afresh for every copy. Its mixer stacks up to eight images with a blend mode. Open it in an editor: it is the best example of what the API allows — the large preview (api.toileApercu()), the 'apercu' and 'images' fields, live preview, and removing its own objects between renders.
Un mot sur les performances
A word on performance
Pour répéter une forme, ne créez pas des milliers d'objets : une page A4 à 8 mm de pas en demanderait ≈ 2 300, et la sélection comme l'export s'effondrent. Utilisez un fabric.Pattern — un seul objet, que le navigateur répète au rendu et que l'export PDF répète de la même façon. C'est ce que fait le plug-in Motif : 9 ms pour habiller une page entière, mesuré.
To repeat a shape, do not create thousands of objects: an A4 page at 8 mm spacing would need ≈ 2,300, and both selection and export collapse. Use a fabric.Pattern — a single object the browser repeats at render time and the PDF export repeats the same way. That is what the Vector Pattern plug-in does: 9 ms to fill an entire page, measured.
Serveur MCP MCP Server
Le dossier superprint/mcp-server/ contient un serveur Model Context Protocol. Il permet à un assistant — Claude Desktop, Claude Code, Cursor, ou tout autre client MCP — de lire, convertir, créer et motiver des documents SuperPrint. Le bouton MCP Server, en bas de la barre de droite, affiche la commande exacte et le JSON de configuration, prêts à copier.
The superprint/mcp-server/ folder contains a Model Context Protocol server. It lets an assistant — Claude Desktop, Claude Code, Cursor, or any other MCP client — read, convert, create and pattern SuperPrint documents. The MCP Server button, at the bottom of the right bar, shows the exact command and the configuration JSON, ready to copy.
Les outils exposés
Exposed tools
| Outil | Tool | Ce qu'il fait | What it does |
|---|---|---|---|
superprint_formats | liste les formats de page en millimètres | lists page formats in millimetres | |
superprint_inspect | résume un .sp ou .json | summarises a .sp or .json | |
superprint_convert | convertit .sp → .json et retour | converts .sp → .json and back | |
superprint_create | crée un document (format, pages, texte) | creates a document (format, pages, text) | |
superprint_pattern | crée un document habillé d'un motif | creates a document filled with a pattern |
Les paramètres de chaque outil
Each tool's parameters
| Outil | Paramètres (* = obligatoire) |
Tool | Parameters (* = required) |
|---|---|---|---|
superprint_formats | aucun | none | |
superprint_inspect | chemin* | ||
superprint_convert | chemin*, vers* (sp | json), sortie | ||
superprint_create | sortie*, titre, format (A4, A5, A3, Letter, perso), pages (défaut 1), texte | ||
largeur, hauteur (si format: "perso"), fondPerdu (défaut 3 mm), marges (défaut 20 mm) | |||
superprint_pattern | sortie*, titre, format, couleur, angle | ||
forme : cercle, carre, losange, triangle, etoile, croix, vague, lignes — pas (défaut 8 mm), taille (défaut 4 mm) |
sortie est obligatoire pour les deux outils qui fabriquent un document ; superprint_convert s'en passe et écrit à côté du fichier source en suffixant .converti — doc.sp devient doc.converti.json. Aucun outil n'écrase le fichier d'entrée. Par ailleurs un chemin relatif est résolu depuis le répertoire courant du client MCP — donc donnez des chemins absolus, sinon un client lancé depuis ailleurs écrira ailleurs.sortie is required for the two tools that build a document; superprint_convert does without it and writes next to the source file with a .converti suffix — doc.sp becomes doc.converti.json. No tool overwrites its input. Also, a relative path is resolved from the MCP client's working directory — so give absolute paths, or a client started elsewhere will write elsewhere.Ce qu'on peut demander à l'assistant
What you can ask the assistant
Une fois le serveur déclaré, l'assistant voit les cinq outils comme n'importe quel autre. Les demandes qui marchent le mieux sont celles qui nomment le format et le fichier de sortie :
Once the server is declared, the assistant sees the five tools like any other. The requests that work best are those naming the format and the output file:
- « Crée une A5 de 8 pages avec le titre Rapport annuel et enregistre-la dans
C:\tmp\rapport.sp. » - « Inspecte
C:\tmp\rapport.spet dis-moi combien de pages et d'objets il contient. » - « Convertis-le en
.jsonà côté, puis compare les deux résumés. » - « Génère une couverture A4 avec un motif d'étoiles à 12 mm, encre
#1a1a1a, dansC:\tmp\couverture.sp. » - "Create an 8-page A5 with the title Annual report and save it to
C:\tmp\report.sp." - "Inspect
C:\tmp\report.spand tell me how many pages and objects it holds." - "Convert it to
.jsonnext to it, then compare the two summaries." - "Generate an A4 cover with a 12 mm star pattern, ink
#1a1a1a, intoC:\tmp\cover.sp."
Le fichier produit s'ouvre ensuite dans SuperPrint par Ouvrir un projet, comme n'importe quel .sp : le serveur et l'application partagent le même format, c'est tout l'intérêt.
The produced file then opens in SuperPrint through Open project, like any .sp: server and application share the same format, which is the whole point.
Installation
Installation
Aucune dépendance : le serveur n'utilise que Node ≥ 18. Il n'y a pas de npm install — le protocole MCP sur stdio est du JSON-RPC 2.0 délimité par des sauts de ligne, l'implémenter directement évite un registre inaccessible ou une coupure réseau au premier lancement.
No dependencies: the server only uses Node ≥ 18. There is no npm install — MCP over stdio is newline-delimited JSON-RPC 2.0, and implementing it directly avoids an unreachable registry or a network failure on first launch.
cd superprint/mcp-server
node server.mjs
# Claude Desktop : %APPDATA%\Claude\claude_desktop_config.json (Windows)
# ~/Library/Application Support/Claude/... (macOS)
{
"mcpServers": {
"superprint": {
"command": "node",
"args": ["/chemin/absolu/vers/superprint/mcp-server/server.mjs"]
}
}
}
Le serveur travaille sur des fichiers, jamais sur l'application ouverte : aucun état partagé avec une fenêtre, donc utilisable en terminal, en serveur ou en CI. Deux limites assumées : il n'y a pas d'export PDF (le moteur de rendu vit dans le navigateur), et superprint_pattern décrit le motif dans l'objet plutôt que de dessiner des milliers de formes.
The server works on files, never on the running application: no state shared with a window, so it works in a terminal, on a server or in CI. Two accepted limits: there is no PDF export (the rendering engine lives in the browser), and superprint_pattern describes the pattern inside the object rather than drawing thousands of shapes.
Le bouton « MCP Server »
The "MCP Server" button
En bas de la barre de droite, le bouton MCP Server n'installe rien : il affiche ce qu'il faut copier. La fenêtre montre quatre blocs — le dossier du serveur, la commande de lancement, l'emplacement du fichier de configuration du client selon le système, et le bloc mcpServers déjà rempli — chacun avec son bouton Copier. C'est le moyen le plus court de répondre à « où est le serveur, et qu'est-ce que je colle où ? ».
At the bottom of the right bar, the MCP Server button installs nothing: it shows what to copy. The window displays four blocks — the server folder, the launch command, the client configuration file location for your system, and the already-filled mcpServers block — each with its own Copy button. It is the shortest answer to "where is the server, and what do I paste where?".
file://, SuperPrint déduit le dossier du serveur de sa propre adresse et vous donne C:\…\superprint\mcp-server\ tout prêt. Ouvert depuis un serveur de développement ou la coquille Tauri, le chemin disque n'est pas lisible depuis la page : le bouton affiche alors le dossier relatif et le dit franchement, plutôt que d'inventer un chemin qui échouerait à l'installation. Le bloc mcpServers, lui, exige toujours un absolu — c'est la seule panne possible après la copie.file://, SuperPrint derives the server folder from its own address and hands you C:\…\superprint\mcp-server\ ready to paste. Opened from a dev server or the Tauri shell, the disk path is not readable from the page: the button then shows the relative folder and says so plainly, rather than inventing a path that would fail at launch. The mcpServers block itself always needs an absolute — that is the only failure left after copying.Vérifier que le serveur parle
Checking that the server talks
Sur stdio, le serveur attend du JSON-RPC délimité par des sauts de ligne. On peut donc le tester sans client, en lui envoyant une poignée de main puis la liste des outils :
On stdio the server expects newline-delimited JSON-RPC. So it can be tested without a client, by sending a handshake then the tool list:
# PowerShell — deux lignes JSON-RPC dans l'entrée standard du serveur
@'
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"t","version":"1"}}}
{"jsonrpc":"2.0","id":2,"method":"tools/list"}
'@ | node server.mjs
Deux lignes de réponse, dont la seconde contient les cinq outils : si vous les voyez, la configuration du client ne peut plus échouer que sur le chemin de server.mjs. C'est la panne la plus fréquente, et la fenêtre du bouton donne ce chemin tout prêt. Sous macOS ou Linux, remplacez le @'…'@ par un printf '%s\n' '…' '…'.
Two response lines, the second holding the five tools: if you see them, the client configuration can then only fail on the path to server.mjs. That is the most common failure, and the button's window hands you that path ready to paste. On macOS or Linux, replace the @'…'@ here-string with a printf '%s\n' '…' '…'.
Raccourcis clavier Keyboard Shortcuts
Texte
Text
| Raccourci | Shortcut | Action | Action |
|---|---|---|---|
| Ctrl+B | Gras | Bold | |
| Ctrl+I | Italique | Italic | |
| Ctrl+U | Souligné | Underline | |
| Ctrl+Shift+H | Surligner | Highlight | |
| Ctrl+A | Tout sélectionner | Select all | |
| Tab | Tabulation : insère une tabulation dans le bloc en édition (les taquets sont activés au besoin, pas par défaut 10 mm) | Tab: inserts a tab in the block being edited (tab stops enabled if needed — default step 10 mm) | |
| Option + Tab Maj + Tab | Tab intégré : navigation vers le champ / contrôle suivant (comportement natif du navigateur ; sous Windows Alt+Tab est réservé au système, utilisez Maj+Tab). | Built-in Tab: move to the next field / control (native browser behaviour; on Windows Alt+Tab is reserved by the system — use Shift+Tab). |
Édition
Editing
| Raccourci | Shortcut | Action | Action |
|---|---|---|---|
| Ctrl+C / X / V | Copier / Couper / Coller | Copy / Cut / Paste | |
| Ctrl+Z | Annuler | Undo | |
| Ctrl+Y / Ctrl+Shift+Z | Rétablir | Redo | |
| Suppr / Retour arrière | Supprimer l'objet | Delete object | |
| Alt+Glisser | Dupliquer l'objet | Duplicate object |
Objets
Objects
| Raccourci | Shortcut | Action | Action |
|---|---|---|---|
| Ctrl+Shift+G | Grouper | Group | |
| Ctrl+Shift+U | Dégrouper | Ungroup | |
| Ctrl+] | Avancer d'un plan | Bring forward | |
| Ctrl+[ | Reculer d'un plan | Send backward | |
| Flèches | Déplacer de 1px | Move 1px | |
| Shift+Flèches | Déplacer de 10px | Move 10px |
Outils rapides
Quick Tools
| Raccourci | Shortcut | Action | Action |
|---|---|---|---|
| ⌥+T | Ajouter un texte | Add text | |
| ⌥+I | Ajouter une image | Add image | |
| ⌥+R | Ajouter un rectangle | Add rectangle | |
| ⌥+C | Ajouter un cercle | Add circle | |
| ⌥+P | Outil plume | Pen tool |
Fichiers & Navigation
Files & Navigation
| Raccourci | Shortcut | Action | Action |
|---|---|---|---|
| Ctrl+S | Sauvegarder (JSON ou Web3) | Save (JSON or Web3) | |
| Ctrl+O | Ouvrir un projet | Open project | |
| Ctrl+E | Exporter PDF | Export PDF | |
| Ctrl+N | Nouvelle page | New page | |
| Ctrl+← / → | Page précédente / suivante | Previous / Next page | |
| Ctrl+L | Lier les blocs texte | Link text blocks | |
| Ctrl+Shift+L | Délier les blocs texte | Unlink text blocks |
Zoom
| Raccourci | Shortcut | Action | Action |
|---|---|---|---|
| Ctrl+= | Zoom avant | Zoom in | |
| Ctrl+- | Zoom arrière | Zoom out | |
| Ctrl+0 | Réinitialiser à 100% | Reset to 100% | |
| Ctrl+Molette | Zoom libre | Free zoom |
Formats de fichiers File Formats
Import (10 formats)
Import (10 formats)
| Format | Bibliothèque | Library | Description FR | Description EN |
|---|---|---|---|---|
| JSON | Native | Restauration complète du projet | Full project restore | |
| PDF.js | Page par page avec aperçu, sélection, recadrage | Page-by-page with preview, selection, crop | ||
| TXT / RTF | Native | Texte brut avec auto-pagination | Plain text with auto-pagination | |
| DOCX | Mammoth.js | Documents Word (texte + images inline) | Word docs (text + inline images) | |
| ODT | JSZip + XML | OpenDocument (texte, listes, tableaux, images) | OpenDocument (text, lists, tables, images) | |
| IDML | JSZip + XML | Format d'échange PAO — ZIP avec polices + liens | Standard DTP interchange format — ZIP with fonts + links | |
| .sla | XML parser | Texte + formes basiques (BETA) | Basic text + shapes (BETA) | |
| SVG | Fabric.js | Graphiques vectoriels | Vector graphics | |
| Images | Fabric.js | PNG, JPG, WebP (fichier ou presse-papiers) | PNG, JPG, WebP (file or clipboard) | |
| .sp | JSON | Projet complet en JSON (images et polices embarquées) | Complete project as JSON (images and fonts embedded) |
Export (4 formats)
Export (4 formats)
| Format | Bibliothèque | Library | Description FR | Description EN |
|---|---|---|---|---|
| jsPDF | Multi-pages, 72/150/300 DPI, fond perdu, repères d'impression | Multi-page, 72/150/300 DPI, bleed, trim marks | ||
| PDF imposé | jsPDF | Imposition cahier pour impression | Booklet imposition for print | |
| Print-to-Web | JSZip | Mini-site HTML en ZIP (D4Export) | HTML mini-site in ZIP (D4Export) | |
| .sp | JSON | Projet complet en JSON (images intégrées) | Complete project as JSON (images embedded) |
Bibliothèques Libraries
| Bibliothèque | Library | Version | Fichier | File | Rôle | Role |
|---|---|---|---|---|---|---|
| Fabric.js | 5.3.0 | JS/fabric.min.js | Moteur de rendu canvas — objets, texte, images, événements, sélection | Canvas rendering engine — objects, text, images, events, selection | ||
| jsPDF | 2.x | JS/jspdf.umd.min.js | Génération PDF multi-pages côté client | Client-side multi-page PDF generation | ||
| JSZip | 3.x | JS/jszip.min.js | Lecture/écriture ZIP pour IDML, ODT et l'export Print-to-Web | ZIP read/write for IDML, ODT and Print-to-Web export | ||
| PDF.js | 3.x | JS/pdf.min.js | Rendu PDF pour import page par page | PDF rendering for page-by-page import | ||
| Paper.js | 0.12 | JS/paper-full.min.js | Opérations booléennes de tracés vectoriels (Pathfinder) | Boolean path operations (Pathfinder) | ||
| Mammoth.js | 1.x | JS/mammoth.min.js | Conversion DOCX → HTML structuré | DOCX to structured HTML conversion | ||
| Hypher | 0.2 | JS/hypher.js + hyphenation-*.js | Moteur de césure extensible (FR, EN, DE, ES, IT) | Extensible hyphenation engine (FR, EN, DE, ES, IT) | ||
| pdf-lib | 1.17 | JS/pdf-lib.min.js | Post-traitement PDF natif : export CMYK, imposition, typos vectorielles | Native PDF post-processing: CMYK export, imposition, vector typography | ||
| WebLLM (studio) | ^0.2.84 | node_modules/@mlc-ai/web-llm (npm) | Inférence LLM locale dans le navigateur (WebGPU) — studio SP213 | In-browser local LLM inference (WebGPU) — SP213 studio | ||
| Vite (version locale) | ^6.3.5 | node_modules/vite (npm) | Serveur de dev + bundler de la version locale (sp213-local) | Dev server + bundler for the local version (sp213-local) |
Documentation générée le 4 octobre 2026 — v1.7.687 Documentation generated September 16, 2026 — v1.7.456