Accueil  

 

  Présentation  

 

  Téléchargement  

 

  Changelog  

 

  Comprendre PML  

 

  Affichage du code PML  

 

Pour le corps du document :

  Affichage du code PML  

 

  Contact  

PERSONNALISABLE MARKUP LANGUAGE

DOCUMENTATION

 

version 0.8.2 – 27 novembre 2017

Sommaire

Avertissement

Préambule

1. Présentation générale

2. Un langage plus simple mais plus strict

3. Les métabalises

4. Cas particuliers et spécificités

5. Balises de pré-traitement

6. Les outils

7. L’utilitaire pml

8. Gestion de bases de données MySql ou MariaDB : PyMyAdmin

Avertissement

L’outil ici présenté n’est encore qu’en phase de mise au point. Il est donc incomplet et présente forcément des bogues.

Pour ceux qui se plongeront dans le code source, le programme de conversion HTML→ePub est à ce jour une transposition/adaptation en Python d’un module initialement développé en PHP et ajusté au fil des ans. C’est donc encore un sac de nœuds dont j’ai bien conscience qu’il devrait être entièrement réécrit.

 

L’ensemble du pack proposé est offert en toute liberté. Chacun peut y apporter des modifications et corrections ainsi que le diffuser librement. Je demande juste à ce que me soient communiquées les modifications et corrections qu’il aura apportées (courriel : jean-luc@blary.eu) afin que le plus grand nombre puisse en profiter.

Tout contributeur sera naturellement crédité de ses interventions dans les évolutions du produit.

Préambule

PML est né de l’idée qu’on pouvait à la fois rendre les documents HTML plus simples, plus lisibles et plus puissants.

☑ Plus simples, parce qu’en remplaçant le système de balises ouvrantes et fermantes par des balises englobantes, on réduit l’encombrement de celles-ci.

☑ Plus lisibles, parce que grâce à la réduction de l’encombrement des balises et à un système de métabalises, on se rapproche du texte natif.

☑ Plus puissants, parce qu’on peut, grâce aux métabalises, utiliser des commandes plus courtes qui en font davantage.

 

Tout fichier HTML est directement convertible en PML et vice-versa.

 

PML est constitué de plusieurs modules distincts :

 

A. Un module de conversion PML ↔ HTML, principalement orienté documents statiques (sites ou parties de site Internet non évolutifs, ePub…) et simplement formé de deux programmes écrits en python 3 :

• pmlimport pour convertir un fichier HTML en PML ;

• pmlexport qui convertit un fichier PML en HTML.

Plus un troisième module, réservé à la création de livres numériques :

• htmlepub qui convertit un fichier HTML en un ePub (ePub2 ou ePub3).

 

B. Un module de gestion des documents PML en tant que pages internet. Il permet de s’affranchir complètement du HTML et de créer ses pages directement en PML, avec l’avantage en plus de la possibilité d’appeler des routines en Python pour compléter les pages, remplaçant là PHP et Python « pur » (ainsi que ASP/IIS sur les serveurs Windows puisque PML est multiplateformes).

 

C. Un outil de gestion de bases de données, pymyadmin, qui doit remplacer avantageusement phpmyadmin (car plus léger et plus performant, notamment grâce à beaucoup moins de javascript) pour l’écrasante majorité des fonctionnalités réellement utiles. (Développement en cours.)

 

D. En principe, il y aura aussi un CMS (Content Management System ou Système de Gestion de Contenu) destiné à mettre en œuvre et gérer des sites Internet complets. Également écrit en python 3, il est entièrement interfacé en mode navigateur et stocke la quasi-totalité des données dans une base MySQL ou compatible (ex. MariaDB). Toutefois, il est possible que j’abandonne cette voie (même si l’outil existe et est opérationnel, nécessitant toutefois encore pas mal de tests et débogage), le module pml mentionné en B. ci-dessus étant extrêmement prometteur et beaucoup plus simple.

 

Les premiers chapitres de cette documentation décrivent le principe du « langage » PML. Les autres modules sont (ou seront) détaillés dans les chapitres suivants.

1. Présentation générale

Le principe de base de PML consiste à remplacer le groupe

<balise>texte</balise>

par

<balise texte>

le texte pouvant lui-même contenir des balises.

 

Exemple 1 :

Ce tableau basique de 2 lignes de 2 colonnes s’écrit en HTML :

<table><tr><td>A1</td><td>B1</td></tr><tr><td>A2</td><td>B2</td></tr></table>

En PML, il devient :

<table <tr <td A1><td B1>><tr <td A2><td B2>>>

N’est-ce pas plus court et sensiblement plus lisible ?

 

Exemple 2 :

Ce titre de chapitre s’écrit en HTML :

<h1>Chapitre III</h1>

Grâce aux métabalises, il peut devenir en PML :

<chapitre III>

Difficile de faire plus court et plus lisible, non ?

 

« Mais que fait-on des classes et autres attributs ? », me direz-vous…

Eh bien, le format général d’une balise PML (sauf balises contenant impérativement un lien, détaillés dans le chapitre Cas particuliers) est le suivant :

<balise[.classe][#id][ #attr1=valeur][ #attr2=valeur] texte>

Important : l’attribut ‘#id’ ne doit pas être précédé d’un espace, il doit être collé à la classe (ou au nom de la balise).

Ce qui correspond, en HTML, à :

<balise[ class="classe"][ id="id"][ attr1=valeur][ attr2=valeur]>texte</balise>

 

Toutefois, sachant que HTML évolue vers le déplacement de tous les attributs (ou presque) vers les feuilles de style CSS, au point que beaucoup ont déjà été dépréciés en HTML4 et sont devenus invalides en HTML5, PML va dans le même sens et il est évidemment recommandé de faire le maximum en CSS.

S’il est toujours possible de déporter des attributs dans les métabalises, car cela simplifie tout autant le code PML, il faut savoir qu’en pareil cas ils sont répétés dans le HTML final autant de fois qu’est utilisée la métabalise. Néanmoins cela peut être utile en cas d’attributs susceptibles d’être souvent modifiés ou avec des métabalises ayant peu d’occurrences.

 

« Même celles qui ne servent qu’une fois ? »

Et pourquoi pas ? C’est d’ailleurs ce qui se passe depuis longtemps dans les documents aux formats .odt ou .docx – sauf que, évidemment, l’utilisateur ne le voit pas.

 

Note importante :

PML simplifie l’écriture de code HTML, mais ne s’occupe que de la syntaxe et non de la grammaire. S’il veille tout de même à vérifier l’existence des classes utilisées, il ne bronchera pas sur un <td texte> non inclus dans un <tr> ou carrément hors d’une table. Il restera tout aussi indifférent à un attribut numérique alimenté avec du texte ou vice-versa.

Il construit un document HTML bétonné question syntaxe, mais le reste est le problème du navigateur qui l’interprétera pour l’afficher… et surtout de la personne qui code les pages !

2. Un langage plus simple mais plus strict

2.1. Notes aux utilisateurs Windows

1. Pour utiliser PML, il est impératif que les fichiers soient en Unicode (UTF-8) et non en ISO-8859 ou (pire) en CP1252. (Sous Linux et sur Mac, Unicode est le codage standard par défaut.)

2. Les programmes de conversion de/vers HTML étant en Python3, il est nécessaire d’installer Python pour pouvoir les utiliser. (Python est installé par défaut sous Linux et Mac. Il peut toutefois être nécessaire d’installer une version 3 si celle en place est antérieure.)

2.2. Caractères spéciaux

En PML, grâce à Unicode, il n’est nul besoin d’utiliser les codes en &xxx;, tous les caractères peuvent être entrés nativement. Néanmoins, les codes &xxx; ne sont pas refusés, ceux présents seront juste convertis (sauf s’ils correspondent aux délimiteurs de base HTML « < », « > » ou « & »).

Nota : contrairement à la tolérance de HTML5, les caractères spéciaux non délimités à droite par un ’;’ ne sont pas reconnus comme tels : ‘&quota’ ne générera pas ‘"a’, mais restera ‘&quota’.

Il n’existe que peu de caractères spéciaux interprétés par PML. L’important est de savoir que tout caractère susceptible d’être vu comme marqueur ou délimiteur alors qu’il s’agit de texte doit être « échappé », c’est-à-dire précédé du caractère « \ ».

Ainsi, « \< » ne sera pas un début de balise, mais simplement le caractère « plus grand ». Bien sûr, si on veut insérer un « \ » dans le texte, il faudra le doubler, sinon il sera traité comme échappement de celui qui le suit.

À noter qu’un caractère échappé inutilement ne prête pas à conséquence, il reste simplement lui-même. Et comme on a affaire à du texte pur (ce sont les balises qui font la mise en forme), « \t » donnera un « t » et non une tabulation, « \n » sera un « n » et non une fin de ligne, etc.

2.3. Règle de base

La règle de départ PML est qu’une balise doit être contenue en entier sur une seule ligne. De cette manière, le contrôle syntaxique détecte immédiatement s’il y a le bon nombre de délimiteurs « < » et « > ».

 

« Que se passe-t-il si les délimiteurs ne sont pas équilibrés ? »

Cela dépend dans quel sens :

– S’il manque des fermetures, le programme de conversion émet un avertissement et ajoute les fermetures manquantes, de sorte que le code HTML obtenu est syntaxiquement propre – même si les fermetures ne sont pas nécessairement là où elles auraient dû.

– S’il y a trop de fermetures, les « > » excédentaires sont traités comme des caractères ordinaires et seront convertis en « > » dans le code HTML résultant. Là aussi, évidemment, il y a émission d’un avertissement.

 

Globalement, le premier caractère d’une ligne non vide ou contenant autre chose que des espaces (ces lignes-là sont autorisées, mais ignorées) peut être :

< : début de balise ;

 : (tabulation), continuation de balise ;

# : commentaire (cf. plus loin) ;

§ : définition de métabalise (cf. plus loin).

Tout autre caractère est une erreur.

2.4. Balises longues

Naturellement, il est fréquent qu’une balise HTML encadre un peu trop d’informations pour tenir confortablement sur une seule ligne, ou que (notamment pour les tableaux) la lisibilité impose un découpage en plusieurs lignes.

C’est évidemment possible tout en respectant le principe précédent, et ce très simplement en faisant appel à la même règle que celle qui gère les blocs en langage Python : l’indentation.

 

Par exemple, le tableau de la page 2 peut s’écrire en HTML :

<table>
→<tr>
→→<td>A1</td>
→→<td>B1</td>
→</tr>
→<tr>
→→<td>A2</td>
→→<td>B2</td>
→</tr>
</table>

Évidemment, les indentations (ou les espaces) ne servent ici qu’à la lisibilité et ne jouent aucun rôle par ailleurs : le tableau s’affichera exactement de la même façon si on écrit ceci :

<table>
<tr>
<td>A1</td>
<td>B1</td>
</tr>
<tr>
<td>A2</td>
<td>B2</td>
</tr>
</table>

 

En PML, le caractère d’indentation joue un rôle fondamental. Sa présence au début d’une ligne signale au convertisseur que la ligne précédente n’est pas complète et qu’il s’en faut d’autant de fermetures qu’il y a de tabulations.

On peut donc écrire la table ainsi :

<table
→<tr
→→<td A1>
→→<td B1>>
→<tr
→→<td A2>
→→<td B2>>>

S’il manque des fermetures, il y aura avertissement(s), mais le code HTML généré sera néanmoins correct.

En revanche, si on code :

<table
<tr
<td A1>
<td B1>>
<tr
<td A2>
<td B2>>>

… le résultat HTML sera celui-ci :

<table />
<tr />
<td>A1</td>
<td>B1</td>>
<tr />
<td>A2</td>
<td>B2</td>>>

… avec pas moins de 5 avertissements !

 

Attention : si on veut carrément séparer les délimiteurs fermants, il faut écrire :

→<tr
→→<td A1>
→→<td B1>
→→>

et non

→<tr
→→<td A1>
→→<td B1>
→>

qui donnerait

→<tr>
→→<td>A1</td>
→→<td>B1</td></tr>
→>

… avec un avertissement. En effet, le délimiteur fermant fait partie de la « ligne » commençant par « <tr » et doit donc être indenté par rapport à ce début pour être considéré comme en faisant partie.

 

Arrivé ici, je vous entends déjà penser : « Et si on met plus de tabulations que nécessaire ? »

Eh bien, dans ce sens-là, pas de problème : les tabulations excédentaires sont purement et simplement ignorées.

 

Pour info, le code HTML généré conserve les tabulations utiles, préservant donc la lisibilité.

 

Important : si on veut un retour à la ligne (pour lisibilité) sans que celui-ci soit assimilable à un espace syntaxique (ex. dans un attribut « style » un peu long), il faut terminer la ligne par un ‘\’ accolé au dernier caractère. Ex. :

< div #style=position:absolute;left:200px;top:100px;display:table;
→width:100px;height:100px;margin:auto;text-align:center texte-du-div>

générera le code html erroné (bien que syntaxiquement valide) :

<div style="position:absolute;left:200px;top:100px;display:table;">
→width:100px;height:100px;margin:auto;text-align:center texte…</div>

tandis que :

<div #style=position:absolute;left:200px;top:100px;display:table;\
→width:100px;height:100px;margin:auto;text-align:center texte-du-div>

générera correctement :

<div style="position:absolute;left:200px;top:100px;display:table;
→width:100px;height:100px;margin:auto;text-align:center">texte…</div>

Pour info, c’est le même principe que dans le langage Python.

2.5. Texte pur

Il peut arriver que certaines parties ne doivent surtout pas être décodées ni altérées (ex. du javascript pouvant contenir des caractères spéciaux PML qui ne sont pas à prendre en compte comme tels). Il suffit alors de les placer entre triples « apostrophes ». Ex :

(<script '''…'''>)

Remarque : Cela peut également être utile pour définir des attributs dont la chaîne contient des espaces, il est ainsi inutile des les échapper.

 

Attention : Si dans ce texte pur il y a des paramètres (<*…>), constantes (<%…>) ou littéraux (<@…>) qui doivent être résolus, il suffit de les « sortir » du mode texte pur en les encadrant par des triples « apostrophes ».

Exemples (javascript) :

'''doc.balise.balisecode.value = "<%titre>";'''

… enverra la valeur <%titre> telle quelle. Tandis que :

'''doc.balise.balisecode.value = "'''<%titre>'''";'''

… enverra correctement la valeur de la constante.

2.6. Commentaires

Il est évidemment possible d’incorporer des commentaires pour une meilleure compréhension du texte.

Il suffit que la ligne commence par un « # » :

#commentaire

Mais par défaut ce commentaire ne sera pas repris dans le code HTML généré (notamment afin d’alléger celui-ci au maximum).

Si on veut qu’il soit répercuté, il faut alors doubler le caractère initial :

##commentaire

… apparaîtra dans le HTML généré comme :

<!-- commentaire -->

 

On peut aussi mettre des commentaires dans le corps d’une balise :

<balise … <#commentaire> …>

De même, le commentaire ne sera maintenu que s’il commence avec un double « # ».

 

Note : le commentaire commence immédiatement après le # ou ##, il peut donc indifféremment y avoir ou non un espace de séparation.

Un commentaire peut s’étendre sur plusieurs lignes, à condition de respecter l’indentation par tabulation. En outre, s’il contient des balises, celles-ci seront identifiées mais ignorées. De sorte qu’il suffit de mettre un « # » comme premier caractère d’une balise pour que celle-ci soit entièrement ignorée avec tout ce qu’elle contient.

Si une séquence « -- » figure dans un commentaire (ce qui est interdit en HTML puisque délimiteur de commentaire), elle sera remplacée dans un commentaire à répercuter par un tiret semi-cadratin « – ».

2.7. Spécificités diverses et précisions

Afin que le code HTML généré soit optimisé, il y a deux traitements différents pour les balises vides :

1. Les balises ne servant qu’à mettre le texte en forme sont ignorées en l’absence dudit texte (c’est-à-dire ne contenant ni lettres ni chiffres), avec émission d’un message d’avertissement. C’est le cas de <i>, <b>, <s>, <em>, <strong>, etc. et en général de tout ce qui est définissable par <span …>. Si nécessaire, accoler un ‘+’ de forçage à la balise afin qu’elle soit prise en compte (ex. <sup+ , > pour mettre une virgule entre deux appels de note consécutifs).

2. Les balises jouant un rôle dans la mise en page sont préservées : un paragraphe vide ne disparaîtra pas.

3. Il y a également vérification des id : seuls les identifiants référencés ailleurs dans le document (liens) sont conservés dans le code HTML générés. En outre, les id référencés mais non définis donnent lieu à avertissement (et sont également supprimés).

4. Les balises de plus haut niveau <html>, <head> et <body> étant générées systématiquement, elles ne sont pas acceptées dans un document PML.

3. Les métabalises

3.1. Principe

Les métabalises complètent et enrichissent le principe des feuilles de style. Dans un document PML, on peut les définir, comme les styles CSS, de deux façons différentes :

 

1. Dans un ou plusieurs fichiers de métabalises qu’on spécifie dans la première ligne du document, laquelle se présente comme ceci :

<pml[ balises.pss[ balises2.pss[…]]]>

(les noms des fichiers peuvent être quelconques et même contenir un chemin, il faut juste qu’ils soient suffixés par « .pss »)

 

2. Directement dans le document, à la suite de la première ligne ci-dessus :

<pml>
§balise <code…>

 

Les deux méthodes sont cumulables, sachant qu’en cas d’identité de métabalise, celle définie en dernier (ordre des fichiers puis directement dans le document) est prioritaire.

En outre, s’il existe un fichier ‘pmlexport.pss’ dans le répertoire du programme ‘pmlexport.py’, il est pris en compte en tout premier. C’est un moyen de définir des métabalises généralisées.

Attention : contrairement aux autres balises, l’ensemble de <pml…> doit figurer sur une seule ligne (pas de retour même avec une tabulation) !

 

Qu’elle soit dans un fichier séparé ou directement dans le document, une métabalise se présente comme suit :

§balise <code équivalent>

Si sa définition est longue, elle peut être répartie sur plusieurs lignes, les suivantes étant obligatoirement indentées d’un cran (la tabulation compte comme un espace – si le retour ligne n’achève pas l’élément par l’équivalent d’un espace, il faut échapper ce retour par un ‘\’ en fin de ligne, ce qui sera interprété par un espace non délimiteur).

 

Exemple :

Si on a des styles CSS du genre :

span.rouge {color:red}
span.bleu {color:blue}
span.vert {color:red}

… on peut définir une balise spécifique à chaque couleur :

§rouge <span class="rouge">

Et mettre un bout de texte en rouge en devient d’une simplicité presque déconcertante :

<rouge texte>

On peut même aller plus loin :

§rougegras <rouge style="text-weight:bold">

Ou encore, si on a défini une classe .gras {text-weight:bold}, on peut écrire :

<rouge.gras texte>

… qui correspondra en HTML à :

<span class="rouge gras">texte</span>

Eh oui, les métabalises sont elles-mêmes redéfinissables.

 

On pourrait aussi définir la balise « rouge » sans passer par CSS en la définissant comme ceci :

§rouge <span style="color:red">

… mais dans ce cas le code HTML généré sera :

<span style"color:red">texte</span>

Donc valable pour des styles et attributs à usage unique ou presque, mais déconseillé là où les classes ont leur utilité. Éviter donc de définir une métabalise pour une balise contenant des attributs non paramétrés (sauf, éventuellement et temporairement, pour faciliter la mise au point), une définition en feuille de style est largement préférable.

 

Pour aller encore plus loin, une métabalise peut même contenir du texte prédéfini.

 

Exemple du chapitre donné en page 2 :

§chapitre <h1 Chapitre>

Le texte associé à la balise dans le code normal PML se place par défaut après celui incorporé dans la définition, séparé par une espace. Il est cependant possible de le positionner avant ou dedans, en spécifiant <*> dans cet attribut.

 

Exemple : avec les métabalises

§partie <h1 class="partie" <*> partie>
§re <sup re>

… le bref texte

<partie 1<re>>

sera converti comme

<h1 class="partie">1<sup>re</sup> partie</h1>

 

Important : tous les attributs d’une balise HTML peuvent être utilisés tels quels dans la définition d’une balise. Mais le premier élément qui ne serait pas de la forme xxxx="yyy" sera identifié comme début du texte ordinaire.

 

Note : certaines balises particulières (comme img ou a explicitées plus loin) peuvent avoir un (et un seul) attribut obligatoire qui alors peut être entré sans mot-clé (ex. #image.jpg), mais doit obligatoirement venir en première position (voir plus bas).

 

Remarque : comme vous l’avez constaté, le nom d’une balise peut contenir des caractères accentués. Mais seuls sont autorisés chiffres, lettres et le « souligné » (« _ »), le premier caractère ne pouvant être un chiffre.

Par défaut, le texte ajouté lors de l’usage d’une métabalise sera séparé du texte pouvant y figurer par une espace. S’il doit au contraire être accolé, l’emplacement du texte doit être explicité avec un ‘<*>’.

Attention :

a. Si une espace, insécable ou ordinaire, est déjà présente en fin de texte dans la métabalise, aucune espace supplémentaire n’est ajoutée.

b. Si aucun texte n’est à ajouter, seules les espaces explicitement mises dans la métabalise sont conservées.

 

Enfin, la combinaison de classes reste possible :

<balise.a+b#c texte>

… générera

<balise class="a b" id="c">texte</balise>

Le signe « + » remplace l’espace uniquement dans ce cas. Il n’a aucun autre usage particulier en PML, à l’exception de forcer la validation d’une balise qui serait autrement ignorée car identifiée comme inutile (« <i ,> » deviendra « , », mais « <i+ ,> » deviendra « <i>,</i> »).

3.2. Les paramètres

On peut bien sûr se passer de style CSS en utilisant le mode paramètre (valeurs précédées d’un #) :

§c <span style="color:<*1>">

et définir n’importe quelle couleur ainsi :

<c #red texte>

ou

<c ##ff0000 texte>

Évidement, en l’absence de style CSS, la spécification de couleur est répétée dans le document HTML avec le code généré :

<span style="color:#ff0000">texte</span>

Vous remarquerez qu’on a séparé le nom de la métabalise de la valeur non par un point mais par un espace. C’est ce qui permet à PML de savoir qu’on n’a plus affaire à une classe ou un identifiant, mais à un ou plusieurs paramètres.

Par exemple, si on a besoin de définir différents blocs div identiques sauf leur position, celle de chacun étant unique, on peut utiliser la définition suivante :

§pavé <div #style=position:absolute;left:<*1>px;top:<*2>px;display:table;\
→→width:100px;height:100px;margin:auto;text-align:center>

(Vous noterez la présence d’un échappement et de deux indentations : en effet, ‘\’ indique qu’on reste dans ‘style’ et pour les indentations, il en faut une pour indiquer qu’on poursuit la définition de « pavé » et une autre pour indiquer qu’on est toujours dans « div ».)

Chaque bloc pourra alors être défini dans le corps du document comme suit :

<pavé #100 #200 texte>

Autre méthode, plus conviviale :

§pavé <div #style=position:absolute;left:<*x>px;top:<*y>px;display:table;
→→width:100px;height:100px;margin:auto;text-align:center>

… permet d’écrire :

<pavé #x=100 #y=200 texte>

 

La première manière (<*1>, <*2>) donne les paramètres dans l’ordre où ils doivent être fournis, tous étant impératifs (il est toutefois possible de passer un paramètre « nul » en mettant un « # » isolé au bon emplacement dans la liste. Attention : la valeur <*0> ne doit pas être utilisée, elle est « réservée » et ne concerne que les définitions implicites.

La deuxième manière (<*x>, <*y> associe des noms aux paramètres, ce qui permet de les donner dans un ordre quelconque… et surtout de voir immédiatement leur signification. L’astérisque devant le nom indique qu’on a affaire à un paramètre et non à une (méta)balise.

Plus encore, il est possible de donner une valeur par défaut à chaque paramètre :

§pavé <div style=position:absolute;left:<*x=0>px;top:<*y=0>px;display:table;
→→width:100px;height:100px;margin:auto;text-align:center>

… permet d’écrire :

<pavé #y=200 texte>

… qui aura donc les coordonnées x=0 (valeur par défaut) et y=200, un paramètre ayant une valeur par défaut devenant facultatif.

 

Attention : une valeur de paramètre étant une chaîne de caractères susceptible de contenir n’importe quoi, il faut veiller à échapper tout caractère « ambigu » tel qu’un espace.

En résumé, une « balise » commençant par « * » dans une définition de métabalise définit un paramètre ; un « mot » commençant par « # » dans une balise est une valeur de paramètre.

PML considère la liste des paramètres terminée au premier mot ne commençant pas par « # ». Si par hasard le premier mot non paramètre doit commencer par ce caractère, il suffit de l’échapper (« \# »), faute de quoi il sera soit pris comme paramètre suivant (si la liste était incomplète), soit ignoré (paramètre en trop).

 

Les paramètres positionnels et par mots-clés sont cumulables, mais les premiers doivent tous être précisés AVANT les seconds.

 

Si des paramètres positionnels en trop sont fournis, ils sont juste ignorés, avec émission d’un message d’avertissement.

Si des paramètres nommés mais non définis sont fournis, ils sont traités comme des attributs HTML :

<balise #size=100 texte>

donnera

<balise size="100">texte</balise>

 

Le paramètre simplement défini par <*> est exclusivement réservé au texte associé à la (méta)balise. On peut d’ailleurs considérer qu’il y a « <*> » implicite en fin de définition quand il n’est pas explicite à un autre emplacement.

 

Rappel : les exemples « div » ci-dessus ne sont naturellement pas recommandés tels quels car générant des « div » à rallonge. Les classes « css » sont là pour stocker les attributs de valeurs communes.

 

Enfin, il est possible de conditionner le « conteneur » d’un paramètre à l’existence de celui-ci (sachant qu’un paramètre avec valeur existera toujours), il suffit de placer la partie conditionnelle dans une balise avec « ** ».

Si aucun paramètre ne figure dans une balise conditionnelle, celle-ci est systématiquement traitée comme si elle avait un paramètre renseigné.

 

Attention : si une balise conditionnelle contient plusieurs paramètres, il suffit qu’un seul ne soit pas renseigné pour que l’ensemble soit éliminé.

 

Exemple :

§image <img #style=<** width:<*l>;><** height:<*h>;>>

Si on écrit ceci :

<image #xxxxx.jpg #h=100px>

… le code HTML sera le suivant :

<img src="xxxxx.jpg" style="height:100px;" />

(Si aucun paramètre n’est spécifié, PML détectera le « style » vide et l’éliminera complètement.)

3.3. Les balises « maison » et blocs

Pour améliorer et « bétonner » certains documents, il est possible de définir des métabalises ne correspondant à aucun balisage HTML. La pseudobalise à utiliser est un « § » seul.

Par exemple :

§question <p — <*> ?>
§guil <§ « <*> »>

remplaceront :

<question Vous avez dit <guil Bizarre>>

par :

<p>— Vous avez dit « Bizarre » ?</p>

L’intérêt ? Eh bien, si vous devez pour une raison ou une autre changer le mode de mise entre guillemets dans tout un document (par exemple des guillemets anglais), il suffit de modifier la définition de la métabalise :

§guil <§ “<*>”>>

… et le tour est joué !

Certes, il est en principe possible d’en faire autant avec du css et les pseudo-classes ‘:before’ et ‘:after’, mais ça implique du <span …> à tout va dans le code html, et donc un traitement plus lourd par le navigateur. Tandis qu’avec PML, on a une forme de précompilation qui fournit le résultat « en dur » au navigateur.

 

L’autre force est de permettre de créer des blocs complets, avec ou sans paramètres, qui pourront être intégrés à la page (ou à l’ePub) de la manière la plus simple qui soit.

 

Exemple :

§identifiant <§ <h1  >
→→<div #style=align:center
→→→<p.centre ISBN <*1>>
→→→<p.centre © <*2> Éditions maison>
→→→>>

En mettant simplement dans le fichier source :

<identifiant #978-2-7544-2017-6 #2017>

… on obtient une page spéciale :

<h1> </h1>
<div style="align:center">
→<p class="centre">ISBN 978-2-7544-2017-6</p>
→<p class="centre">© 2017 Éditions maison></p>
→</div>

(La marque «   » matérialise une espace insécable.)

Cette méthode est très pratique pour définir des entêtes, pieds de page, pages de garde, etc. communs à diverses pages ou documents.

Il est toutefois fortement conseillé de mettre ce genre de définition dans un fichier .pss et non directement dans le fichier source .pml (ce qui aurait évidemment beaucoup moins d’intérêt…) Une autre solution, plus élégante, consiste à définir ce code dans un fichier importé et de faire appel à des constantes plutôt qu’à des paramètres (voir chapitre suivant).

4. Cas particuliers et spécificités

Si le format général d’une balise PML est le suivant :

<balise[.classe][#id][ #paramètres…][ attributs=…] texte>

… il existe comme déjà dit quelques cas particuliers, détaillés ci-après.

4.1. Images et liens hypertexte, balises avec 'value'

Pour une image (balise <img …>), le format est :

<img[.classe][#id] #lien [ #attributs=…] [texte]>

Si le lien est évidemment obligatoire (attribut implicite src), le texte, en revanche, est facultatif (et même, de nos jours, pratiquement superflu). Si un texte est fourni, il sera seulement utilisé comme valeur d’attribut « alt » (et concaténé à celle-ci si également fournie explicitement).

 

Pour un lien hypertexte (balise <a …>), même format :

<a[.classe][#id] #lien [ #attributs=…] [texte]>

Le lien est bien sûr obligatoire (attribut implicite href). Le texte, lui, si utile, est facultatif. S’il est absent, c’est le lien lui-même qui sera utilisé en ses lieu et place.

 

Vous noterez que tant pour a que pour img le format est bien standard PML. La spécificité vient juste de ce que ces balises sont définies implicitement comme suit :

§a href="<*0>" <*=#0>>
§img src="<*0>" [alt="<*>"]>

De ce fait, quelles que soient les redéfinitions éventuelles, le lien doit toujours être le premier paramètre fourni (et le texte évidemment toujours à la fin).

 

Note : on peut considérer que le lien de ces balises équivaut au paramètre <*0> implicite. Il doit donc impérativement être le premier paramètre fourni.

 

Attention : si des liens image ou hypertexte sont définis dans des métabalises, les mots-clés « href » ou « src » doivent être explicitement mis, faute de quoi il peut y avoir collision avec les paramètres de la métabalise.

De même, il se peut que ne puisse être utilisé le paramètre par défaut <*> et qu’il faille utiliser un paramètre genre <*1>, ou parfois même un paramètre nommé genre <*num>.

 

Pour les balises input, li, option, meter, progress et param, qui n’accueillent normalement pas de texte mais seulement un attribut value, celui-ci peut être omis et son contenu placé comme texte normal, il sera automatiquement attribué à cet attribut (ou concaténé à la valeur existante si value est également fourni explicitement). Ceci permet par exemple d’utiliser des constantes reçues en paramètres pour les mettre dans un champ de saisie, même si le texte contient des espaces.

 

Exemple :

<input #type=text #name=c_objet #maxlength=64 #size=40 <%c_objet>>

Si %c_objet contient le texte saisi « Problème technique », le code résultant sera :

<input size="40" maxlength="64" name="c_objet" type="text" value="Problème technique" />

Alors que si on avait écrit :

<input #type=text #name=c_objet #maxlength=64 #size=40 #value=<%c_objet>>

… ça aurait donné :

<input size="40" maxlength="64" name="c_objet" type="text" value="Problème">technique</input>

… qui est non seulement non attendu, mais également invalide en tant que code HTML (même si les navigateurs l’affichent).

4.2. SVG

Les images vectorielles SVG peuvent être incluses directement dans un document HTML5, ses balises étant spécifiques… Mais certaines ayant le même nom que des balises normales HTML, toutes les balises internes à un bloc <svg> doivent être préfixées par ‘svg@’ afin de préserver l’unicité globale.

Exemple :

→<svg_1
→→<svg@image #width=422 #height=705 #xlink:href=cover.jpeg>
→→>

4.3. Petites capitales : <smallcaps …>

L’attribut de style small-caps (font-variant:small-caps) étant très mal supporté par les logiciels de lecture (notamment tous ceux qui utilisent le moteur Adobe), une balise spéciale s’y substitue :

<smallcaps texte>

Lors de l’exportation, son contenu est remplacé par un ou plusieurs <span class="sc" …> (classe qu’il faut définir dans la feuille css utilisée, par exemple .sc { font-size:75%;}, faute de quoi la balise n’aura aucun effet). Seuls les caractères alphabétiques en minuscules sont convertis. Les caractères non concernés (capitales, chiffres, ponctuations, espaces, etc.) restent hors balise (d’où souvent plusieurs occurrences de celle-ci).

Note : lorsque l’attribut susmentionné sera enfin supporté, il sera très simple de modifier le traitement de cette balise, ne serait-ce qu’en la redéfinissant dans « pml.cfg ».

4.4. Notes : <note …>

Une balise spécifique est définie pour les notes de bas de page :

<note texte>

Il suffit de la positionner dans le corps du texte. Lors de la conversion HTML, un lien hypertexte numéroté est automatiquement généré, et le contenu de la note généré à la fois en boîte surgissante (pop-up) de type <aside …> pour les logiciels compatibles HTML5/css3 (à venir), et par défaut à la fin du bloc conteneur pour les affichages « classiques ».

Il est possible de personnaliser le fonctionnement des notes, et même d’en définir de plusieurs sortes.

La définition par défaut est celle-ci :

§note <note #parent=h1 #format=[1] #début=1 #init=h1 #classeref=note
→#classetxt=txtnote>

Ce qui se décode ainsi :

– les notes sont regroupées à la fin de chaque niveau h1 (parent) ;

– elles sont numérotées en chiffres arabes à partir de 1 et encadrées par des crochets (format) ;

– la numérotation repart à 1 à chaque rupture ;

– la numérotation recommence au début à chaque niveau h1 (init) ;

– la classe CSS des renvois est note ;

– la classe CSS des notes proprement dites est txtnote.

Si on veut des notes en chiffres romains minuscules entre parenthèses avec numérotation sur tout le document, il suffit de redéfinir ainsi :

§note <note <*format=(i)> <*init=body>>

Type et point de départ de la numérotation se définissent ainsi :

– Le premier de ces 6 caractères [1,a,A,i,I,*] trouvé définit le mode de numérotation :

1 générera 1, 2, 3… (mode par défaut)

a générera a, b, cz, aa, ab, etc. (resp. A pour A, B, C…)

I générera I, II, III, IV… (resp. i pour i, ii, iii, iv…)

* générera *, **, ***, ****… (déconseillé au-delà d’une demi-douzaine de notes).

S’il y a plusieurs caractères, ceux qui précèdent et suivent celui défini plus haut sont utilisés comme préfixe et suffixe.

Si aucun des 6 caractères de format n’est trouvé, le format par défaut sera utilisé.

Pour parent et init, veiller à ce que parent soit d’un niveau égal ou supérieur à init, faute de quoi on risquerait de trouver plusieurs notes de même numéro en fin de bloc parent.

Si début n’est pas numérique ou est inférieur à 1, sa valeur sera forcée à 1.

Pour modifier les paramètres de note, il suffit de redéfinir cette métabalise en reprenant uniquement les paramètres concernés.

Il est possible de faire coexister plusieurs notations indépendantes. Pour ce faire, il suffit de définir des métabalises dont le nom commence par note (ex. note1, notefin, etc.). Ex. :

§notefin <note #parent=body #format=[i] #init=body #classeref=note
→#classetxt=txtnotefin>

… permet d’insérer des notes de fin de volume numérotées en romain et ayant un style différent de celles de bas de page.

Nota : Toutefois, un seul type de note par balise parent est possible. Même s’il y a plusieurs définitions avec des noms différents, chacune ne fera que redéfinir la précédente.

4.5. Note(s) répétée(s) : <notebis>

Permet de n’avoir qu’une seule note réelle pour plusieurs éléments référencés.

 

Exemple :

<p Il montrait plusieurs <i makiwara><note Accessoires de karaté pour s’entraîner aux <i atémis> ou coups frappés.> arrachés aux murs, un <i sunatawara><notebis> suspendu dans un coin. Un peu partout, il y avait des <i take-maki><notebis> appuyés à la muraille.>

générera dans le texte :

<p>Il montrait plusieurs <i>makiwara</i><span class="note"><a href="#note_20" id="noteref_20">[8]</a></span> arrachés aux murs, un <i>sunatawara</i><span class="note"><a href="#note_21" id="noteref_21">[9]</a></span> suspendu dans un coin. Un peu partout, il y avait des <i>take-maki</i><span class="note"><a href="#note_22" id="noteref_22">[10]</a></span> appuyés à la muraille.</p>

et en fin de chapitre (ou de l’emplacement défini en paramètre si différent) :

<p class="txtnote"><a href="#noteref_20" id="note_20">[8]</a>,<a href="#noteref_21" id="note_21">[9]</a>,<a href="#noteref_22" id="note_22">[10]</a> Accessoires de karaté pour s’entraîner aux <i>atémis</i> ou coups frappés.</p>

… soit à l’affichage :

Il montrait plusieurs makiwara[8] arrachés aux murs, un sunatawara[9] suspendu dans un coin. Un peu partout, il y avait des take-maki[10] appuyés à la muraille.

et

[8],[9],[10] Accessoires de karaté pour s’entraîner aux atémis ou coups frappés.

 

Note : Ceci ne fonctionne bien sûr que pour des entrées consécutives.

4.6. Sommaire : <toc>

Il est possible de faire générer un sommaire pour le document. Pour ce faire, il suffit de définir une métabalise ‘toc’ décrivant ce sommaire :

§toc <h1[.sommaire] #1=chapitre,titre,classe #prefixe=toc_ Sommaire>

… et de placer une balise <toc> à l’emplacement désiré dans le document.

– h1 : balise html de titre du sommaire. La valeur ‘h1’ est requise.

– .sommaire : le style css du titre du sommaire (par défaut, le style normal de h1).

– #n : niveau d’indentation des entrées du sommaire. Pour un sommaire simple, le 1 suffit. Pour un sommaire plus élaboré (ex. parties et chapitres), on peut définir en sus un niveau 2, etc. Si aucun niveau n’est défini, ‘#1=h1’ est utilisé par défaut (mais définir #2 sans #1 est une erreur).

– chapitre : nom de la balise ou métabalise PML du document source. Si plusieurs métabalises sont à prendre en compte, on peut écrire (par exemple) ‘#1=préface+chapitre+postface,titre’.

– titre : si le chapitre comporte un titre dans une balise distincte, la préciser ici. Si un style est défini sans cette entrée, accoler les deux virgules.

– classe : style css de l’entrée de la table des matières. Par défaut, le style normal des paragraphes (niveau 1) et listes (niveaux 2 et suivants) est utilisé.

– prefixe : début du nom de tous les id créés (les id éventuellement préexistants sont conservés). Si pas spécifié, ’toc_’ est la valeur par défaut.

– Sommaire : libellé du titre de la table des matières. Un littéral (cf. 5.4 Littéraux) peut être fourni. Si rien n’est spécifié, le littéral <@Contents> sera utilisé par défaut.

 

Exemple de table des matières complexe :

§partie <h1 <*> partie>
§chapitre <h1 Chapitre >
§titre <p.titre>
§sous_chapitre <h2>
§toc <h1.sommaire #1=partie,titre,toc1 #2=chapitre,titre,toc2 #3=sous_chapitre,,toc3 <@contents>>

Ceci génère une table à 3 niveaux.

 

Important :

a. Les balises concernées, si elles n’ont pas déjà un id, en recevront un généré automatiquement.

b. Si un niveau est manquant (ex. absence de parties avec l’exemple ci-dessus), les entrées du niveau inférieur sont remontées d’un cran.

c. Si une entrée est présente mais sans texte, elle n’est pas prise en compte et ce qui vient dessous est remonté d’un cran.

d. À défaut de balise <toc> dans le document, l’existence d’une définition créera des id sur les balises concernées qui n’en auraient pas déjà.

Remarque : Si le document est destiné à devenir un ePub, il est inutile de définir des classes pour les entrées de table des matières.

4.7. Section : <section …>

Cette balise est standard en HTML5 et ne prend pas d’attributs, elle n’est qu’un regroupement – équivalente à <div #style=display:block …>.

Elle est néanmoins dotée en PML d’un statut spécial (mais qui n’affecte en rien son rôle en HTML).

 

En effet, la construction des sommaires et l’affichage des notes ne sont correctement gérés que si :

a. Les balises marquées dans les définitions §toc et §note (ainsi que <toc> ne sont pas indentées ;

b. OU sont dans un document importé (dans lequel elles ne sont pas indentées), même si l’import lui-même est indenté ;

c. OU si toutes ces balises sont regroupées dans une balise englobante <section …> qui peut être indentée (idem <import …>).

Note : La balise section étant censée englober un grand bloc de texte PML, il est indispensable de la mettre seule sur une ligne, au risque que ce qui l’accompagne sur la même ligne disparaisse de la conversion.

5. Balises de pré-traitement

Ces balises permettent de conditionner la création du document HTML à certaines données, faciliter la mise en forme en évitant des répétitions, pouvoir obtenir plusieurs versions à partir d’un même document PML.

5.1. Insertion de blocs : <import …>

Il est possible d’incorporer dans un document des éléments PML stockés séparément. Ils sont alors insérés à l’emplacement de leur appel et traités comme si le code faisait partie du document source.

<import fichier.pml>

Note : le cas échéant, préciser le chemin si le fichier n’est pas dans le répertoire du document en cours de traitement.

Cette fonctionnalité est récursive, c’est-à-dire qu’un bloc importé peut lui-même contenir des imports.

Attention : un import ne peut être conditionné par une constante, un retour d’appel Python ou une balise conditionnelle : si ce genre de condition est nécessaire, il doit être défini dans le fichier importé.

Attention : Un import peut figurer à l’intérieur d’un bloc, mais sous réserve que :

1. cette balise soit seule sur la ligne source ;

2. le contenu importé n’ait pas d’indentation initiale (càd qu’il doit pouvoir être importé hors d’un bloc ;

5.2. Python : <py …>

Il est possible d’incorporer du code généré par une fonction externe écrite en Python3, par exemple des données récupérées dans une base.

<py fonction(paramètres…)>

La balise entière sera remplacée par le contenu du retour de la fonction, lequel sera analysé en tant que code PML. Si la fonction ne renvoie rien, ou du code PML invalide, l’erreur est signalée (sauf si le retour est la valeur python None).

 

Attention :

1. Tout ce qui serait ajouté derrière la fonction sera ignoré !

2. Les paramètres sont à mettre entre ' ' et séparés par des virgules.

 

Cette balise peut évidemment être interne (et à ce moment renvoyer un simple texte).

Exemple avec une fonction devant renvoyer la date formatée en clair :

<p.classe Nous sommes aujourd’hui le <py fonc_date()>.>

Ces fonctions doivent être regroupées dans un module ‘modules.py’, par défaut dans le répertoire ‘fonctions’ de l’installation de PML.

Il est toutefois possible d’utiliser un autre emplacement, qui doit alors être précisé avec la constante ‘%modules’.

 

Possibilité très puissante :

Sous réserve qu’il renvoie bien du code PML et non une valeur pour une constante, un appel Python peut renvoyer une liste. Dans ce cas, la ligne source contenant cet appel sera répétée autant de fois qu’il y a d’éléments dans l’objet retourné, chaque occurrence recevant un élément de la liste. Cela peut être extrêmement pratique pour remplir un tableau, par exemple.

Attention : il est impératif pour que cela fonctionne de n’avoir qu’une seule balise <py …> sur la ligne source ! (Le problème ne se pose pas pour les retours de texte simple.)

5.3. Constantes : <%xxx>

Plusieurs métabalises correspondent à des ‘constantes’ dont les valeurs dépendent uniquement des paramètres initiaux. Ces balises sont directement remplacées par la valeur correspondante et, à la différence des littéraux, n’acceptent aucun paramètre ni texte associé.

– <lang> : remplace par le code langue en cours (ex : ‘fr’).

– <document> : remplace par le nom du document traité, sans son chemin ni suffixe .pml.

– <pmlroot> : remplace par le chemin menant à pml.py, permet d’éviter les chemins relatifs dans les liens locaux en positionnant tout vs pml.py.

 

Il est également possible de définir des constantes personnalisées :

§%isbn <978-2-7544-2017-6>

… pour les définir, et :

<%isbn>

… pour les utiliser. Remarquez le ‘%’ obligatoire comme premier caractère de la constante.

Dans l’exemple ci-dessus, toutes les balises <%isbn> du document seront remplacées par la valeur 978-2-7544-2017-6.

 

Important : ce remplacement ayant lieu avant tout traitement (hors imports), il est possible de placer une constante n’importe où, y compris dans une définition de métabalise, dans un bloc importé ou comme paramètre (ex : ). Inversement, on ne peut définir de constantes en retour d’un appel Python ni dans un bloc importé, elles ne seront pas reconnues comme telles.

 

Attention : Lors de l’utilisation d’une constante, ne rien ajouter dans les délimiteurs sous peine qu’elle ne soit pas reconnue : ex. <%isbn est l’ISBN> sera rejeté comme « balise %isbn inconnue».

En outre, une constante doit impérativement être définie sur une seule ligne.

 

Note : un paramètre %… peut aussi recevoir une valeur à l’exécution, c’est-à-dire comme paramètre passé à l’appel de pmlexport. Cf. plus loin dans ce document.

Un paramètre personnalisé sans valeur définie sera remplacé par un texte de longueur nulle (avec affichage d’un message d’erreur).

 

Exemple des possibilités presque infinies :

§%isbn <<py isbn('<document>')>>

… appelle une fonction python qui reçoit le nom du document en paramètre et renvoie son code ISBN (par exemple lu dans une base de données), lequel devient la valeur de la constante %isbn utilisée ailleurs dans le document.

Remarquez les doubles délimiteurs : la paire extérieure délimite une constante, laquelle est générée par une balise, donc elle-même entre délimiteurs !

Attention : <py …> est la seule balise autorisée à l’intérieur d’une constante !

Note : dans le cas d’une constante pas nécessairement utilisée, pour éviter les messages d’avertissement une routine python peut lui donner la valeur None plutôt qu’un texte vide.

Une ou plusieurs constantes peuvent être définies (ou leur valeur modifiée) directement en ligne de commande avec l’option -c %nom=valeur[ %nom2=valeur2[ …]]

Important : Les constantes « remplies » par des appels Python sont analysées non pas dans l’ordre où elles apparaissent dans le document, mais dans l’ordre alphabétique. Donc, en cas d’interdépendance (ex. routine Python générant des valeurs récupérées par d’autres routines Python), veiller à les nommer de manière idoine (par exemple avec un préfixe commun suivi d’un numéro d’ordre).

 

Il existe plusieurs autres façons de définir une constante :

– dans pml.cfg, avec une ligne %constante=valeur ;

– passée en paramètre dans l’appel de pmlexport.py sous la forme %constante=valeur ou %constante tout court, équivalent à un caractère blanc (attention : %constante= sans valeur ne sert à rien car constante vide≈constante nulle|non définie).

 

Remarque : une constante passée en paramètre sera ‘écrasée’ par une définition de la même dans pml.cfg ou le document pml. De même, une constante définie dans pml.cfg sera écrasée par une définition de la même dans le document.

 

Astuce : Afin d’éviter de remplir le fichier log avec des messages signalant des constantes vides ou inutilisées – cas de champs de saisie non remplis ou de constantes présentes dans un bloc <incl> non inclus –, mettre comme premier caractère '@' : une définition telle que §%@xyz <…> ne donnera jamais lieu à avertissement quel que soit le statut de la constante. Naturellement, bien veiller lors de l’utilisation à ne pas oublier le préfixe '%' : <%@xyz> !

5.4. Littéraux : <@xxxx>

Il s’agit de pseudo-balises commençant par un '@'. Ce nom, un mnémonique qui doit obéir aux règles de codification d’une balise ou métabalise, est remplacé par le libellé associé trouvé dans le fichier locales/pml_xx.po ou locales/pml_xx.mo, où xx est le code de la langue utilisée (‘lang=xx’ dans pml.cfg ou langue système par défaut).

Si le littéral n’a pas de correspondance, la balise entière apparaît telle quelle dans le HTML généré et un message d’erreur s’affiche à la génération.

Le texte d’un littéral peut contenir des paramètres et/ou un texte associé tels que définis au chapitre 3.

 

Exemple :

Si on a dans pml_fr.po le mnémonique ‘test’ avec le libellé ‘C’est <*> qu’on teste.’, et dans pml_en.po le libellé ‘Here, <*> is tested.’

<@test pml>

donnera respectivement :

C’est pml qu’on teste.
Here, pml is tested.

… selon la langue en cours.

 

S’il faut plus d’un élément au sein du texte, il faut alors utiliser les paramètres, soit positionnels, soit nommés.

 

Exemple :

Si ‘countdown’ correspond en français à ‘Il vous reste <*1> minutes et <*2> secondes.’,

<@countdown #2 #59>

donnera :

Il vous reste 2 minutes et 59 secondes.

Ou bien, si ‘countdown’ correspond en français à ‘Il vous reste <*mn> minutes et <*s> secondes.’,

<@countdown #s=59 #mn=2>

… donnera la même chose que plus haut.

 

Note : le libellé d’un littéral peut contenir diverses balises PML (gras, italique, lien, image…), elles seront traitées normalement.

 

Remarque : Les littéraux présentent essentiellement un intérêt pour des pages destinées à Internet. Si l’objectif est un ePub, par définition monolingue, le besoin n’est guère présent.

5.5. Traitement conditionnel <incl …>, <excl …>, <else …>

À l’aide de constantes, il est possible de conditionner la présence ou l’exclusion de parties du document. Ceci permet de créer plusieurs versions à partir d’un même fichier .pml (par exemple, un extrait de roman pour un epub, voir exemple en fin de cette section).

Il y a deux modes d’utilisation.

 

1. Incorporation directe de la partie concernée :

<incl %param=valeur[ %param=valeur …] <balise …>>

La balise ne sera présente dans le document que si chacun des %param (qui peuvent être aussi une constante fixe telle <lang> ou <document>) a la valeur indiquée. <excl fera l’inverse : la balise sera présente sauf si le ou les paramètres possèdent tous la valeur indiquée.

Si la condition pour une constante est basée sur l’existence ou la valeur non nulle (c.à.d. contenant au moins un caractère) du paramètre, il suffit de ne pas mettre de comparaison :

<incl %param <balise …>>

… prendra en compte la balise si %param est défini et non nul, quelle que soit sa valeur par ailleurs.

Dans le cas de vérification sur l’absence (ou la valeur nulle) d’une constante, les deux notations ci-dessous sont équivalentes :

<excl %param …>
<incl %param- …>

L’intérêt de la seconde notation réside surtout dans l’usage de plusieurs constantes dans une même condition :

<incl %param1 %param2- …>

… correspond à la condition "si param1 et non param2 …".

 

2. Délimitation :

<incl %param=valeur[ %param=valeur …]>

<incl>

Ici, en l’absence de balise associée, c’est toute la partie du document comprise entre les deux <incl qui ne sera présente que si les paramètres correspondent.

Chaque <incl ou <excl est traité en séquence indépendamment des précédents. Toute condition remplie activera l’exclusion ou l’inclusion de la suite. Un <incl> inconditionnel rétablira l’état initial (pas de <excl> inconditionnel, qui équivaudrait à supprimer systématiquement tout ce qui suit et ne se serait donc guère pertinent).

 

Astuce : il est également possible d’inverser une condition, en remplaçant ‘=’ par ‘!=’ ou ‘≠’ (ou en ajoutant un ‘-’ à la fin d’une constante sans valeur associée). De même, on peut accepter une sous-valeur avec '~=' ou '≃' : une constante contenant 'en-GB' validera une telle comparaison avec 'en'.

Note : une inclusion ou exclusion avec balise associée sera traitée indépendamment de l’état inclusion ou exclusion global en cours.

Exemple pour un ePub (titre_principal, centre et àsuivre sont bien sûr des métabalises maison) :


<titre_principal Titre de livre>
<incl %extrait <centre <b (extrait)>>>

<incl %extrait <àsuivre (à suivre)>>
<excl %extrait>

Si %extrait n’est pas mis dans la ligne de commande, on génère l’ePub normal du livre complet.

Si %extrait est spécifié, un ePub réduit est généré, avec « (extrait) » sous le titre, et « (à suivre) » en fin de document, à la place de tout ce qui suit la balise excl.

 

La balise else, qui ne prend aucune constante, ne joue qu’un rôle complémentaire :

a. En l’absence de conditions incl (directes ou en délimiteurs) la précédant, else se comporte comme un incl inconditionnel (elle est en fait inutile).

b. Précédée par une ou plusieurs conditions incl, son contenu ou ce qui la suit sera pris en compte si, et uniquement si, aucune des conditions précédentes n’a été validée.

Une balise <incl> ferme un groupe else tout comme n’importe quel <incl …>.

Exemple :

<incl %src=abc>

<incl %src=def>

<else>
<p Erreur>
<incl>

… affichera 'Erreur' si la constante %src ne vaut ni 'abc' ni 'def'.

 

À noter : Les balises incl, excl et else ne suivent apparemment pas la règle d’indentation en vigueur dans HTML et XML, à savoir qu’une balise ne doit affecter que ce qui est inclus entre ses délimiteurs de début et fin.

Toutefois, il s’agit ici de balises de prétraitement ayant un rôle particulier, puisque ne jouant pas sur l’environnement, mais sur la présence ou l’absence, une nouvelle condition pouvant altérer la précédente.

Il était donc plus simple de faire une petite entorse en leur faisant impacter non pas le contenu, mais la suite.

5.6. directives HTTP <http …>

Cette balise permet de définir des directives http, qui seront émises avant le document lui-même. Aucun contrôle n’est effectué sur leur contenu (avec risque de « Internal error 500 » en cas de contenu invalide).

Il est ainsi possible d’effectuer de nombreux pré-traitements, comme par exemple une redirection.

 

Exemple :

<pml>
§%ok <<py valide('<%user>')>>>
<incl %ok!=oui <http Location: http://www.pml.ovh/>>
…code de la page…

… n’affichera la page que si le paramètre 'user' a été reçu et validé par la routine python. Dans tous les autres cas, on est renvoyé vers la page principale du site.

 

L’usage des directives http est évidemment réservé aux pages Internet… et aux « webmestres » chevronnés.

Une liste de ces directives ici : https://en.wikipedia.org/wiki/List_of_HTTP_header_fields

 

Note : Les directives "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0" et "Content-type: text/html" sont automatiquement placées devant le début du document Internet proprement dit, elles ne sont donc jamais à spécifier.

5.7. Mises à jour (à faire)

Un élément ajouté ou supprimé peut être balisé ainsi :

texte <- enlevé><+ ajouté>

Cependant, la génération HTML ne pourra donner que :

texte ajouté

C’est pourquoi on peut ajouter une indication derrière le signe :

texte <-1 enlevé><-2 <+1 ajouté>><+2 modifié>

Ainsi, la génération HTML pourra être différente selon la valeur de l’option -v xx spécifié dans la ligne de commande :

-v 0 :

texte enlevé

-v 1 :

texte ajouté

-v 2 (ou >2) :

texte modifié

Pour un meilleur traitement, il est possible d’associer des données plus parlantes dans la zone des métabalises :

§1 <20170109>

ou

§1 <lundi>

Ainsi, -v 20170109 (ou -v lundi) sera équivalent à -v 1.

Attention, seules les métabalises uniquement constituées d’un nombre sont associables à des repères de mises à jour.

6. Les outils

Compte tenu de ses _usages multiples, PML est fourni en plusieurs « colis » :

A. Un pack base contenant les outils pour importer/exporter/créer du HTML ou des ePub. Son installation se fait simplement en décompressant l’archive dans un répertoire au choix (qu’il est bon d’ajouter dans la liste des « path » du système pour simplifier les appels par la suite).

Contenu :

– Les programmes pmlimport.py, pmlexport.py, htmlepub.py.

– Un fichier de configuration pml.cfg. C’est dans ce fichier qu’on définit quelques paramètres d’installation, comme la langue et le chemin de l’outil epubcheck…

– Une feuille de style de métabalises pml.pss, qui contient quelques redéfinitions « générales » (pour le français).

– Un sous-répertoire fonctions, qui contient les fonctions partagées par les programmes susmentionnés et un fichier modules.py destiné à accueillir les fonctions python utilisateur. C’est également là qu’il faudra mettre les fonctions externes pour ceux qui développeront des choses supplémentaires, telles des accès à une base de données.
Le fichier fourni contient un exemple de lecture d’une base de données afin de renvoyer les caractéristiques d’un livre dans des constantes en vue créer un ePub.

– Un sous-répertoire locale, qui contient les littéraux définis pour un contexte international (cf. métabalise <@…>).

 

B. Un pack web pour les appications de site Internet (ou Intranet, ne soyons pas chauvins).

Contenu :

– Le programme pml.py d’interface pour les requêtes Internet.

– Un fichier de configuration pml.cfg. C’est dans ce fichier qu’on définit quelques paramètres d’installation, comme la langue. (idem pack base)

– Une feuille de style de métabalises pml.pss, qui contient quelques redéfinitions « générales » (pour le français). (idem pack base)

– Un fichier pml.alias d’exemple (cf. plus loin dans ce chapitre).

– Un fichier .htaccess avec les instructions permettant à Apache de traiter des documents PML.

– Un fichier 404.pml, appelé quand la page demandée n’est pas trouvée. il est évidemment personnalisable.

– Un sous-répertoire fonctions, qui contient les fonctions partagées par les programmes susmentionnés et un fichier modules.py destiné à accueillir les fonctions python utilisateur. C’est également là qu’il faudra mettre les fonctions externes pour ceux qui développeront des choses supplémentaires, telles des accès à une base de données. (idem pack base, sauf modules.py qui ne contient pas les mêmes exemples. Ici, c'est la conversion d’un code source PML en document (toujours PML) qui affichera ce code source avec coloration syntaxique. Cf Affichage du code PML et Comprendre PML sur http://www.pml.ovh.)

– Un sous-répertoire log, qui recevra les messages émis par l’export pml→html dans un environnement de navigation internet (avertissements, erreurs, plantages…)

 

C. La documentation sous forme d’ePub.

 

Note 1 : il est recommandé d’installer l’utilitaire epubcheck, téléchargeable sur https://github.com/IDPF/epubcheck/releases.

Note 2 : Les utilisateurs Windows doivent également installer :

– Python 3.6, téléchargeable sur https://www.python.org/downloads/windows/.

– Java, dispo sur https://www.java.com/fr/download/manual.jsp (prendre une version hors ligne).

Note 3 : l’intérêt de PML étant de faciliter la mise à jour|mise au point de documents, un bon éditeur de texte est donc recommandé. Personnellement, je conseille KomodoEdit : http://www.activestate.com/komodo-ide/downloads/edit.

Il a, entre autres points forts (coloration syntaxique pour de nombreux langages, Unicode pleinement supporté, etc.) le double avantage d’exister pour Windows, Mac et Linux… et d’être gratuit pour un usage personnel. (Pour la coloration syntaxique, je tâcherai dans un avenir pas trop lointain de lui adjoindre la reconnaissance de PML.)

6.1. Installation

➢ Windows (W7 minimum) :

Installer python 3.5 ou supérieur depuis https://www.python.org/downloads/windows.

Installer win-unicode-console, soit directement avec pip install win-unicode-console, ou télécharger le module depuis la page https://pypi.org/project/win_unicode_console/ et l’installer par pip install win_unicode_console-0.5.zip. Ne pas oublier de cocher la case pour ajouter le chemin de Python dans le Path.

Cela fait, l’appel de tout programme python en ligne de commande doit simplement être précédé de ‘python’.

 

➢ Linux :

Rien à installer, python et java sont en principe de base (à vérifier, peut n’être pas vrai pour toutes les plates-formes).

L’appel de tout programme python en ligne de commande doit simplement être précédé de ‘python3’ (‘python’ tout court appelle python 2.7, non compatible).

 

➢ Tous systèmes :

Les modules python suivants peuvent être nécessaires et devront éventuellement être installés :

polib : à installer, indispensable pour la gestion des littéraux et des messages.

PIL : indispensable pour htmlepub. Attention, prendre python-pil (pour python3) et non pillow (python2, non compatible).

mysql.connector : pour toute fonction utilisateur devant accéder à une base de données.

 

➢ Serveur internet :

Le pack doit simplement être décompressé dans le répertoire racine du site.

Que ce soit sur une machine locale ou raccordée au réseau, l’utilisation en mode web de PML nécessite que ce serveur soit configuré pour exécuter les fichiers Python.

Il est également indispensable que le module ‘rewrite’ d’Apache soit activé (ex. par la commande en ligne ‘a2enmod rewrite’).

6.2. Le fichier de configuration pml.cfg

Simple suite de valeurs sous la forme :

code = valeur

Peut contenir des commentaires avec un # en début de ligne. Ce fichier est d’ailleurs ainsi auto-documenté. Il est fourni avec des valeurs par défaut (Linux pour les chemins d’accès).

6.3 Les fichiers de littéraux et messages

Fichiers suffixées en .mo (format binaire) contenant des littéraux associés à des mnémoniques dans diverses langues. Tous placés dans le répertoire locale, ils doivent s’intituler msg_xx.mo (pour les messages) et pml_xx.mo pour les littéraux utilisateur.

Un petit utilitaire ‘locales_gen.py’ permet de générer/mettre à jour ces fichiers à partir d’un fichier source unique locales.txt (fourni et auto-documenté).

6.4. L’utilitaire pmlimport.py

Pour convertir un document HTML ou EPUB en document PML :

python[3] [chemin/]pmlimport.py [-feuille.pss] [document.html|document.epub] [-o fichier[.pml]][ -ignore classe1[,classe2…]] [ -indent]

-feuille.pss’ est une option de spécification d’une feuille de style .pss à prendre en compte pour la conversion (en sus de pml.pss, toujours exploité). Le cas échéant, préciser son chemin. Il peut s’agir de définitions « temporaires » aidant au remplacement de balises ou attributs qui seront différents par la suite (en d’autres termes, des métabalises utilisées pour pmlimport n’auront pas nécessairement la même définition avec une autre feuille de style utilisée par pmlexport). Si cette feuille se trouve dans le répertoire défini par la constante%scripts, écrire -[%scripts]feuille.pss (les caractères < et > posent problème en ligne de commande).

Par défaut, le fichier PML généré porte le même nom de base que le source HTML : abc.pml→abc.html. Il est toutefois possible de spécifier un autre nom dans la ligne de commande.

-ignore permet de définir une liste de classes contenues dans l’ePub ou le document HTML et correspondant à des balises à ne pas conserver (nettoyage de documents inutilement surchargés). Par défaut, seules les balises span sont concernées. Il est toutefois possible de préciser une autre balise en mettant explicitement balise.classe. Ex.

ignore calibre4,i.calibre6

supprimera les balises <span class="calibre4" …> et <i class="calibre6" …>. Ce qui se situe entre les <span …> et </span> est évidemment préservé.

Souvent des balises inutiles sont numérotées en séquence. Pour simplifier, on peut mettre un ‘ ?’ là où peut figurer un chiffre. Ainsi, -ignore calibre?? ignorera toutes les classes de calibre00 à calibre 99 (mais pas celles avec 1 ou 3 chiffres).

-indent force la restructuration du code indépendamment de l’assemblage HTML. Ceci est extrêmement utile en cas de document HTML bâti n’importe comment et souvent illisible, car apportant la lisibilité nécessaire à la compréhension.

 

Attention : les métabalises avec texte ne sont reconnues que si elles sont effectivement sur une seule ligne.

Toute balise HTML, dans le cas général :

<balise[ class="abc"][ id="def"][ attribut="ghij"]>texte</balise>

… est convertie comme suit :

1. Une métabalise reprenant la définition, avec un commentaire signalant le nombre d’occurrences (utile pour le nettoyage) :

§balise_abc_n <balise.abc[#def][ #attribut=ghij]>
# Utilisée 5 fois

2.La balise PML proprement dite :

<balise_n texte>

Remarques :

– ‘n’ est une numérotation différenciant les variantes de ‘balise’ utilisées (balise_0, balise_1, etc.). En général, le nom de la métabalise reprend juste celui de la classe de la balise html. Dans le cas où la même classe servirait à plusieurs balises différentes, le nom de la balise devient alors 'classe_balise[_n]'.

– Si une définition est présente dans pml.pss ou la feuille de style donnée en paramètre, c’est son nom qui est utilisé et aucune métabalise nouvelle n’est définie.

– Les contenus d’éventuelles balises style ou script sont mis entre triples « apostrophes » et laissés intacts dans le code généré.

– Si le document source est un ePub, le fichier PML obtenu ainsi que la (ou les) feuille(s) de style et l’image de couverture, sont copiés dans le répertoire courant. Les images sont amenées avec le même chemin relatif vs le texte, donc soit dans le répertoire courant, soit (le plus souvent) dans un sous-répertoire.

– Les attributs ayant des valeurs normalement uniques (href, src, data-…) ne sont jamais incorporés dans une métabalise, afin de ne pas multiplier inutilement les définitions.

 

Points forts :

☑ Si, comme souvent, une même balise avec les mêmes attributs apparaît 36 fois dans le document HTML (ce qui est toujours le cas dans les conversions Word→HTML), une seule redéfinition est faite, ce qui :

a. raccourcit considérablement le code résultant, et…

b. permet d’identifier très vite les balises redondantes (pas identiques mais presque) et de simplifier très facilement le code dans le document PML.

☑ L’usage d’une feuille de style .pss permet de générer directement la métabalise voulue, d’où simplification du nettoyage et gain de temps important.

6.5. L’utilitaire pmlexport.py

Pour convertir un document PML en document HTML :

python[3] [chemin/]pmlexport.py document.pml [-o fichier[.html]] [-epub|-epub2|epub3] [%constante=valeur]…

-epub’ est une option qui a pour effet de lancer htmlepub sitôt la création du document HTML achevée. -epub et -epub2 lancent la fabrication d’un ePub2, -epub3 celle d’un ePub3 (bien que cette norme soit encore très mal/peu supportée par les logiciels de lecture).

Par défaut, le fichier HTML généré porte le même nom de base que le source PML : abc.pml→abc.html. Il est toutefois possible de spécifier un autre nom dans la ligne de commande.

Note : si ce nom fourni n’est pas suffixé, ou suffixé avec autre chose que .htm ou .html, le suffixe sera forcé en .html.

Remarque : comme on peut le voir ci-dessus, il est possible de passer des constantes en paramètres (et pas qu’une seule).

 

Points forts :

☑ Les fermetures de balises manquantes ou excédentaires sont identifiées et compensées, ainsi le HTML généré est toujours propre (même s’il peut ne pas être conforme au souhait du fait des erreurs rencontrées).

☑ Création d’une table des matières pouvant être très structurée (jusqu’à 3 niveaux) grâce à une simple métabalise (cf. 4.D plus haut).

☑ Positionnement et numérotation automatique des notes (cf. 4.C plus haut), adaptation ePub3 prévue (infobulles|pop-up) sans qu’il soit besoin de toucher au code PML.

☑ Gestion des petites capitales tenant compte du mauvais|non support de l’attribut de style ‘small-caps’.

☑ Nettoyage du code par suppression des balises de type span (b, i, sup, inf, etc.) ne contenant aucun caractère pour lequel la spécification aurait un sens ; chaque correction est signalée pour permettre le nettoyage dans le source PML.

☑ Suppression des ‘id’ inutiles (non référencés) et ‘href’ locaux invalides (lien vers id non défini), avec signalisation.

☑ Signale les classes non définies dans une feuille .css, ainsi que les métabalises directement définies dans le document mais non utilisées.

☑ Capacité d’appel de routines en Python pour incorporer de l’information ou vérifier du code.

☑ L’usage combiné de constantes dans la ligne de commande et des balises incl|excl permet de générer des HTML différents à partir d’un unique PML.

☑ L’usage de littéraux permet de créer des pages HTML dans diverses langues à partir d’un unique PML.

6.6. L’utilitaire htmlepub.py

Pour convertir un document HTML en livre ePub :

python[3] [chemin/]htmlepub.py document.html [-epub3]

-epub3’ indique que le résultat souhaite doit être un ePub3. Par défaut, c’est un ePub2 qui est créé. (Régression temporaire : ne fonctionne plus pour ePub3)

 

Points forts :

☑ Reconnaît un chapitre contenant une table des matières (notamment créée par pmlexport) et s’en sert pour celle de l’ePub. À défaut, la crée de toutes pièces, en utilisant les balises <h1 dotées d’un ‘id’. cf. paramètre ‘tocid’ dans pml.cfg.

☑ Se sert des ‘meta’ pour enregistrer correctement les diverses caractéristiques d’un ePub (auteur(s), traducteur(s), description, etc.).

☑ Fusionne toutes les feuilles de style .css en ne conservant que les styles effectivement utilisés : pas de définitions inutiles.

☑ En fin de traitement, appelle epubcheck (si installé) pour vérifier la conformité du livre obtenu.

 

Prévu : une option pour incorporer les polices de caractères, mais en les réduisant aux sous-ensembles effectivement utiles au livre.

La plupart des données informatives d’un ePub peuvent être insérées directement dans le document HTML en tant que <meta.

Ex :

<meta name="type" content="Science-fiction" />
<meta name="publisher" content="Éditions de chez moi" />
<meta name="description" content="Description du contenu de l’ouvrage//sur deux paragraphes" />
<meta name="creator:aut" content="Jean Dupont" />
<meta name="language" content="fr" />
<meta name="title" content="Mon livre à moi" />
<meta name="date" content="2017-12-31" />

ou bien, en partant d’un document PML :

<meta #name=type #content=Science-fiction>
<meta #name=publisher #content=Éditions de chez moi>
<meta #name=description #content='''Description du contenu de l’ouvrage//sur deux paragraphes'''>
<meta #name=creator:aut #content=Jean Dupont>
<meta #name=language #content=fr>
<meta #name=title #content=Mon livre à moi>
<meta #name=date #content=2017-12-31>

(Notez qu’il est possible dans ce contexte d’éviter d’échapper les espaces en mettant le texte entre triples « apostrophes »)

Les éléments pouvant contenir plusieurs paragraphes (notamment description) doivent avoir les sauts de paragraphes repérés par des // et non par des retours de ligne réels.

Les valeurs de « name » sont décrites dans le document:

http://www.idpf.org/epub/20/spec/OPF_2.0.1_draft.htm#Section2.2

Les données ayant un attribut « opf:role » dans l’ePub (creator et contributor) peuvent s’écrire très simplement en PML (ou équivalent HTML) :

<meta name="creator" opf:role="xyz" … />
= <meta #name=creator:xyz …>
= <meta name="creator:xyz" … />

La liste des codes en trois lettres reconnus figure dans le même document susmentionné.

6.7. routines Python utiles

Ceci s’adresse évidemment en premier lieu à ceux et celles qui implémenteraient du code Python pour exploiter au mieux les capacités de PML.

fonctions de trace

Le fichier fonctions/trace.py contient deux fonctions utiles pour aider au débogage :

1. trace.log fonctionne comme un print, sauf qu’elle n’accepte qu’un seul paramètre (donc bien formater l’ensemble de ce qui lui est passé) : trace.log(texte).

2. trace.val prend deux paramètres :

a. une chaîne de caractère contenant le nom de la variable (ou des variables, séparés par des virgules) dont on veut connaître la valeur ;

b. la fonction locals(), indispensable pour que Python utilise bien les variables du fichier en cours et non d’éventuelles variables de même nom définies ailleurs.

trace.val donnera les valeurs de toutes les variables données dans le premier paramètre, quel que soit leur format, avec '???' pour celles qui ne seraient pas identifiées (donc sans plantage même en cas d’erreur de nom). Ex : trace.val('var1,var2',locals()). Restriction : ne pas mettre d’élément de tableau ave un indice lui-même variable, genre tab[xt].

 

trace.log et trace.val enregistrent les résultats dans un fichier log (dans le répertoire de même nom, associés à jun horodatage et au fichier et au numùéro de la ligne où elles ont été appelées.)

fonctions/trace.py est défini en standard pour l’environnement pml destiné à Internet. Pour pmlexport.py, qui affiche tout dans le terminal, son utilité est moindre, print étant disponible.

tri naturel

Le fichier fonctions.fonctionssort.py contient un puissant utilitaire permettant de trier des données dans un ordre naturel pour l’esprit humain. il utilise les descriptions Unicode enregistrées dans le système.

• La séquence Lefèvre / Lefebvre / Le Fèvre / Lefébure sera triée en Lefébure / Lefebvre / Le Fèvre / Lefèvre. (Les espaces, accents, etc. sont traités comme des variantes – œ est classé comme 'oe', ß comme 'ss', etc.) Seule restriction : non testé pour les systèmes non alphabétiques.

• La séquence a5 / A10 / a9b sera triée en a5 / a9b / A10 (toute suite de chiffres est traitée comme un nombre).

 

La fonction naturalsort peut recevoir plusieurs paramètres (en tri « standard », seul le premier, au format list est obligatoire) :

— Le deuxième doit être une liste (ou une liste de listes, cf. 4e paramètre) de mots considérés comme des préfixes et déplacés en fin de séquence pour l’ordre de tri. ainsi, avec une liste d’articles comme le, la, les, du, de la, des, l’…, C'est le mot qui suit l’article qui sert au classement : La gauche / Le milieu / La droite / L’envers seront triés comme La droite / L’envers / La gauche / Le milieu.

– Le troisième est compare=True (étant par défaut compare=False). Avec True, le tri renvoie non pas une, mais deux listes, la seconde étant les chaînes telles que reformatées pour le tri. Peut être utile pour comprendre ce qui s’est passé si le résultat n’est pas celui escompté – ce qui ne signifie pas que le tri est mauvais, juste que sa logique n’a pas été bien comprise.

— Le quatrième est sep='x' où 'x' est un caractère de séparation permettant de trier comme si on donnait plusieurs colonnes. Par exemple, sep='/' triera correctement des chemins de répertoires (Linux ou Mac, sachant que Windows demandera '\\' – hélas le caractère d’échappement standard, donc à doubler).

 

Pour les dictionnaires, naturalsortDict (qui ne prend qu’un seul paramètre renvoie les clés du dictionnaire passé en paramètre selon la logique décrite plus haut.

 

Cet outil est offert en bonus, à chacun de l’importer dans ses modules Python – il est indépendant et n’est pas réservé à PML !

7. L’utilitaire pml

Ce programme, utilisé dans le traitement de requêtes de pages Internet, permet, à l’aide de quelques redirections à définir pour Apache sur le serveur, de travailler avec des fichiers .pml aussi nativement que s’il s’agissait de pages .html ou .php.

Ainsi une requête http://www.monsiteamoi.fr/accueil.pml enverra au navigateur le flux au format html issu de l’export pml→html.

 

Points forts :

☑ Permet d’utiliser des fichiers pml aussi facilement que s’il s’agissait de html, php, py…

☑ Contrairement aux programmes php ou python, même une erreur grave s’affichera à l’écran plutôt qu’un ‘Internal error 500’ souvent sans informations utiles dans error.log d’Apache.

☑ La puissance des métabalises (et notamment la possibilité de faire appel à des routines python, ce qui inclut des accès base de données) permet d’avoir des pages dynamiques et quasiment de créer des sites complets.

 

pml.py doit être installé dans le répertoire racine du site. Il est livré avec un .htaccess contenant les commandes Apache indispensables pour que les fichiers .pml soient reconnus, ainsi que 2 pages en pml : index.pml et 404.pml. La première permet de tester le bon fonctionnement en saisissant dans la barre d’adresse du navigateur :

http://chemin_vers_pml/index.pml

ou, en local :

localhost/chemin_vers_pml/index.pml

… où le niveau de base http:// ou localhost/ est celui défini dans la configuration du serveur (en local sous Linux, souvent /var/www) et chemin_vers_pml le ou les sous_répertoires menant à celui qui contient pml.py.

404.pml est la page par défaut qui s’affiche (dans la langue du système ou celle spécifiée dans pml.cfg) quand xyz.pml n’existe pas.

 

Les sous_répertoires sont parfaitement reconnus. La requête :

localhost/chemin_vers_pml/rep1/rep2/pagerep3.pml

… fonctionnera aussi bien avec .pml que s’il s’agissait de .html, .php ou .py.

 

De même, un lien

<a #pagesuivante.pml Suite>

qui, en html, deviendra

<a href="pagesuivante.pml">Suite</a>

… sera parfaitement opérationnel.

 

Pour aider à la mise au point des pages, pml.py a été conçu pour pouvoir également être appelé en ligne de commande :

Ainsi la requête navigateur :

localhost/chemin_vers_pml/page37.pml?lang=fr

aura pour équivalent dans un terminal, à partir du répertoire de pml.py :

python[3] pml.py "page37&lang=fr"

La page HTML générée (ainsi que les messages d’erreur) s’afficheront bien sûr dans le terminal.

À noter que pml.py dispose d’un système de recouvrement d’erreurs (module fonctions/trace.py) qui intercepte les plantages afin de les afficher dans la fenêtre du navigateur. Vous n’avez rien à configurer pour cela.

 

Pour faciliter encore la navigation, un fichier facultatif pml.alias, situé dans le même répertoire que pml.py, offre la possibilité de définir des raccourcis (à raison d’un par ligne).

Par exemple, si l’accès standard à une page est

http://www.blary.eu/cultureSF/orion/orion.pml

… si on indique dans pml.alias

orion.pml = cultureSF/orion/orion.pml

… on pourra alors se contenter de :

http://www.blary.eu/orion.pml

… pour obtenir exactement la même navigation.

Attention : ceci n’est évidemment valide que pour des pages pml, et le suffixe ‘.pml’ doit être présent de part et d’autre dans la définition de chaque alias.

8. Gestion de bases de données MySql ou MariaDB : PyMyAdmin

Cet outil, en cours de développement, est conçu comme un quasi-clone de PhpMyAdmin, mais écrit en Python ; utilisant du PML ; plus performant car n’utilisant pas de javascript à outrance ; même si toutes les fonctionnalités de PhpMyAdmin ne seront pas reprises (beaucoup n’étant d’ailleurs que d’une utilité toute relative car d’usage très spécifique et/ou exceptionnel).

(Développement en cours, disponibilité prévue pour la version 0.9)


© 2017 Jean-Luc-Blary