Modi per variare in modo discreto il rendering del testo?


12

Sto scrivendo un'estensione emacs da utilizzare con il riconoscimento vocale e sto cercando aiuto con una particolare funzione. Alcune parole che il riconoscimento vocale (Dragon) riconosce costantemente in modo scadente - non importa quante volte lo alleni, farà semplicemente schifo nel riconoscere determinate parole. Allo stesso tempo, di solito quando scrivi su un argomento o quando scrivi un codice utilizzerai molte delle stesse parole più e più volte.

Quindi ho scritto una modalità che utilizza le sovrapposizioni per modificare il modo in cui le parole vengono visualizzate nel buffer. Prende una lettera casuale nella parola, la sottolinea in un colore casuale e mette un segno diacritico casuale (accento, umlaut, ecc.) Sopra di esso. Ecco uno screenshot (probabilmente dovrai ingrandire per vedere segni / sottolineature):

inserisci qui la descrizione dell'immagine

Quindi puoi dire "p capelli viola" e cercherà la parola con una sottolineatura viola sotto la sua 'a' con un segno diacritico che assomiglia a capelli e digita quella parola per te. Quindi nello screenshot sopra che dice che farebbe emacs digitare "regexp-quote" per te.

L'idea è che questo ti permetta di fare riferimento a qualsiasi parola che hai già usato sullo schermo usando un insieme finito di parole che il riconoscitore è costantemente bravo a riconoscere.

Funziona abbastanza bene, tranne che occasionalmente c'è una collisione. Per farlo, posso imparare a fare costantemente riferimento alle parole nello stesso modo in cui sto usando i byte dell'hash md5 della parola anziché (random)o facendo in modo che un algoritmo assegni le modifiche in modo da evitare le collisioni. Ho trovato solo 6 colori facilmente distinguibili (è difficile quando la sottolineatura è larga solo un carattere e spessa un solo pixel) e 3 segni diacritici facilmente distinguibili (facili da distinguere l'uno dall'altro e anche non confondibili con una sottolineatura di cui sopra linea o sovrapposizione con la sottolineatura), visualizzato nella parte superiore della fonte sopra.

Ho bisogno di più modi per modificare il rendering al fine di ridurre la frequenza di collisione. Idealmente una modifica del rendering dovrebbe:

  • Non essere stonato dal resto del testo. Questo mi ha portato ad eliminare, ad esempio, la proprietà del video inverso.
  • Non essere facilmente confondibile con altre modifiche. Le sottolineature possono essere facilmente scambiate per sottolineature nella riga precedente. Molti segni diacritici sembrano simili a meno che la dimensione del carattere non sia incredibilmente grande.
  • Essere spazialmente vicino a dove sono gli altri cambiamenti. In questo momento, una volta che il mio occhio trova il personaggio bersaglio, tutte le informazioni sono lì, il marcatore, la sottolineatura e la lettera.
  • Funziona bene con un carattere a larghezza fissa (necessario per la codifica) che esegue correttamente il rendering dei segni diacritici (ho dovuto passare a DejaVu Sans Mono da Consolas per avere il rendering corretto dei segni)
  • Lavora su lettere dell'alfabeto latino. Ci sono segni di combinazione arabi per esempio, ma non si combinano su caratteri alfabetici latini.
  • Non cambiare il colore delle lettere, poiché è già utilizzato per l'evidenziazione della sintassi.
  • Effettivamente fattibile in emacs con emacs lisp;)

Forse ci sono speciali caratteri unicode che controllano il rendering che potrebbero essere abusati per aprire nuove possibilità? O un modo per addensare le sottolineature in modo da poter distinguere facilmente più colori? O qualche altra caratteristica oscura di emacs che ti consente di rendere segni sopra i personaggi oltre all'unicode?


Non una risposta diretta alla tua domanda, ma forse un paio di idee che usano sovrapposizioni per dare nuove apparenze ai personaggi. Un'idea sarebbe quella di concatenare / mettere insieme due sovrapposizioni - costringendoli a adattarsi allo stesso spazio di un personaggio normale - ad esempio, il primo personaggio è una linea sottile con colore aggiunto (char-to-string ?\uFEFF)e l'altro è un personaggio bersaglio che è ridotto in dimensioni in modo che si adattino entrambi. Un'altra idea sarebbe quella di utilizzare un barrato verticale (disponibile in alcuni caratteri, ma non tutti) simile a quello che viene utilizzato nella libreria vline.el emacswiki.org/emacs/VlineMode
elenco della legge

@lawlist: l'idea di una linea unicode è interessante, mi permetterebbe di fare una "linea laterale". Hai idea di come ridurre le dimensioni del seguente personaggio? Potrei forse generare un'immagine da usare con la proprietà display ma AFAICT non c'è modo di ottenere emacs per rendere il testo in un'immagine, quindi dovrei rendere le immagini esterne a emacs.
Joseph Garvin,

Questo commento sostituisce il commento precedente (che ho rimosso) e anche il codice nel seguente link è stato aggiornato - contiene tre esempi (uno dei quali è identico alla risposta che ho pubblicato di seguito nel thread corrente): stackoverflow .com / questions / 23744237 /…
elenco delle leggi

Risposte:


4

Un'altra possibilità sarebbe quella di visualizzare i numeri di riga e pronunciare il numero di riga prima della parola, oppure, dato che guardare oltre per ottenere il numero di riga esatto sarebbe fastidioso, si potrebbe avere la ricerca dell'algoritmo all'interno di + o - 5 o 10 righe del numero che si dire.

O forse dichiarare una regione o una funzione in cui si sta lavorando e fare in modo che tutte le ricerche guardino solo lì. Immagino che ciò limiterebbe le collisioni.

Puoi anche rendere i simboli unicode dopo o prima di una parola in un determinato colore per farli risaltare. E anche box o sottolineare la parola in un altro colore. In questo modo potresti avere 6 colori di parole * 6 colori di simboli * Possibilità di simboli N. Probabilmente potresti trovare 10 buoni simboli e avere 360 ​​combinazioni. Ad esempio, potresti dire "stella gialla blu" per fare riferimento alla parola gatto qui.

inserisci qui la descrizione dell'immagine

Se la stella è troppo stonata, puoi accoppiare: riquadro e due diversi: sottolinea.

Quindi puoi fare riferimento all'albero delle parole qui usando "blu giallo rosso" che ti darebbe 216 combinazioni da usare.

inserisci qui la descrizione dell'immagine


1
Ho aspettato un po 'per vedere se qualcuno avrebbe escogitato altri trucchi, ma probabilmente andrò con il doppio colore di sottolineatura poiché l'aggiunta di simboli può eliminare il rientro. Accettato, grazie.
Joseph Garvin,

2

Hai mai sentito parlare della modalità asso-salto ?

Non soddisfa nessuno dei requisiti specificati, ma sembra corrispondere perfettamente a ciò che stai cercando di ottenere. Consentirebbe all'utente di specificare qualsiasi parola pronunciando solo 2 o 3 parole.

Puoi definire l'insieme di caratteri che ti offre, in modo da evitare le consonanti che sono difficili da distinguere. Quindi l'uso potrebbe semplicemente dire "correzione A nove" e correggere la nona parola che inizia con a.


Vedi il mio commento sul post di tmalsburg per il motivo per cui l'asso-jump-mode non ha funzionato.
Joseph Garvin,

1

Domanda interessante. Scommetto che otterrai alcuni suggerimenti interessanti.

Un piccolo suggerimento che mi viene in mente è di usare colori e stili diversi per sottolineare. Vedere l'Elisp manuale, nodo Face Attributesattributo about :underlineei suoi :colore :stylecomponenti.

Puoi anche sperimentare attributi :boxe larghezze di linea e stili diversi, ma forse è troppo stonante.


1

Risponderò proponendo un modo alternativo per selezionare la parola target. Evidenzia la metà delle parole (scelte casualmente). L'utente dice "sì" se la parola target è evidenziata e "no" altrimenti. Se l'utente ha detto "sì", prendi tutte le parole che sono state evidenziate ed evidenzia a caso metà di esse. Se l'utente ha detto "no", evidenzia in modo casuale la metà delle parole che non sono state evidenziate. Ancora una volta l'utente indica se la parola target viene evidenziata dicendo "sì" o "no". Ripeti finché non viene evidenziata solo la parola target.

Alcuni vantaggi di questo approccio:

  • Funziona, indipendentemente da quante parole hai sullo schermo.
  • Non hai bisogno di colori, caratteri o simboli fantasiosi. È sufficiente un display monocromatico.
  • Carico cognitivo molto basso perché è facile dire se una parola è evidenziata o meno.

Svantaggio: devi dire "sì" e "no" troppo spesso. Tuttavia, questo è risolto dalla seguente variazione dell'idea: non evidenziare le parole ma usare i colori per esse. Dici di avere 6 colori facilmente distinguibili. Ciò significa che se hai 100 parole sullo schermo, selezionare la parola target richiede in media un nome di 2,6 colori. Se ci sono 1000 parole, devi nominare in media 3,9 colori.


1
Purtroppo il numero di parole pronunciate è una metrica fuorviante. Il problema con questo stile di soluzione è che contiene round di percezione / azione. Devo vedere il colore, quindi reagire, quindi vedere, reagire, vedere. Dire 3 parole senza doversi fermare a guardare tra una e l'altra deve essere più veloce nella pratica di una soluzione in cui lo si fa, specialmente con Dragon che ha una bassa latenza. Se questi round trip non fossero un problema, utilizzerei semplicemente la modalità asso-salto. Con i segni diacritici posso guardare lo schermo una volta e conoscere l'intera stringa di ciò che devo dire senza dover fare una pausa affinché Dragon reagisca dopo ogni parola.
Joseph Garvin,

1

Di seguito è riportato un esempio che utilizza un overlay con un'immagine xpm per le versioni grafiche di Emacs che supportano il formato immagine xpm. È largo 11 pixel; 20 pixel di altezza; e ha un numero specificato dall'utente di 4 colori possibili. Sono su un Mac con Snow Leopard 10.6.8 e il carattere che preferisco quando utilizzo Emacs è -*-Courier-normal-normal-normal-*-18-*-*-*-m-0-iso10646-1: l' frame-char-width11 e l' frame-char-height20. Ho aggiunto una sottile linea gialla verticale a sinistra della lettera maiuscola "A" come un esempio di come disegnare immagini personalizzate. La sostituzione del carattere in questo punto può essere effettuata a livello di (char-after (point))codice usando e prendendo quel numero - che in questo caso è 65 per la lettera maiuscola "A" - e sostituendo la variabile appropriata - ad es. (cond ((eq (char-after (point)) 65) cap-ltr-a-xpm) . . .- e usando quella variabile nel posizionamento overlay - ad es.(overlay-put (make-overlay (point) (1+ (point))) 'display cap-ltr-a-xpm). Funziona molto bene sia con i buffer troncati che con il ritorno a capo automatico poiché la displayproprietà overlay su un carattere nel mezzo di una parola non fa pensare che il ritorno a capo automatico ritenga che la prima parte della parola appartenga alla fine della riga precedente . Naturalmente, ci vorrà del tempo per creare una libreria personalizzata di immagini xpm preferite.

ImageMagick è in grado di produrre un xpm semi-accurato di un particolare personaggio basato su una famiglia e una dimensione di font specifiche, ma non era preciso come avevo sperato - ecco un link alle istruzioni per l'uso di quell'utilità esterna: https: / /stackoverflow.com/a/14168154/2112489 In poche parole, l'utente dovrebbe essere pronto a passare il tempo a personalizzare le immagini xpm a proprio piacimento.

(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)))

@wasamasa - grazie - ho rimosso l'errata dichiarazione relativa alle bitmap XBM.
elenco delle leggi del
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.