Möglichkeiten, die Textwiedergabe unauffällig zu variieren?

12

Ich schreibe eine Emacs-Erweiterung für die Spracherkennung und suche Hilfe bei einer bestimmten Funktion. Einige Wörter erkennt der Spracherkenner (Dragon) durchweg schlecht - es spielt keine Rolle, wie oft Sie ihn trainieren, er wird nur beim Erkennen bestimmter Wörter nerven. In der Regel werden beim Schreiben eines Themas oder beim Codieren immer wieder dieselben Wörter verwendet.

Deshalb habe ich einen Modus geschrieben, der Überlagerungen verwendet, um zu ändern, wie Wörter im Puffer gerendert werden. Es nimmt einen zufälligen Buchstaben in das Wort auf, unterstreicht es in einer zufälligen Farbe und setzt eine zufällige diakritische Markierung (Akzent, Umlaut usw.) darüber. Hier ist ein Screenshot (Sie müssen wahrscheinlich zoomen, um Markierungen / Unterstreichungen zu sehen):

Bildbeschreibung hier eingeben

Dann können Sie sagen, "lila Haare" und es wird nach dem Wort mit einem lila Unterstrich unter dem "a" mit einem diakritischen Zeichen, das wie Haar aussieht, gesucht und das Wort für Sie eingegeben. In dem obigen Screenshot würde dies dazu führen, dass Emacs "regexp-quote" für Sie eingibt.

Die Idee ist, dass Sie auf jedes Wort verweisen können, das Sie bereits verwendet haben und das auf dem Bildschirm mit einer endlichen Menge von Wörtern angezeigt wird, die der Erkenner durchweg gut erkennt.

Es funktioniert ziemlich gut, außer dass es gelegentlich zu einer Kollision kommt. Um dies so zu gestalten, dass ich lernen kann, konsequent auf Wörter zu verweisen, wie ich Bytes aus dem md5-Hash des Wortes verwende, anstatt (random)die Änderungen durch einen Algorithmus so zuzuweisen, dass Kollisionen vermieden werden. Ich habe nur 6 leicht unterscheidbare Farben gefunden (es ist schwierig, wenn die Unterstreichung nur ein Zeichen breit und ein Pixel dick ist) und 3 leicht unterscheidbare diakritische Zeichen (leicht voneinander zu unterscheiden und auch nicht mit einer Unterstreichung zu verwechseln) Linie oder Überlappung mit der Unterstreichung), oben in der Quelle oben zu sehen.

Ich benötige mehr Möglichkeiten zum Ändern des Renderings, um die Kollisionshäufigkeit zu verringern. Im Idealfall würde eine Rendering-Änderung:

  • Nicht vom Rest des Textes abschrecken. Dies hat mich veranlasst, beispielsweise die Inverse-Video-Eigenschaft zu verwerfen.
  • Nicht leicht mit anderen Änderungen zu verwechseln. Overlines werden in der vorherigen Zeile leicht mit Unterstrichen verwechselt. Viele diakritische Zeichen sehen ähnlich aus, es sei denn, Ihre Schriftgröße ist unpraktisch groß.
  • Seien Sie räumlich in der Nähe der anderen Veränderungen. Sobald mein Auge den Zielcharakter gefunden hat, sind alle Informationen vorhanden, die Markierung, die Unterstreichung und der Buchstabe.
  • Arbeiten Sie gut mit einer Schriftart mit fester Breite (für die Codierung erforderlich), die diakritische Zeichen korrekt wiedergibt (ich musste von Consolas zu DejaVu Sans Mono wechseln, damit die Zeichen korrekt wiedergegeben werden).
  • Arbeiten Sie an lateinischen Buchstaben. Es gibt zum Beispiel arabische Kombinationszeichen, die sich jedoch nicht mit lateinischen Buchstaben kombinieren lassen.
  • Buchstabenfarbe nicht ändern, da dies bereits für die Syntaxhervorhebung verwendet wird.
  • Eigentlich machbar in emacs mit emacs lispel;)

Vielleicht gibt es spezielle Unicode-Zeichen, die das Rendern steuern und die missbraucht werden könnten, um neue Möglichkeiten zu eröffnen? Oder eine Möglichkeit, die Unterstreichungen zu verdicken, damit ich möglicherweise problemlos mehr Farben unterscheiden kann? Oder eine andere obskure Emacs-Funktion, mit der Sie neben Unicode Markierungen auf Zeichen rendern können?

Joseph Garvin
quelle
Keine direkte Antwort auf Ihre Frage, aber vielleicht ein paar Ideen, die Overlays verwenden, um neuen Charakteren das Aussehen zu verleihen. Eine Idee wäre, zwei Overlays zusammenzufassen / einzubetten, um sie dazu zu zwingen, in denselben Raum wie ein normales Zeichen zu passen. Beispielsweise ist das erste Zeichen eine dünne Linie mit hinzugefügter Farbe, (char-to-string ?\uFEFF)und das andere ist ein Zielzeichen, das verkleinert wird Größe so passen sie beide. Eine andere Idee wäre, ein vertikales Durchgestrichen zu verwenden (in einigen Schriften verfügbar , aber nicht in allen), ähnlich dem, was in der Bibliothek vline.el emacswiki.org/emacs/VlineMode
lawlist am
@lawlist: Diese Unicode-Zeilen-Idee ist interessant, sie würde mich nebenbei machen lassen. Haben Sie eine Idee, wie Sie die Größe des folgenden Zeichens verringern können? Ich könnte vielleicht ein Bild für die Anzeigeeigenschaft generieren, aber AFAICT gibt es keine Möglichkeit, Emacs zum Rendern von Text in ein Bild zu bringen, sodass ich die Bilder außerhalb von Emacs erstellen müsste.
Joseph Garvin
Dieser Kommentar ersetzt den vorherigen Kommentar (den ich entfernt habe) und der Code im folgenden Link wurde ebenfalls aktualisiert. Er enthält drei Beispiele (von denen eines mit der Antwort identisch ist, die ich unten im aktuellen Thread gepostet habe): stackoverflow .com / questions / 23744237 /…
Gesetzesliste

Antworten:

4

Eine andere Möglichkeit wäre, Zeilennummern anzuzeigen und die Zeilennummer vor dem Wort auszusprechen, oder, da es lästig wäre, nach der genauen Zeilennummer zu suchen, den Algorithmus innerhalb von + oder - 5 oder 10 Zeilen der von Ihnen eingegebenen Nummer suchen zu lassen sagen.

Oder geben Sie eine Region oder Funktion an, in der Sie arbeiten, und lassen Sie alle Suchvorgänge nur dort anzeigen. Ich würde vermuten, dass dies Kollisionen einschränken würde.

Sie können Unicode-Symbole auch nach oder vor einem Wort in einer bestimmten Farbe rendern, um sie hervorzuheben. Außerdem können Sie das Wort in einer anderen Farbe markieren oder unterstreichen. Auf diese Weise könnten Sie 6 Wortfarben * 6 Symbolfarben * N Symbolmöglichkeiten haben. Sie könnten wahrscheinlich 10 gute Symbole finden und 360 Kombinationen haben. Zum Beispiel könnte man "blauer gelber Stern" sagen, um sich hier auf das Wort Katze zu beziehen.

Bildbeschreibung hier eingeben

Wenn der Stern zu nervig ist, können Sie: box und zwei verschiedene: underlines koppeln.

Sie könnten hier also mit "blau, gelb, rot" auf den Wortbaum verweisen, was 216 Kombinationen ergeben würde.

Bildbeschreibung hier eingeben

Jordon Biondo
quelle
1
Ich habe eine Weile gewartet, bis sich jemand andere Tricks ausgedacht hat, aber ich werde wahrscheinlich die doppelte Unterstreichungsfarbe verwenden, da das Hinzufügen von Symbolen Einrückungen verursachen kann. Akzeptiert, danke.
Joseph Garvin
2

Hast du schon mal von Ass-Sprung-Modus gehört ?

Es erfüllt keine der von Ihnen angegebenen Anforderungen, scheint jedoch perfekt zu dem zu passen, was Sie erreichen möchten. Es würde dem Benutzer erlauben, ein beliebiges Wort zu spezifizieren, indem nur 2 oder 3 Wörter gesagt werden.

Sie können den Zeichensatz definieren, den er Ihnen bietet, damit Sie schwer unterscheidbare Konsonanten vermeiden können. Dann könnte die Verwendung einfach "fix A nine" sagen und das neunte Wort korrigieren, das mit beginnt a.

Malabarba
quelle
Siehe meinen Kommentar zu tmalsburgs Beitrag, warum der Ass-Sprung-Modus nicht funktioniert hat.
Joseph Garvin
1

Interessante Frage. Ich wette, Sie bekommen interessante Vorschläge.

Ein kleiner Vorschlag, der mir einfällt, ist, verschiedene Farben und Stile zum Unterstreichen zu verwenden. Siehe das Elisp-Handbuch, Knoten Face Attributesüber Attribute :underlineund ihre :colorund :styleKomponenten.

Sie können auch mit Attributen :boxund verschiedenen Linienbreiten und Stilen experimentieren , aber das ist vielleicht zu irritierend.

Drew
quelle
1

Ich werde antworten, indem ich eine alternative Methode zur Auswahl des Zielworts vorschlage. Markieren Sie die Hälfte der Wörter (zufällig ausgewählt). Der Benutzer sagt "Ja", wenn das Zielwort markiert ist, und "Nein", wenn dies nicht der Fall ist. Wenn der Benutzer "Ja" gesagt hat, nehmen Sie alle hervorgehobenen Wörter und markieren Sie zufällig die Hälfte davon. Wenn der Benutzer "Nein" gesagt hat, markieren Sie zufällig die Hälfte der Wörter, die nicht markiert wurden. Der Benutzer gibt wieder an, ob das Zielwort hervorgehoben ist, indem er "Ja" oder "Nein" sagt. Wiederholen Sie diesen Vorgang, bis nur das Zielwort markiert ist.

Einige Vorteile dieses Ansatzes:

  • Dies funktioniert, egal wie viele Wörter Sie auf dem Bildschirm haben.
  • Sie brauchen keine ausgefallenen Farben, Schriften oder Symbole. Ein monochromes Display reicht aus.
  • Sehr geringe kognitive Belastung, da leicht zu erkennen ist, ob ein Wort hervorgehoben ist oder nicht.

Nachteil: Sie müssen zu oft "Ja" und "Nein" sagen. Dies wird jedoch durch die folgende Variante der Idee behoben: Markieren Sie die Wörter nicht, sondern verwenden Sie Farben für sie. Sie sagen, Sie haben 6 leicht unterscheidbare Farben. Dies bedeutet, dass bei 100 Wörtern auf dem Bildschirm für die Auswahl des Zielworts durchschnittlich 2,6 Farben erforderlich sind. Bei 1000 Wörtern müssen Sie durchschnittlich 3,9 Farben benennen.

Tmalsburg
quelle
1
Leider ist die Anzahl der gesprochenen Wörter eine irreführende Metrik. Das Problem bei diesem Lösungsstil besteht darin, dass er Wahrnehmungs- / Aktionsrundgänge enthält. Ich muss die Farbe sehen, dann reagieren, dann sehen, reagieren, sehen. Das Sprechen von 3 Wörtern, ohne anzuhalten, um dazwischen zu schauen, ist in der Praxis schneller als eine Lösung, bei der Sie dies tun, insbesondere wenn Dragon eine geringe Latenz hat. Wenn diese Rundfahrten kein Problem wären, würde ich einfach den Ass-Sprung-Modus verwenden. Mit den diakritischen Zeichen kann ich einmal auf den Bildschirm schauen und die gesamte Zeichenfolge von dem, was ich sagen muss, kennen, ohne dass Dragon nach jedem Wort eine Pause einlegen muss, um zu reagieren.
Joseph Garvin
1

Das folgende Beispiel zeigt eine Überlagerung mit einem xpm-Bild für grafische Emacs-Versionen, die das xpm-Bildformat unterstützen. Es ist 11 Pixel breit; 20 Pixel hoch; und hat eine benutzerdefinierte Anzahl von 4 möglichen Farben. Ich arbeite auf einem Mac mit Snow Leopard 10.6.8, und die Schriftart, die ich bei der Verwendung von Emacs bevorzuge, ist -*-Courier-normal-normal-normal-*-18-*-*-*-m-0-iso10646-1- die frame-char-widthist 11 und die frame-char-heightist 20. Ich habe links neben dem Großbuchstaben "A" eine dünne vertikale gelbe Linie als Beispiel für das Zeichnen von benutzerdefinierten Bildern. Die Ersetzung des Zeichens an dieser Stelle kann programmgesteuert unter Verwendung (char-after (point))dieser Zahl erfolgen - in diesem Fall 65 für den Großbuchstaben "A" - und durch Ersetzen der entsprechenden Variablen - z. B. (cond ((eq (char-after (point)) 65) cap-ltr-a-xpm) . . .- und unter Verwendung dieser Variablen in der Overlay-Platzierung - zB(overlay-put (make-overlay (point) (1+ (point))) 'display cap-ltr-a-xpm). Dies funktioniert sowohl bei abgeschnittenen Puffern als auch bei Zeilenumbrüchen sehr gut, da die displayÜberlagerungseigenschaft eines Zeichens in der Mitte eines Wortes nicht den Eindruck erweckt, dass der erste Teil des Wortes am Ende der vorherigen Zeile steht . Natürlich wird es einige Zeit dauern, um eine benutzerdefinierte Bibliothek mit bevorzugten xpm-Bildern zu erstellen.

ImageMagick ist in der Lage, eine semi-genaue xpm eines bestimmten Zeichens basierend auf einer bestimmten Schriftfamilie und Schriftgröße zu erzeugen, aber es war nicht so genau wie ich gehofft hatte - hier ist ein Link zu einer Anleitung zur Verwendung dieses externen Dienstprogramms: https: / /stackoverflow.com/a/14168154/2112489 Kurz gesagt, der Benutzer sollte bereit sein, die xpm-Bilder nach seinen Wünschen anzupassen.

(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)))
Gesetzesliste
quelle
@wasamasa - danke - Ich habe die fehlerhafte Aussage zu XBM-Bitmaps entfernt.
Gesetzesliste