Pourquoi les symboles Markdown ne s’affichent que dans le mot où se trouve le curseur
Vous est-il déjà arrivé de placer le curseur pour corriger un seul mot en gras et de voir tout le paragraphe revenir au Markdown source ? mote ne révèle que les symboles de la syntaxe touchée par le curseur.

Dans le mode live, la position du curseur détermine ce qui apparaît à l’écran. Les symboles Markdown doivent rester masqués en temps normal et n’apparaître que lorsqu’on les modifie.
Mais comment savoir quand on est en train de « modifier » quelque chose ?
Au début, mote prenait le paragraphe entier comme référence. Dès que le curseur entrait dans un paragraphe, tous les symboles de celui-ci s’affichaient.
L’implémentation était simple, mais l’écran devenait chargé. Il suffisait de placer le curseur pour corriger un seul mot en gras, et même le lien et le code situés trois lignes plus bas revenaient à leur forme source. Le regard restait fixé sur un point, mais tout le paragraphe bougeait.
Regarder la syntaxe, pas le paragraphe
Désormais, mote n’affiche que la syntaxe en contact avec le curseur.
La forme source n’apparaît que lorsque le curseur se trouve entre le symbole ouvrant et le symbole fermant. Les positions immédiatement avant et après les symboles sont également comprises dans cette zone. Placer le curseur à cet endroit constitue aussi une action visant à modifier la syntaxe.
Dès que le curseur s’en éloigne d’un seul caractère, l’affichage revient à sa forme rendue. L’apparition et la disparition utilisent une transition d’opacité de 120 ms. Comme cette transition possède un début et une fin, elle ne laisse aucune trace une fois terminée.
Même si un paragraphe contient à la fois du gras, un lien et du code en ligne, le reste ne bouge pas. Seule la syntaxe touchée par le curseur change, et le redessin se limite à cette ligne. Le document entier n’est pas réinterprété.
Le même principe s’applique à l’italique, au gras, au texte barré, au surlignage, aux indices, aux exposants, au code, aux formules, aux liens, aux images et aux références de notes de bas de page.
Les symboles placés en début de ligne fonctionnent un peu différemment. Comme # et > définissent la nature de toute la ligne, ils conservent le même aspect où que se trouve le curseur sur celle-ci. En revanche, le - d’une liste n’est révélé que lorsque le curseur se trouve sur le symbole. Dès que le curseur dépasse l’espace et entre dans le corps du texte, il redevient immédiatement une puce.
Lorsqu’un texte est sélectionné, seules les syntaxes qui chevauchent la sélection reviennent également à leur forme source. Si toute une ligne se transforme en source alors que seuls trois caractères sont sélectionnés, il devient au contraire plus difficile de savoir ce qui a été sélectionné.
Les symboles adoptent eux aussi l’apparence des caractères
Les symboles révélés reprennent le style de la syntaxe.
Les ** d’un texte en gras apparaissent en gras, et les * de l’italique apparaissent en italique. Les ~~ du texte barré sont eux aussi traversés par un trait.

*. Les astérisques sont eux aussi inclinés, tandis que le texte en gras et le code en ligne présents sur la même ligne conservent leur forme rendue.Auparavant, tous les symboles étaient affichés en gris. Lorsqu’on plaçait le curseur sur du texte en gras, le mot semblait alors enfermé entre des parenthèses grises. L’indication que le texte en cours de modification était en gras disparaissait elle aussi momentanément.
En appliquant aux symboles le style des caractères, leur signification est devenue plus claire. Le mot continue d’apparaître en gras, tandis que les astérisques ne servent plus qu’à indiquer l’étendue de la syntaxe.
Le gris est réservé aux symboles de bloc comme #, > et les puces. Ces symboles décrivent la nature de la ligne plutôt que celle des caractères.
Le principe est simple. Les symboles attachés aux caractères sont affichés comme s’ils faisaient partie de ceux-ci, tandis que ceux qui définissent la ligne sont présentés comme un arrière-plan.
Seuls les astérisques sont automatiquement appariés
Lorsqu’on saisit un astérisque, un astérisque fermant est créé en même temps. Si l’on saisit un astérisque supplémentaire, la paire s’étend pour former du gras.
Lorsqu’on saisit l’astérisque fermant après avoir écrit le contenu, aucun nouveau symbole n’est créé : le curseur passe par-dessus le symbole existant. Cette règle a également résolu le problème qui faisait apparaître les astérisques par groupes de quatre.
Toutefois, un astérisque saisi juste après un caractère ou un autre astérisque est considéré comme une fermeture manuelle de la syntaxe par l’utilisateur. Dans ce cas, aucune paire n’est créée.
Les traits de soulignement et les tildes ne sont pas automatiquement appariés. Ils risqueraient de gêner la saisie de chaînes courantes comme snake_case, __init__ ou ~/경로. Ils fonctionnent par paire uniquement lorsqu’ils servent à entourer le texte sélectionné.
Le caret doit être moins visible que les caractères
Au début, le caret était bleu, la couleur d’accentuation. Il utilise désormais la même couleur d’encre que le corps du texte.
Une barre bleue convient bien aux champs de saisie courts. Mais dans un document, les caractères sont au premier plan. Il suffit que le caret indique jusqu’où le texte a été saisi. La couleur d’accentuation est désormais réservée aux sélections et aux résultats de recherche.
Sa largeur est déterminée en divisant la hauteur du caret par la hauteur d’encre du corps du texte, puis en arrondissant le résultat à l’entier le plus proche. Elle est de 1 px dans le corps du texte et ne passe à 2 px que dans les grands titres. Si une largeur décimale était utilisée telle quelle, elle se répartirait sur deux colonnes de pixels et paraîtrait épaisse et floue au lieu d’être fine.
Sa hauteur suit celle des caractères, et non l’interligne. Elle est de 18 px dans le corps du texte, de 24 px dans un h3, de 29 px dans un h2 et de 36 px dans un h1. Le caret suffit ainsi à savoir si le curseur se trouve dans le corps du texte ou dans un titre.

Le clignotement est défini comme l’unique exception à la règle interdisant de laisser une source répétitive active au repos. Lorsque la fenêtre perd le focus, le clignotement s’arrête et la sélection s’efface elle aussi jusqu’à une opacité de 45 %.
Le décalage a été conservé
Lorsque les symboles apparaissent, les caractères qui les suivent se décalent légèrement. Nous avons choisi de conserver ce mouvement.
Nous avons aussi essayé de réserver leur espace en affichant constamment les symboles masqués dans un gris pâle. Mais un résidu gris restait alors autour du texte en gras, tandis que les marques du texte barré dépassaient du mot. Le résultat se trouvait dans un état maladroit, qui n’était ni l’affichage rendu ni la forme source.
En revanche, pour les symboles de début de ligne accompagnés d’un élément dessiné, comme les puces et les cases de tâches, la ligne est déplacée d’une distance égale à la différence de largeur entre la source et le rendu. Les caractères du corps du texte ne bougent donc pas lorsque le symbole est révélé. Pour le # des titres et le > des citations, nous avons conservé le déplacement du corps du texte. Cette décision repose sur la familiarité des éditeurs qui fonctionnent ainsi.
Comme l’adresse d’un lien peut être longue, les changements à l’écran peuvent être plus importants. C’est pourquoi seul le texte du lien est normalement affiché, accompagné d’une petite flèche à la fin. On peut ainsi savoir qu’il s’agit d’un lien, mais son adresse n’apparaît que lorsqu’on la modifie.
Pour examiner précisément la source, il suffit d’utiliser le mode source. Le mode live n’est pas un endroit où tous les symboles sont affichés, mais un endroit qui n’ouvre que ce que l’on est en train de modifier.
mote ne cherche pas à deviner l’intention de l’utilisateur. Si le curseur se trouve à l’intérieur d’une syntaxe, les symboles s’affichent ; s’il se trouve à l’extérieur, ils sont masqués. Une supposition est pratique lorsqu’elle est juste, mais lorsqu’elle se trompe, il est difficile d’en comprendre la raison. En utilisant la position comme unique critère, le résultat reste toujours prévisible.
Décider quand afficher les symboles revient finalement à décider où doit se poser le regard de l’utilisateur.