Outils pour utilisateurs

Outils du site


issue193:inkscape

In the previous instalment, I looked at the new multi-page tool introduced in Inkscape 1.2. As I often delve into the guts of Inkscape’s SVG files in this series, I thought it would be interesting to see exactly how multiple pages have been implemented. What I’ve found is a little disappointing, because I think the developers have made a slightly bad choice that limits the usefulness of multi-page mode more than was necessary. In this article, we’ll take a look at exactly what that mistake was, and a couple of ways to work around it. To investigate this, we’ll be using a simple multi-page Inkscape file. Each page contains a colored rectangle that fills the whole page area (so it’s easier to see the page boundary when loaded into a web browser), plus a random single object in the middle, as a placeholder for the real content you might put in your document.

Dans l'épisode précédent, j'ai examiné le nouvel outil multi-pages introduit dans Inkscape 1.2. Comme je plonge souvent dans les entrailles des fichiers SVG d'Inkscape dans cette série, j'ai pensé qu'il serait intéressant de voir exactement comment les pages multiples ont été implémentées. Ce que j'ai trouvé est un peu décevant, car je pense que les développeurs ont fait un choix légèrement mauvais qui limite l'utilité du mode multi-pages plus que nécessaire. Dans cet article, nous allons voir en quoi consiste exactement cette erreur, et quelques façons de la contourner.

Pour ce faire, nous utiliserons un simple fichier Inkscape multipage. Chaque page contient un rectangle coloré qui remplit toute la surface de la page (de sorte qu'il est plus facile de voir les limites de la page lorsqu'elle est chargée dans un navigateur Web), ainsi qu'un objet unique aléatoire au milieu, tenant lieu de remplaçant d'un contenu réel que vous pourriez mettre dans votre document.

The first thing to do is to load the SVG file directly into a web browser and see what appears. You don’t win any prizes for guessing that only the first page is displayed. This is simply the same behaviour as a single-page Inkscape document. It could be argued that the main purpose of the multi-page tool is for importing and exporting PDFs, so it’s hardly surprising that a web browser won’t show the extra pages, but since SVG is a first-class format for the web, it does seem a shame that there’s no easy way to view the other pages. But the key word there is “easy”. If you’re prepared to get a little technical, it is possible to work around this limitation. First, let’s take a look at what’s going on inside the SVG file itself. You can simply open it in a text editor, but as this is an Inkscape column, I’m going to look at it via the Edit > XML Editor… option (below).

La première chose à faire est de charger le fichier SVG directement dans un navigateur Web et de voir ce qui s'affiche. Vous ne gagnerez pas de prix en devinant que seule la première page est affichée. Il s'agit tout simplement du même comportement qu'un document Inkscape d'une seule page. On pourrait arguer que le principal objectif de l'outil multi-pages est d'importer et d'exporter des PDF, et qu'il n'est donc pas surprenant qu'un navigateur Web n'affiche pas les pages supplémentaires, mais puisque SVG est un format de première classe pour le Web, il semble dommage qu'il n'y ait pas de moyen facile de visualiser les autres pages. Toutefois, le mot clé est « facile ». Si vous êtes prêt à faire preuve d'un peu de technique, il est possible de contourner cette limitation.

Tout d'abord, regardons ce qui se passe à l'intérieur du fichier SVG lui-même. Vous pouvez simplement l'ouvrir dans un éditeur de texte, mais comme il s'agit de la rubrique Inkscape, je vais l'examiner via l'option Édition > Éditeur XML… (ci-dessous).

In the left pane, we can see the tree of XML elements that make up our file. At the top is the ‘root’ node, shown as <svg:svg …>, followed by a <sodipodi:namedview …>. If you’re new to Inkscape, you may not realise it was forked from an older program named Sodipodi, the fingerprints of which are still present inside Inkscape’s SVG files. In this case, we have a <namedview> element which is in the ‘sodipodi’ namespace. Namespaces are a means of mixing multiple different XML languages together in one file and ensuring they don’t clash with each other. In the case of Inkscape, it means that anything in the ‘sodipodi’ or ‘inkscape’ namespaces are not part of the SVG standard, and will simply be ignored by most other programs. As hinted by its Sodipodi heritage, the <namedview> element has been present in Inkscape files right from the start. It contains metadata about how the file should be displayed when loaded into Inkscape: this is where you’ll find XML attributes that store the window size, zoom factor, and page color, amongst other things. But with a multi-page Inkscape document the <namedview> element has gained something else: children. Expanding the <namedview> entry in the XML editor reveals an <inkscape:page …> element for each page in your document. To clarify, these are <page> elements in the ‘inkscape’ namespace, so other applications – including your web browser – have no idea what to do with them.

Dans le panneau de gauche, nous pouvons voir l'arbre des éléments XML qui composent notre fichier. Au sommet se trouve le noeud « racine », représenté par <svg:svg …>, suivi par <sodipodi:namedview …>. Si vous ne connaissez pas Inkscape, vous ne savez peut-être pas qu'il a été dérivé d'un ancien programme appelé Sodipodi, dont les empreintes sont encore présentes dans les fichiers SVG d'Inkscape. Dans ce cas, nous avons un élément <namedview> qui se trouve dans l'espace de noms « sodipodi ». Les espaces de noms sont un moyen de mélanger plusieurs langages XML différents dans un seul fichier et de s'assurer qu'ils n'entrent pas en conflit les uns avec les autres. Dans le cas d'Inkscape, cela signifie que tout ce qui se trouve dans les espaces de noms « sodipodi » ou « inkscape » ne fait pas partie de la norme SVG et sera simplement ignoré par la plupart des autres programmes.

Comme l'indique son héritage Sodipodi, l'élément <namedview> est présent dans les fichiers Inkscape depuis le début. Il contient des métadonnées sur la façon dont le fichier doit être affiché lorsqu'il est chargé dans Inkscape : c'est là que vous trouverez notamment les attributs XML qui stockent la taille de la fenêtre, le facteur de zoom et la couleur de la page. Mais avec un document Inkscape de plusieurs pages, l'élément <namedview> a gagné quelque chose d'autre : des enfants. Le développement de l'entrée <namedview> dans l'éditeur XML révèle un élément <inkscape:page …> pour chaque page de votre document. Pour clarifier, il s'agit d'éléments <page> dans l'espace de noms « inkscape », de sorte que d'autres applications - y compris votre navigateur Web - ne savent pas quoi en faire.

In this screenshot, I’ve selected the second page in the document. You can see the attributes of the <page> element in the right-hand pane. These consist of the width and height of the page, and the coordinates of the top-left corner of the page (x and y). There’s also an auto-generated ID, and an ‘inkscape:label’ attribute which holds any custom name you may have given to the page. If you’re familiar with the internals of SVG files, then you may recognise the four dimension-related attributes as being the same as those used in an SVG viewBox definition. That fact gives us our first workaround for viewing pages in a browser. When loading an SVG file into a web browser, there’s a little-known trick that can be used to override the default viewBox definition from the main <svg> element. I covered this previously in part 79 of this series (FCM issue #139), but the summary is that you can use the ‘fragment identifier’ of the file’s URL to specify the x, y, width and height values of the viewBox you wish to use. Let’s look at this with an example: first, we’ll load the SVG file directly into Firefox and, as expected, we see only the first page. To access other pages, we first need to find the coordinates (x, y) and dimensions (width, height) from the relevant <inkscape:page> element. You can see from the screenshot of the XML editor that Inkscape stores these to quite a high precision but, in practice, you can usually truncate them to just a couple of decimal places – perhaps even less if there’s a little free space between the edge of the page and the content. You then need to take these values, swap them into the following string, and append the whole thing to the URL in your web browser: #svgView(viewBox(x,y,width,height))

Dans cette capture d'écran, j'ai sélectionné la deuxième page du document. Vous pouvez voir les attributs de l'élément <page> dans le volet de droite. Il s'agit de la largeur et de la hauteur de la page, ainsi que des coordonnées du coin supérieur gauche de la page (x et y). Il y a également un identifiant auto-généré et un attribut « inkscape:label » qui contient tout nom personnalisé que vous avez pu donner à la page. Si vous êtes familier avec le fonctionnement interne des fichiers SVG, vous reconnaîtrez peut-être les quatre attributs liés aux dimensions comme étant les mêmes que ceux utilisés dans la définition d'une viewBox SVG. Ce fait nous donne notre première solution de contournement pour la visualisation des pages dans un navigateur.

Lors du chargement d'un fichier SVG dans un navigateur Web, il existe une astuce peu connue qui permet de remplacer la définition viewBox par défaut de l'élément principal <svg>. J'ai déjà abordé ce sujet dans la partie 79 de cette série (numéro 139 du FCM), mais en résumé, vous pouvez utiliser l'« identifiant de fragment » de l'URL du fichier pour spécifier les valeurs x, y, largeur et hauteur de la viewBox que vous souhaitez utiliser. Voyons cela avec un exemple : tout d'abord, nous chargeons le fichier SVG directement dans Firefox et, comme prévu, nous ne voyons que la première page.

Pour accéder aux autres pages, nous devons d'abord trouver les coordonnées (x, y) et les dimensions (largeur, hauteur) de l'élément <inkscape:page> correspondant. Vous pouvez voir sur la capture d'écran de l'éditeur XML qu'Inkscape stocke ces valeurs avec une précision assez élevée mais, en pratique, vous pouvez généralement les tronquer à quelques décimales seulement - peut-être même moins s'il y a un peu d'espace libre entre le bord de la page et le contenu. Vous devez ensuite prendre ces valeurs, les échanger contre la chaîne suivante et ajouter le tout à l'URL dans votre navigateur web :

#svgView(viewBox(x,y,width,height))

In the case of this example, the filename is ‘multi_page.svg’, and the values for the second page are shown in the earlier screenshot of the XML editor. The URL for viewing the second page therefore becomes: …/multi_page.svg#svgView(viewBox(112.6,0,102.6,102.6)) This syntax works wherever the browser expects an image URL, so web developers can also use it in <img> elements, and even in CSS url() values. It’s a clever trick, which gives you access to all the pages in a multi-page Inkscape file, but it’s not without its limitations. The biggest of these, quite clearly, is the need to dig into the SVG file to find the page size and position, then copy those values into the URL directly. The resultant link also lacks semantics – that specific combination of numbers doesn’t exactly scream ‘page 2’ to the uninitiated. However, SVG also allows us to add ‘named views’ to the file (not the same thing as the <sodipodi:namedView> element), which still requires digging out the magic numbers, but does at least allow us to map each viewBox to a more meaningful name. The downside of this approach is that we will need to edit the SVG file, either with a text editor or using Inkscape’s XML editor.

Dans le cas de cet exemple, le nom de fichier est « multi-page.svg » et les valeurs de la seconde page sont présentées dans la précédente copie d'écran de l'éditeur XML. L'URL pour voir la seconde page devient donc :

…/multi_page.svg#svgView(viewBox(112.6,0,102.6,102.6))

Cette syntaxe fonctionne partout où le navigateur s'attend à une URL d'image ; ainsi, les développeurs Web peuvent l'utiliser dans des éléments <img> et même dans des valeurs url() du CSS.

C'est une brillante astuce qui vous donne accès à toutes les pages d'un fichier Inkscape multi-page, mais elle n'est pas sans limitations. La plus importante d'entre elles, très clairement, est le besoin d'aller fouiller dans le fichier SVG pour trouver la taille et la position de la page, puis de copier ces valeurs directement dans l'URL. Le lien résultant manque de clarté - cette combinaison spécifique de nombres n'exprime pas « page 2 » au non-initié. Cependant, SVG nous permet aussi d'ajouter des « named views » (vues nommées) au fichier (rien à voir avec l'élément <sodipodi:namedView>), qui implique encore d'extraire les valeurs « magiques », mais qui nous permet au moins d'associer chaque viewBox à un nom plus significatif. Le point négatif de cette approche est que nous aurons besoin d'éditer le fichier SVG, que ce soit dans un éditeur de texte, ou dans l'éditeur XML d'Inkscape.

If you’re comfortable editing XML files in a text editor, that’s probably the easiest method. Just make sure you don’t have the file open in Inkscape at the same time, or you may find your hand-crafted edits are automatically replaced. That approach is also described in part 79 of this series, so this time I’m instead going to show you how to make the same edits within Inkscape. Once again, you’ll need the x, y, width and height parameters from the relevant <inkscape:page> element. This time, I’ll use the values for page 3 in the file. Again, these were obtained by selecting the relevant <inkscape:page> element in the XML editor, and looking at the attributes in the second pane. Once again, we’ll truncate these to 1 decimal place, giving this set of values: x: 225.3 y: 0 width: 102.6 height: 102.6 Observant readers may have noticed that only the x value has changed compared with the values for page 2. This makes sense, as the third page is the same size as the others, and has only been displaced horizontally. If your multi-page documents all use the same page size, with the pages aligned in a single row, it will always be the case that only the x value differs between them.

Si vous êtes à l'aise dans l'édition des fichiers XML, c'est probablement la méthode la plus aisée. Assurez-vous simplement que vous n'avez pas ouvert le fichier dans Inkscape en même temps ; sans quoi, vos modifications manuelles seront écrasées automatiquement. Cette approche est aussi décrite dans la partie 79 de cette série ; aussi, cette fois-ci, je vais vous montrer comme faire les même modifications dans Inkscape.

Une fois de plus, j'aurai besoin des paramètres x, y, largeur et hauteur pour l'élément <inkscape:page> correspondant. Cette fois, j'utiliserai les valeurs de la page 3 du fichier. À nouveau, elles sont accessibles en sélectionnant l'élément <inkscape:page> correspondant dans l'éditeur XML et en visualisant les attributs dans le second panneau. Et encore une fois, nous les réduirons à une seule décimale, ce qui donnera : x: 225.3 y: 0 width: 102.6 height: 102.6

Les lecteurs attentifs noterons peut-être que seule la valeur x a changé par rapport aux valeurs de la page 2. Ça se comprend, car la page trois a la même taille que les autres et qu'elle est uniquement déplacée horizontalement. Si vos documents multi-pages utilisent la même taille de page et que les pages sont sur la même ligne, seule la valeur x différera entre elles.

Now we need to create a new element in the document, which we can do via the XML editor. This can actually go anywhere in the document, and I’ve previously advocated putting it in the <defs> section – but now I’ve changed my mind. To keep similar items grouped together, I’m actually going to create it as a child of the appropriate <inkscape:page> element. To achieve this, first select the <inkscape:page> element in the left-hand pane of the XML editor. While it’s highlighted, you might want to note down those all-important dimensions that are shown in the second pane (which could actually be below rather than to the right, depending on the orientation buttons in the bottom-right of the dialog). With the existing element selected, click the first button in the dialog’s toolbar: “New element node”. This will open a much smaller dialog with a single text field and a couple of buttons, where you should enter the name (including the namespace reference) of the new element you wish to create. In this case the string to type is “svg:view” – with no spaces, and without the quotes.

Nous devons maintenant créer un nouvel élément dans le document, ce que nous pouvons faire via l'éditeur XML. Cet élément peut en fait être placé n'importe où dans le document, et j'ai précédemment préconisé de le placer dans la section <defs> - mais j'ai maintenant changé d'avis. Pour regrouper les éléments similaires, je vais le créer en tant qu'enfant de l'élément <inkscape:page> approprié. Pour ce faire, sélectionnez d'abord l'élément <inkscape:page> dans le volet gauche de l'éditeur XML. Pendant qu'il est en surbrillance, vous pouvez noter les dimensions très importantes qui sont affichées dans le deuxième volet (qui pourrait en fait être en dessous plutôt qu'à droite, selon les boutons d'orientation en bas à droite de la boîte de dialogue).

L'élément existant étant sélectionné, cliquez sur le premier bouton de la barre d'outils de la boîte de dialogue : « Nouveau nœud élément ». Cela ouvrira une boîte de dialogue beaucoup plus petite avec quelques boutons et un seul champ de texte, où vous devrez saisir le nom (y compris la référence à l'espace de noms) du nouvel élément que vous souhaitez créer. Dans ce cas, la chaîne à saisir est “svg:view” - sans espaces, ni guillemets.

Click the ‘Create’ button, and you should find your new element appears in the first pane as a child of the <inkscape:page>. It should already be selected, with no attributes present in the second pane. We will need to add two attributes to this element. Let’s start with the ‘id’, which you can create by clicking on the ‘+’ button at the top of the second pane, and entering ‘id’ into the name field that appears in the list below. When you press enter, the value field will be focused, and it’s here that you should put the more semantic name you wish to use for the page. Note that this is an XML ID, which means it can’t contain any whitespace characters – so no ‘Page 3’ for example. In practice it’s best to stick to alphanumeric characters, underscores and hyphens. The first character should be a letter, and I tend to stick to lowercase characters. In practice, therefore, something like ‘page-3’ is ideal. Now repeat the process to add a second attribute, this time with a name of ‘viewBox’ (watch the capitalization), and a value of your four values, separated by space characters, in the order ‘x y width height’. If all has gone well, the XML editor should look something like that shown below.

Cliquez sur le bouton « Créer » et vous devriez constater que votre nouvel élément apparaît dans le premier volet en tant qu'enfant de <inkscape:page>. Il devrait déjà être sélectionné, sans aucun attribut dans le second volet. Nous allons devoir ajouter deux attributs à cet élément. Commençons par l'attribut « id », que vous pouvez créer en cliquant sur le bouton « + » en haut du deuxième volet et en saisissant « id » dans le champ de nom qui apparaît dans la liste en dessous. Lorsque vous appuyez sur la touche « Entrée », le champ « Valeur » s'affiche, et c'est dans ce champ que vous devez indiquer le nom plus sémantique que vous souhaitez utiliser pour la page. Notez qu'il s'agit d'un ID XML, ce qui signifie qu'il ne peut pas contenir de caractères d'espacement - donc pas de « Page 3 » par exemple. En pratique, il est préférable de s'en tenir aux caractères alphanumériques, aux traits de soulignement et aux traits d'union. Le premier caractère doit être une lettre, et j'ai tendance à m'en tenir aux minuscules. En pratique, quelque chose comme « page-3 » est donc idéal.

Répétez le processus pour ajouter un deuxième attribut, cette fois avec un nom de « viewBox » (attention aux majuscules), et une valeur de vos quatre valeurs, séparées par des caractères d'espacement, dans l'ordre « x y largeur hauteur ». Si tout s'est bien passé, l'éditeur XML devrait ressembler à l'illustration ci-dessous.

Repeat the process for each page, using the appropriate values and different IDs before saving your file to commit the changes to disk. Then, to view a page in the browser, you simply have to use the base URL for your SVG file, and append a hash (#) followed by the ID of the page. In this example, therefore, the URL becomes ‘…/multi_page.svg#page-3’: Once again, this trick works with any place that the browser expects a URL, including <img> tags and CSS. In practice, I suggest picking better semantic IDs than simply ‘page-n’ if you possibly can. Suppose we had used ‘yellow-spiral’ as my ID in this case: if we subsequently wanted to rearrange the pages within the SVG document we would only have to update the coordinates in the <svg:view> elements, but any website that referred to the page by that ID would still work without modification.

Répétez ce processus pour chaque page, en utilisant les valeurs appropriées et des ID différents avant d'enregistrer votre fichier pour écrire vos modifications sur le disque. Ensuite, pour voir une page dans le navigateur, vous n'avez qu'à utiliser l'URL de base de votre fichier SVG en lui ajoutant un dièse (#) suivi de l'ID de la page. Ainsi, dans cet exemple, l'URL devient « …/multi_page.svg#page-3 » :

Une fois de plus, cette astuce fonctionne dans tous les cas où le navigateur attend une URL, y compris les balises <img> et le CSS. En pratique, je suggère de choisir des identifiants plus parlants que la simple « page-n » si vous le pouvez. Supposons que nous ayons utilisé « spirale-jaune » comme identifiant dans ce cas : si nous voulions par la suite réorganiser les pages dans le document SVG, nous n'aurions qu'à mettre à jour les coordonnées dans les éléments <svg:view>, mais tout site Web faisant référence à la page par cet identifiant continuerait à fonctionner sans modification.

Perhaps you can now see why I think the Inkscape developers made a mistake when implementing multi-page support. The <inkscape:page> element has attributes for an ID, an optional label (in the ‘inkscape’ namespace), and the four dimension and position values. The SVG standard <view> element, on the other hand, has an ID and a viewBox (which consists of the four dimension and position values). It’s lacking a label attribute, but this could legitimately be added within the ‘inkscape’ namespace, without breaking any XML or SVG rules. I fail to see, therefore, why the Inkscape developers chose to use a non-standard <page> element in their own namespace, rather than just use the existing SVG <view> element, adding custom attributes where required. Had they done so, every Inkscape page would automatically get a named view, and therefore be much easier to access via a web browser. Sadly, this missed opportunity leaves users either having to extract the details of each page’s viewbox in order to construct a suitable #svgView(…) fragment identifier, or manually creating their own <view> elements to achieve the same effect but with nicer URLs. Next month we’ll look at a different approach to ‘fixing’ this problem – though one that unfortunately comes with its own set of limitations.

Vous comprenez peut-être maintenant pourquoi je pense que les développeurs d'Inkscape ont fait une erreur en mettant en place le support multi-pages. L'élément <inkscape:page> possède des attributs pour un ID, un label optionnel (dans l'espace de noms « inkscape »), et les quatre valeurs de dimension et de position. L'élément SVG standard <view>, quant à lui, possède un identifiant et une boîte de visualisation (viewBox) (qui comprend les quatre valeurs de dimension et de position). Il lui manque un attribut label, mais celui-ci pourrait légitimement être ajouté dans l'espace de noms « inkscape », sans enfreindre les règles XML ou SVG. Je ne vois donc pas pourquoi les développeurs d'Inkscape ont choisi d'utiliser un élément <page> non standard dans leur propre espace de noms, plutôt que d'utiliser simplement l'élément SVG <view> existant, en ajoutant des attributs personnalisés là où c'est nécessaire. S'ils l'avaient fait, chaque page Inkscape aurait automatiquement reçu une vue nommée, et serait donc beaucoup plus facile d'accès via un navigateur Web.

Malheureusement, cette occasion manquée oblige les utilisateurs à extraire les détails de la boîte de visualisation de chaque page afin de construire un identifiant de fragment #svgView(…) approprié, ou de créer manuellement leurs propres éléments <view> pour obtenir le même effet, mais avec des URL plus jolies. Le mois prochain, nous examinerons une approche différente pour « résoudre » ce problème - bien qu'elle arrive malheureusement avec ses propres limites.

issue193/inkscape.txt · Dernière modification : 2023/05/31 15:33 de auntiee