Greboca  

Suport technique et veille technologique

Aujourd’hui, les grandes entreprises et administrations publiques hésitent entre continuer à utiliser des logiciels propriétaires ou basculer vers les Logiciels Libres. Pourtant, la plupart des logiciels libres sont capables de bien traiter les données issues des logiciels propriétaire, et parfois avec une meilleur compatibilité.

C’est alors la barrière de la prise en main qui fait peur, et pourtant...

Les logiciels libres

L’aspect « Logiciel Libre » permet une évolution rapide et une plus grande participation des utilisateurs. Les aides et tutoriels foisonnent sur Internet ou sont directement inclus dans le logiciel lui-même.

Enfin, les concepteurs sont plus proches des utilisateurs, ce qui rend les logiciels libres plus agréable à utiliser et conviviaux.

Grâce à la disponibilité des logiciels libres, vous trouverez facilement des services de support techniques et la licence n’est plus un frein à l’utilisation de ces logiciels par votre personnel.

Notre support technique concerne essentiellement les logiciels libres, que ce soit sous forme de services ponctuels ou de tutoriels.

LinuxFr.org : les journaux  -  Générer des images vectorielles procédurales avec des technologies des années 2000

 -  26 février - 

Cher nal, récemment je ré-étudiais pour la n-ième fois le problème de concevoir des schémas simplement par un langage de description graphique (je n'aime pas les éditeurs visuels) avec potentiellement une partie générée procéduralement, pour faciliter certaines constructions. J'avoue que je suis plutôt du style « à l'ancienne », donc j'ai regardé le classique tikz (vraiment trop ésotérique quand on n'est pas un habitué du Latex), xfig (j'aime bien les vieilles interfaces, mais là bof), dia (que j'ai utilisé à ses débuts, mais ici trop spécifique aux diagrammes), mais aucun ne me convenait.

Comme le média de destination de ces schémas est le Web, j'ai essayé de regarder directement le format vectoriel standard pour celui-ci : Scalable Vector Graphics, ou SVG. Je l'ai souvent vu comme un format plutôt « bas-niveau », uniquement destiné à être le format final issu de sources plus « haut-niveau ». Mais j'ai eu une expérience il y a quelques années d'écriture directe de SVG qui retranscrivait une courbe de Bézier qui m'a bien plu, au point que je me suis dit que je devrais le regarder de plus près pour voir si ça ne serait pas possible d'écrire du SVG directement pour mon besoin.

Je me suis alors penché sur la très bonne documentation de Mozilla sur SVG et ça m'a permis de me mettre le pieds à l'étrier. J'ai d'abord trouvé un petit projet d'exemple de dessiner un minuteur, avec des formes pas trop compliquée : un cercle, quelques segments, etc. Et finalement, j'ai été supris par la simplicité d'écrire directement du SVG. Mais très vite j'ai eu besoin de générer une partie de ce SVG « procéduralement » (avec des constructions de répétition propres à un langage de programmation).

Comme vous le savez, SVG est basé sur XML, la technologie des années 20001 par excellence : un langage de balisage issu de HTML et SGML qui respecte un ensemble de règles bien définies, comme le fait d'être une structure arborescente. J'ai l'habitude de travailler sur du XML avec XSLT, un langage de transformation que je trouve super utile, même si sa syntaxe horripile tout le monde, moi y compris à certains moments. J'ai essayé d'imaginer comment faire ce que je voulais avec, mais l'orientation algorithmique du problème (générer 60 marques, dont une marque plus grosse toutes les cinq marques) commençait à me faire peur, vu les limitations du langage2.

J'ai alors pensé à une vieille connaissance que j'avais utilisé il y a deux décennies, à la grande époque de Python comme langage révolutionnaire pour le Web (au début des années 20000 ; ce qui a un peu foiré) : Zope. Pas pour tout le framework ORM qui l'accompagnait, mais pour son langage de templating (patronnage ça fait bizarre en français)TAL, qui respecte les principes de XML jusqu'au bout : le langage de template n'est pas invasif et respecte la structure du document (qui reste donc un fichier XML valide) contrairement à de nombreux moteurs de template modernes qui utilisent des syntaxes qui se superposent mal à XML ; il utilise avantageusement un namespace séparé pour ne pas rendre invalide le document ; il est basé sur Python, qui est le langage que je visais tout à fait pour l'écriture de la partie procédurale.

Seul problème : je veux TAL, mais je ne veux pas le reste de Zope. Et de toutes façons, Zope n'est plus disponible sur Debian depuis des lustres. Je regarde alors les alternatives, qui sont listées sur Wikipédia.

Je vois tout d'abord Simple TAL, qui semble répondre à mes besoins : pas de dépendance, simple, stable, etc. J'essaye, et ça marche plutôt bien : ça fait étrange de retrouver la syntaxe verbeuse de TAL, mais j'aime bien, même si la gestion d'erreur très rudimentaire fait que je me retrouve parfois avec des bouts de message d'erreurs mélangés à mon contenu… Bof bof, mais ça peut passer pour des petits travaux. Ça donne ça :

 xmlns="http://www.w3.org/2000/svg" version="1.1" width="200" height="200">

 id="minutes" z="1">
 cx="100" cy="5" r="2"
    tal:repeat="angle python:[i*6 for i in range(60) if i%5]"
    tal:attributes="transform string:rotate(${angle}, 100, 100)"/>


 id="fives" z="1">
 x="98.5" y="0" width="3" height="10"
    tal:repeat="angle python:[i*30 for i in range(12)]"
    tal:attributes="transform string:rotate(${angle}, 100, 100)"/>


 id="slice" tal:define="timeangle python:int(path('time'))*6">


 
    fill="red"
    z="0"
    tal:define="
        timesegx python:100-95*math.sin(path('timeangle')/360*2*math.pi);
        timesegy python:100-95*math.cos(path('timeangle')/360*2*math.pi)"
    tal:attributes="d string:M 100 5 L 100 100 L ${timesegx} ${timesegy} A 95 95 0 0 1 100 5 Z"/>

 x="98.5" y="5" width="3" height="95" />
 x="98.5" y="5" width="3" height="95"
    tal:define="angle python:-path('timeangle')"
    tal:attributes="transform string:rotate(${angle}, 100, 100)"/>


Compte à rebours 10 minutes

Mais quelques semaines après, pour une seconde utilisation, je trouve cette approche pas encore assez à mon goût. Cette fois-ci, je veux reprendre un SVG existant, et le « génériciser ». Ce fichier c'est une représentation des flottants en informatique https://en.wikipedia.org/wiki/File:IEEE_754_Double_Floating_Point_Format.svg

Je reprends la liste des alternatives ZPT, et je regarde de plus près Chameleon (disponible sur Debian avec le package python3-chameleon) : le projet semble lié à Pyramid, un framework Web que j'aime beaucoup et que j'ai utilisé il y a dix ans, basé sur des idées vraiment bonnes selon moi (allez voir ce que font les mecs du projet Pylons pour avoir une meilleure idée). Par exemple, il parse la template en bytecode Python directement, pour éviter le jonglage avec des traductions intermédiaires de source, ça me semble bien. Il est fourni uniquement sous forme de bibliothèque, pour faciliter son intégration3.

Du coup, après avoir passé au départ un gros temps de nettoyage du SVG généré par Inkscape, je commence à tester, et ça marche vraiment bien : assez vite, j'utilise le fait que le type d'expression par défaut est Python, et non les chemins d'objet ZPT (qui sont bien adaptés pour l'ORM de Zope, mais moins quand on a un code Python simple à 100%), ce qui simplifie beaucoup le code. Puis je remplace les très XML-èsque tal:attributes (qui me rappellent les xsl:attribute) par l'utilisation de l'insertion de texte directe sur des attributs, qui sont donc littéralement écrits avec comme valeur une expression utilisant la syntaxe ${…}, issue de Genshi. Elle remplacera même plus tard même les tal:replace ou tal:content pour les contenus d'élément texte. Certes, on se rapproche ainsi plus des moteurs de template classiques, mais ça ne casse au moins pas la structure, qui serait plus amochée si je n'utilisais pas les tal:repeat, ou la définition de variables utiles avec tal:define.

J'ai au début uniquement programmé la répétition des barres de l'image, puis des points sous la barre. Puis je suis allé encore plus loin pour ce cas précis de flottant en informatique, en généricisant pour n'importe quelle taille d'exposant ou de fraction. Enfin j'ai rendu dynamique le positionnement du texte au-dessus, ce qui me permet au passage de le passer en français. Et au final, ça donne ça :

<?xml version="1.0" encoding="UTF-8"?>


<?python
def nbars(n):
    "Size of `n` bars."
    return n * 9
?>
 xmlns="http://www.w3.org/2000/svg"
    xmlns:tal="http://xml.zope.org/namespaces/tal"
    tal:define="exponent int(exponent); fraction int(fraction); start 28"
    width="${ start + nbars(1 + exponent + fraction + 1) }" height="100">
  
     id="bar" width="${nbars(1)}" height="28"/>
  
  
    #bar    { stroke: black; }
    .above  { stroke: black; fill: none; }
    text    { font-size: 12px; text-align: center; text-anchor: middle; font-family: sans }
    circle  { stroke: black; fill: black; fill-opacity: 0.25; }
  
  
    
     href="#bar" tal:repeat="i range(1)"
        style="fill:#d5ffff" x="${ start + nbars(i) }" y="44"/>
     href="#bar" tal:repeat="i range(1, 1+exponent)"
        style="fill:#a4ffb4" x="${ start + nbars(i) }" y="44"/>
     href="#bar" tal:repeat="i range(1+exponent, 1+exponent+fraction)"
        style="fill:#ffb2b4" x="${ start + nbars(i) }" y="44"/>

    
     tal:define="x start + nbars(0 + 1/2)">
       style="text-anchor: end">
     x="${ x + 2 }" y="25" >signe
      
       class="above" d="M ${x},31.5 L ${x},41.5"/>
    

    
     tal:define="x start + nbars(1 + exponent/2)">
       x="${x}" y="12.5" >exposant
       x="${x}" y="25" >(${exponent} bits)
    
     tal:define="x1 start + nbars(1); x2 start + nbars(1 + exponent)"
        class="above" d="M ${x2-1},41.5 L ${x2-1},31.5 L ${x1},31.5 L ${x1},41.5"/>

    
     tal:define="x start + nbars(1 + exponent + fraction/2)">
       x="${x}" y="12.5">fraction
       x="${x}" y="25" >(${fraction} bits)
    
     tal:define="x1 start + nbars(1 + exponent); x2 start + nbars(1 + exponent + fraction)"
        class="above" d="M ${x2},41.5 L ${x2},31.5 L ${x1+1},31.5 L ${x1+1},41.5"/>

    
     tal:repeat="b (0, fraction, fraction+exponent)">
       tal:omit-tag="" tal:define="x start + nbars(1/2+exponent+fraction - b)">
     cx="${x}" cy="79" r="3.7"/>
     x="${x}" y="93">${b}
      
    
  

Et je suis vraiment content du résultat. C'est plutôt propre, relativement conforme à ce qu'on attend d'un XML, au point où j'imagine même une chaîne de traitement qui pourrait combiner TAL et XSLT ! Ah, et pour voir le résultat, sur un double par exemple :

Flottant à double précision

Le seul bémol par rapport à la « standardicité » de ce template utilisant TAL, c'est que Chameleon ré-utilise l'espace de nommage (namespace) original de Zope alors qu'ils ont en fait étendu le dialecte pour l'insertion directe par exemple, ou le fait que les expressions soient en Python par défaut (il y a d'autres nouveautés également). Dans un soucis de compatibilité ascendante, idéalement, ils auraient dû définir un nouveau namespace pour ces extensions4.

Mais justement, rien que le fait d'utiliser un namespace pour intégrer de la « procéduralité » dans un SVG va permettre de montrer une possibilité géniale de XML : de pouvoir être une structure de données mélangeant divers aspects de manière non-intrusive (ou orthogonale), ce qui permet par exemple dans notre cas de modifier le SVG avec Inkscape par exemple, et de continuer à obtenir un template valide ! Ça fonctionne moyennement avec le template ci-dessus, car le dessin ne ressemble à rien vu que par exemple les coordonnées des objets n'ont pas de valeur correcte : on utilise l'insertion directe avec des ${x} par exemple, qui n'est pas une coordonnée valide. C'est pour ce cas où rester avec la syntaxe strictement XML d'origine de TAL peut être utile : ces attributs auront une valeur qui est utile pour présenter ce dessin dans un logiciel d'édition de SVG comme Inkscape, mais seront remplacés lors de l'instanciation du template par TAL ! Essayez avec cette version du dessin, vous verrez que le template continue d'être utilisable et applique les modifications que vous y avez effectué.

Et ça c'est la puissance de XML qui n'a malheureusement jamais été beaucoup développée : pouvoir intégrer plusieurs dialectes ou formats (avec son propre namespace) au sein d'un même fichier pour qu'il soit « multiforme ». J'avais il y a quelques années ainsi intégré une extension à un diagramme à état en SCXML qui me permettait de travailler sur un aspect orthogonal au diagramme, en utilisant au passage un namespace que j'avais créé pour l'occasion en utilisant les Tag URI. Vous voyez d'ailleurs qu'Inkscape intègre lui-même ses propres données au fichier SVG standard à travers le namespace souvent préfixé « sodipodi » (le nom d'origine du projet) pour y stocker ses paramètres. Dans un autre contexte, RDFa est une manière d'étendre le HTML pour faire du RDF, en trouvant un entre-deux n'utilisant que des attributs préfixés et non pas des éléments spécifiques, afin de concilier le divorce du HTML moderne avec XML (mais faites du XHTML5 même s'il n'a pas de schéma !).

Bref, j'espère que ce journal t'auras un peu réconcilié avec XML, et puis donné envie de lier Python et XML pour ton prochain projet. Tu trouveras tous les fichiers de mon expérimentation ici : http://dolka.fr/bazar/tal-svg-experiment/


  1. j'ai toujours trouvé ça étrange mais quand on dit « les années XXXX », on parle de la dizaine d'année qui commence par l'année citée ; dans notre cas, les années 2000--2010. 

  2. en fait, XSLT n'est vraiment pas fait pour de la génération procédurale, mais pour du traitement de données en flux. Il est idéal pour transformer un document en un autre, mais laissez tomber dès que la part de calcul devient trop importante. À la limite, vous pouvez partir d'un programme dans un langage classique pour la partie calcul, et sortir un document « de base » –  en utilisant même des printf() à la barbare avec une structure simple  – à transformer plus aval par XSLT. Mais n'essayez pas de tout faire en XSLT. 

  3. du coup Chameleon étant une bibliothèque seulement, j'ai créé un petit outil talproc pour traiter les templates TAL. Il s'utilise à la manière de xsltproc avec les paramètres du template passés en --stringparam. Par exemple, pour générer le fichier du flottant double précision : talproc --stringparam exponent 11 --stringparam fraction 52 IEEE_754_Floating_Point_Format-direct-template.svg 

  4. pour troller, je voudrais signaler que Microsoft, pourtant habitué au EEE, a correctement namespacé ses extensions à OOXML et continue de le faire des années après, cf. https://learn.microsoft.com/en-us/openspecs/office_standards/ms-docx/d0a2e301-0ff7-4e9e-9bb7-ff47070dce0a issu de https://learn.microsoft.com/en-us/openspecs/office_standards/ms-docx/b839fe1f-e1ca-4fa6-8c26-5954d0abbccd. Après, vous pourrez arguer qu'avoir un « standard » qui continue d'avoir des extensions (à l'utilité discutable, si vous regardez le contenu précisément) tous les deux ans, ça n'est pas vraiment une forme de stabilité qui lui confèrerait un caractère si « standard », mais bon… 

Commentaires : voir le flux Atom ouvrir dans le navigateur

par benoar

LinuxFr.org : les journaux

LinuxFr.org : Journaux

antistress adventure in Flatpak land

 -  30 avril - 

Hello nal, ça faisait un bail !Certain (il se reconnaîtra) m'a demandé de le tenir au courant lorsque j'aurai basculé sur un usage de Firefox (...)


Téléphone sous Linux ?

 -  25 avril - 

Aujourd'hui, avoir un téléphone avec un Android libéré, c'est possible, on pense en particulier à Murena.Avoir un téléphone sous GNU/Linux, c'est (...)


Quand votre voiture vous espionne… et vous le fait payer

 -  23 avril - 

Ceci se passe aux États-Unis, pour l’instant, aucune preuve qu’une telle fuite existe en Europe. Mais… si votre assurance augmente brutalement, (...)


firefox, nouvelle fenêtre dans une session isolée

 -  15 avril - 

Les fenêtres de navigation privées de firefox partagent leurs cookies de session or je souhaitais avoir des fenêtres de navigation isolées, (qui ne (...)


Pretendo tente de déprogrammer l'obsolescence des consoles Nintendo

 -  9 avril - 

Ah Nal,Gros N vient de faire un gros doigt aux utilisateurs de ses consoles 3DS et Wii U en annonçant la fermeture des services en ligne pour (...)