Comment modifier discrètement le rendu du texte?

12

J'écris une extension emacs à utiliser avec la reconnaissance vocale, et je cherche de l'aide avec une fonctionnalité particulière. Certains mots que le logiciel de reconnaissance vocale (Dragon) ne reconnaît pas toujours correctement - peu importe le nombre de fois que vous l'entraînez, il suffira de reconnaître certains mots. En même temps, généralement, lorsque vous écrivez sur un sujet ou lors du codage, vous utiliserez maintes et maintes fois les mêmes mots.

J'ai donc écrit un mode qui utilise des superpositions pour changer la façon dont les mots sont rendus dans le tampon. Il prend une lettre au hasard dans le mot, la souligne dans une couleur aléatoire et met une marque diacritique aléatoire (accent, tréma, etc.) par-dessus. Voici une capture d'écran (vous devrez probablement zoomer pour voir les marques / soulignements):

entrez la description de l'image ici

Ensuite, vous pouvez dire «cheveux violet p» et il recherchera le mot avec un soulignement violet sous son «a» avec une marque diacritique qui ressemble à des cheveux et tapez ce mot pour vous. Donc, dans la capture d'écran ci-dessus, cela indique qu'emacs tapera "regexp-quote" pour vous.

L'idée est que cela vous permet de vous référer à n'importe quel mot que vous avez déjà utilisé qui est à l'écran en utilisant un ensemble fini de mots que le programme de reconnaissance est toujours bon à reconnaître.

Cela fonctionne plutôt bien, sauf qu'il y a parfois une collision. Pour que je puisse apprendre à faire référence aux mots de la même manière que j'utilise les octets du hachage md5 du mot au lieu de (random)ou qu'un algorithme attribue les changements de manière à éviter les collisions. Je n'ai trouvé que 6 couleurs facilement reconnaissables (c'est difficile lorsque le soulignement n'a qu'un caractère de large et un seul pixel d'épaisseur) et 3 marques diacritiques facilement reconnaissables (faciles à distinguer les unes des autres et non confondables avec un soulignement ci-dessus) ou chevauchement avec le soulignement), vu en haut de la source ci-dessus.

J'ai besoin de plus de façons de modifier le rendu afin de réduire la fréquence des collisions. Idéalement, une modification de rendu:

  • Ne vous ébranlez pas du reste du texte. Cela m'a conduit à rejeter par exemple la propriété vidéo inverse.
  • Ne pas être facilement confondu avec d'autres changements. Les surlignages sont facilement confondus avec les soulignements de la ligne précédente. Beaucoup de signes diacritiques se ressemblent, sauf si la taille de votre police n'est pas énorme.
  • Soyez spatialement près des autres changements. En ce moment, une fois que mon œil a trouvé le personnage ciblé, toutes les informations sont là, le marqueur, le soulignement et la lettre.
  • Fonctionne bien avec une police à largeur fixe (nécessaire pour le codage) qui rend correctement les marques diacritiques (j'ai dû passer à DejaVu Sans Mono de Consolas pour que les marques soient correctement rendues)
  • Travail sur les lettres de l'alphabet latin. Il y a des marques de combinaison arabe par exemple, mais elles ne se combinent pas sur les caractères de l'alphabet latin.
  • Ne change pas la couleur des lettres, car cela est déjà utilisé pour la coloration syntaxique.
  • En fait être faisable dans emacs avec emacs lisp;)

Peut-être existe-t-il des caractères unicode spéciaux contrôlant le rendu qui pourraient être utilisés abusivement pour ouvrir de nouvelles possibilités? Ou un moyen d'épaissir les soulignements pour que je puisse facilement distinguer plus de couleurs? Ou une autre fonctionnalité emacs obscure vous permettant de rendre des marques au-dessus des caractères en plus de l'unicode?

Joseph Garvin
la source
Pas une réponse directe à votre question, mais peut-être quelques idées utilisant des superpositions pour donner de nouvelles apparences aux personnages. Une idée serait de concaténer / prendre en sandwich deux superpositions - en les forçant à s'insérer dans le même espace qu'un caractère normal - par exemple, le premier caractère est une fine ligne avec de la couleur ajoutée (char-to-string ?\uFEFF)et l'autre est un caractère cible qui est réduit en taille pour qu'ils s'adaptent tous les deux. Une autre idée serait d'utiliser un barrage vertical (disponible dans certaines polices, mais pas toutes) similaire à ce qui est utilisé dans la bibliothèque vline.el emacswiki.org/emacs/VlineMode
lawlist
@lawlist: Cette idée de ligne unicode est intéressante, elle me permettrait de faire une 'ligne de touche'. Avez-vous une idée de comment réduire la taille du caractère suivant? Je pourrais peut-être générer une image à utiliser avec la propriété d'affichage, mais AFAICT, il n'y a aucun moyen d'obtenir qu'emacs rende le texte dans une image, donc je devrais faire les images en dehors d'emacs.
Joseph Garvin
Ce commentaire remplace le commentaire précédent (que j'ai supprimé), et le code dans le lien suivant a également été mis à jour - il contient trois exemples (dont l'un est identique à la réponse que j'ai postée ci-dessous dans le fil de discussion actuel): stackoverflow .com / questions / 23744237 /…
lawlist

Réponses:

4

Une autre possibilité serait d'afficher les numéros de ligne et de dire le numéro de ligne avant le mot, ou, puisque chercher pour obtenir le numéro de ligne exact serait gênant, vous pourriez avoir la recherche d'algorithme dans + ou - 5 ou 10 lignes du numéro que vous dire.

Ou peut-être déclarer une région ou une fonction dans laquelle vous travaillez et faire en sorte que toutes les recherches n'y regardent que. Je suppose que cela limiterait les collisions.

Vous pouvez également restituer des symboles Unicode après ou avant un mot dans une couleur donnée pour les aider à se démarquer. Et aussi encadrer ou souligner le mot dans une autre couleur. De cette façon, vous pourriez avoir 6 couleurs de mots * 6 couleurs de symboles * N possibilités de symboles. Vous pourriez probablement trouver 10 bons symboles et avoir 360 combinaisons. Par exemple, vous pourriez dire «étoile bleu jaune» pour faire référence au mot chat ici.

entrez la description de l'image ici

Si l'étoile est trop choquante, vous pouvez coupler: boîte et deux différents: soulignements.

Vous pouvez donc vous référer à l'arbre des mots ici en utilisant "bleu jaune rouge" qui vous donnerait 216 combinaisons à utiliser.

entrez la description de l'image ici

Jordon Biondo
la source
1
J'ai attendu un moment pour voir si quelqu'un proposerait d'autres astuces, mais je vais probablement choisir la double couleur de soulignement, car l'ajout de symboles peut annuler l'indentation. Accepté, merci.
Joseph Garvin
2

Avez-vous entendu parler du mode ace-jump ?

Il ne répond à aucune des exigences que vous spécifiez, mais il semble qu'il s'adapte parfaitement à ce que vous essayez d'atteindre. Cela permettrait à l'utilisateur de spécifier n'importe quel mot en disant seulement 2 ou 3 mots.

Vous pouvez définir l'ensemble des caractères qu'il vous propose, afin d'éviter les consonnes difficiles à distinguer. Ensuite, l'utilisation pourrait simplement dire "fixer un neuf" et corriger le 9ème mot qui commence par a.

Malabarba
la source
Voir mon commentaire sur le post de tmalsburg pour savoir pourquoi le mode ace-jump n'a pas fonctionné.
Joseph Garvin
1

Question interessante. Je parie que vous obtiendrez des suggestions intéressantes.

Une suggestion mineure qui me vient à l'esprit est d'utiliser différentes couleurs et styles pour souligner. Consultez le manuel Elisp, noeud Face Attributessur les attributs :underlineet ses :coloret :stylecomposants.

Vous pouvez également expérimenter avec l'attribut :boxet différentes largeurs de ligne et styles pour cela, mais c'est peut-être trop choquant.

A dessiné
la source
1

Je répondrai en proposant une autre manière de sélectionner le mot cible. Mettez en surbrillance la moitié des mots (choisis au hasard). L'utilisateur dit «oui» si le mot cible est mis en surbrillance et «non» sinon. Si l'utilisateur a dit "oui", prenez tous les mots qui ont été mis en surbrillance et mettez en surbrillance au hasard la moitié d'entre eux. Si l'utilisateur a dit «non», mettez en surbrillance au hasard la moitié des mots qui n'ont pas été mis en surbrillance. Encore une fois, l'utilisateur indique si le mot cible est mis en surbrillance en disant «oui» ou «non». Répétez cette opération jusqu'à ce que seul le mot cible soit mis en surbrillance.

Quelques avantages de cette approche:

  • Cela fonctionne, peu importe le nombre de mots que vous avez à l'écran.
  • Vous n'avez pas besoin de couleurs, de polices ou de symboles fantaisistes. Un écran monochrome suffit.
  • Charge cognitive très faible car il est facile de savoir si un mot est mis en surbrillance ou non.

Inconvénient: vous devez dire «oui» et «non» trop souvent. Cependant, cela est corrigé par la variation suivante de l'idée: ne mettez pas en surbrillance les mots mais utilisez des couleurs pour eux. Vous dites que vous avez 6 couleurs facilement reconnaissables. Cela signifie que si vous avez 100 mots à l'écran, la sélection du mot cible nécessite de nommer 2,6 couleurs en moyenne. S'il y a 1000 mots, vous devez nommer 3,9 couleurs en moyenne.

tmalsburg
la source
1
Malheureusement, le nombre de mots prononcés est une mesure trompeuse. Le problème avec ce style de solution est qu'il contient des allers-retours perception / action. Je dois voir la couleur, puis réagir, puis voir, réagir, voir. Dire 3 mots sans avoir à s'arrêter pour regarder entre chacun est plus rapide dans la pratique qu'une solution où vous le faites, surtout avec Dragon ayant une faible latence. Si ces allers-retours n'étaient pas un problème, j'utiliserais simplement le mode ace-jump. Avec les signes diacritiques, je peux regarder l'écran une fois et connaître toute la chaîne de ce que je dois dire sans avoir à faire une pause pour que Dragon réagisse après chaque mot.
Joseph Garvin
1

Voici un exemple d'utilisation d'une superposition avec une image xpm pour les versions graphiques d'Emacs qui prennent en charge le format d'image xpm. Il fait 11 pixels de large; 20 pixels de haut; et a un nombre spécifié par l'utilisateur de 4 couleurs possibles. Je suis sur un Mac exécutant Snow Leopard 10.6.8 et la police que je préfère lorsque j'utilise Emacs est -*-Courier-normal-normal-normal-*-18-*-*-*-m-0-iso10646-1- le frame-char-width11 et le frame-char-height20. J'ai ajouté une fine ligne verticale jaune à gauche de la lettre majuscule "A" comme exemple de la façon de dessiner des images personnalisées. La substitution du caractère au point peut être effectuée par programme en utilisant (char-after (point))et en prenant ce nombre - qui dans ce cas est 65 pour la lettre majuscule "A" - et en remplaçant la variable appropriée - par exemple, (cond ((eq (char-after (point)) 65) cap-ltr-a-xpm) . . .- et en utilisant cette variable dans le placement de la superposition - par exemple,(overlay-put (make-overlay (point) (1+ (point))) 'display cap-ltr-a-xpm). Cela fonctionne très bien pour les tampons tronqués et aussi pour le retour à la ligne car la displaypropriété de superposition sur un caractère au milieu d'un mot ne fait pas penser au retour à la ligne que la première partie du mot appartient à la fin de la ligne précédente. . Bien sûr, il faudra du temps pour créer une bibliothèque personnalisée d'images xpm préférées.

ImageMagick est capable de produire un xpm semi-précis d'un caractère particulier basé sur une famille et une taille de police spécifiques, mais ce n'était pas aussi précis que je l'espérais - voici un lien vers des instructions pour utiliser cet utilitaire externe: https: / /stackoverflow.com/a/14168154/2112489 En un mot, l'utilisateur doit être prêt à consacrer du temps à la personnalisation des images xpm à son goût.

(defun xpm-example ()
(interactive)
"Doc-string"
  (let* (
      (cap-ltr-a-xpm `(image :type xpm :mask nil :ascent center :data
        "/* XPM */
        static char * letters_xpm[] = {
        /* columns rows colors chars-per-pixel */
        /* columns = 1 pixel in width -- see also (frame-char-width) */
        /* rows = 1 pixel in height -- see also (frame-char-height) */
        \"11 20 4 1\",
        \". c #000000\",
        \"+ c #FF0000\",
        \"@ c #7F0000\",
        \"% c yellow\",
        \"%..........\",
        \"%....++....\",
        \"%....++....\",
        \"%..++..++..\",
        \"%..++..++..\",
        \"%++......++\",
        \"%++......++\",
        \"%++......++\",
        \"%++......++\",
        \"%++......++\",
        \"%++......++\",
        \"%++++++++++\",
        \"%++++++++++\",
        \"%++......++\",
        \"%++......++\",
        \"%++......++\",
        \"%++......++\",
        \"%++......++\",
        \"%++......++\",
        \"%..........\"};"))  )
    (overlay-put (make-overlay (point) (1+ (point))) 'display cap-ltr-a-xpm)))
liste des lois
la source
@wasamasa - merci - j'ai supprimé la déclaration erronée concernant les bitmaps XBM.
lawlist