Comment brouiller joliment un texte ?
January 15, 2018 | Snippets | fr | en
Le « texte postiche » est un matériau indispensable lorsque l'on travaille les aspects typographiques d'une mise en page InDesign. Bien sûr, il suffit d'invoquer la fonction Texte de substitution
pour couler dans le bloc courant un impeccable lorem ipsum. Mais il peut se trouver qu'un texte soit déjà présent (dans une langue ou avec des caractères spécifiques) et que vous souhaitiez alors en fabriquer une version postiche par brouillage. Grâce à IdExtenso, un tel utilitaire ne nous demandera que quelques lignes de code…
Quelle différence entre un « bon » et un « mauvais » mélange de caractères ? Pour parodier un sketch inoxydable, le bon mélange a ceci de plus qu'il mélange bien ! Certes, dans les deux cas, tout repose sur un processus aléatoire, mais le bon mélange tient compte de la distribution statistique des caractères au sein du texte. C'est ce qui rend plus délicat qu'on ne l'imagine, par exemple, le développement d'un générateur de type « lorem ipsum ». Bien que les éléments soient piochés plus ou moins au hasard, ils ne sont pas réassemblés tout à fait au hasard.
Le principal problème, c'est qu'un algorithme purement aléatoire ne préserve pas les articulations probables entre les lettres. Le résultat d'un brouillage aveugle n'a plus le goût ni la forme générale du texte d'origine. Illustrons ceci au moyen d'un script « naïf » :
// Brouillage naif // (Selectionnez un bloc-texte avant d'executer ce script) var sto = app.selection[0].parentStory; var a = sto.texts[0].contents.split(''); var i = a.length; var p,t; while( --i ) { p = ~~(i*Math.random()); t = a[i]; a[i] = a[p]; a[p] = t; } sto.contents = a.join('');
Le code ci-dessus se contente d'enregistrer le contenu d'un objet Story
dans un tableau de caractères, puis de le mélanger en remplaçant chaque caractère par un autre pris au hasard parmi ceux existant. Pour les besoins de ma démonstration, j'utilise un extrait de « L’inspiration coule des Cévennes » de Flora Clodic (en espérant que l'auteur me pardonnera d'avoir martyrisé son texte). Voici le résultat typique du brouillage naïf (cliquez sur l'image pour visualiser l'animation avant/après) :
Comme vous le percevez instantanément, le brouillage n'est pas satisfaisant pour un sou. Les lettres, espaces, signes de ponctuation, majuscules et minuscules, se télescopent d'une façon chaotique qui ne rend plus compte des règles d'agencement auxquelles nous sommes habitués. Pour produire un mélange moins dénaturant, il suffirait d'enregistrer et d'appliquer ces règles, du moins sur un plan probabiliste. Telle est précisément la prouesse qu'accomplit une chaîne de Markov à états discrets.
Chaîne de Markov
Bonne nouvelle ! Notre librairie IdExtenso pour InDesign/ExtendScript possède un module nommé Markov.jsxlib qui implémente toute la mécanique d'une chaîne de Markov. Considéré comme une structure de données, cet objet capture le comportement statistique d'une séquence quelconque. Étant donné un flux d'entrée (chaîne de caractères, tableau) formé d'éléments ordonnés (appelés tokens), la chaîne de Markov enregistre sous forme d'états les lois de succession les plus probables d'un token à l'autre. En gros, elle répond à la question suivante : si j'ai un token T
précédé par les tokens T0,T1...Ti
, quels sont les tokens qui ont le plus de chance d'apparaître à la suite de T
? La séquence (T0,T1...Ti,T)
est traitée comme un état (au sens des automates finis) de la chaîne de Markov à cet instant particulier. La taille (ou profondeur) de la structure définit le nombre d'items à enregistrer dans chaque état.
Pour explorer tous les rouages de cet algorithme, le mieux est d'expérimenter son API, largement commentée dans le code source. Vous découvrirez, entre autres, qu'il est possible de recombiner des mots ou des objets plutôt que de simples lettres. Mais pour l'heure, mettons en pratique l'usage le plus simple d'une chaîne de Markov : la recombinaison des caractères d'un texte.
Voici la recette en cinq étapes :
1. Prendre une chaîne de caractères S
(par exemple, issue d'un bloc-texte).
2. Choisir une profondeur convenable (paramètre depth). En pratique, pour un petit échantillon de texte, depth=2
sera satisfaisant et très rapide. La chaîne de Markov forme alors des états représentant les couples de caractères. Comme nous allons le voir, cela suffit à éliminer presque toutes les scories produites par un mélange strictement aléatoire.
3. Invoquer $$.Markov( S, depth )
pour créer ladite chaîne de Markov, basée sur le texte S
.
4. Appeler result = $$.Markov.run()
pour construire un nouveau texte. Cette opération se fonde implicitement sur une fonction de rappel (callback) prélevant des caractères au hasard au sein de la chaîne de Markov ; le processus s'arrête automatiquement quand la valeur de retour a la même taille que le texte d'origine.
5. Remplacer le texte d'origine par la valeur de retour de l'étape 4.
Le script final ne comporte qu'une trentaine de lignes tout compris. (Notez en passant l'inclusion du module Random
qui, pour être tout à fait facultatif dans ce contexte, améliore sensiblement les caractéristiques des fonctions aléatoires.)
// Point d'entree IdExtenso et inclusion des modules // --- #include '../$$.jsxinc' #include '../etc/$$.Random.jsxlib' #include '../etc/$$.Markov.jsxlib' $$.load(); try { const DEPTH = 2; var t, sto, n; t = (t=app.properties.selection) && t.length && t[0]; if( t && (t instanceof TextFrame) ) { t = (sto=t.parentStory).texts[0].contents; if( DEPTH < (n=t.length) && $$.Markov(t,DEPTH) ) { t = $$.Markov.run(); app.scriptPreferences.enableRedraw = false; sto.texts[0].contents = t; app.scriptPreferences.enableRedraw = true; } } else { alert(__("Veuillez sélectionner un bloc-texte.")); } } catch(e) { $$.receiveError(e); } $$.unload();
Voyons comment se comporte notre nouveau brouilleur :
Vous m'accorderez que le résultat obtenu, quoique totalement charabiesque, semble beaucoup plus fidèle, par sa forme, ses proportions, au matériau initial. Voilà toute la saveur des chaînes de Markov !
Note. — Le code source est disponible sur GitHub dans le cadre du projet IdExtenso. Mais, si vous ne souhaitez pas installer le framework, une version « autonome » du script est également disponible (voir option ci-dessous).
Comments
Bonjour, je cherche un script dans indesign permettant d'afficher des repères selon la règle du nombre d'or. Cela existe-t-il ? Comment créer un pareil script?
Merci