Способы ненавязчиво варьировать отрисовку текста?

12

Я пишу расширение emacs для использования с распознаванием речи и ищу помощь с определенной функцией. Некоторые слова распознаватель речи (Дракон) постоянно плохо распознает - не имеет значения, сколько раз вы тренируете его, он просто не справится с распознаванием определенных слов. В то же время, как правило, когда вы пишете по теме или кодируете, вы будете использовать множество одних и тех же слов снова и снова.

Итак, я написал режим, который использует наложения, чтобы изменить способ отображения слов в буфере. Он берет случайную букву в слове, подчеркивает ее случайным цветом и помещает поверх нее случайный диакритический знак (ударение, умляут и т. Д.). Вот снимок экрана (вам, вероятно, понадобится увеличить изображение, чтобы увидеть метки / подчеркивание):

введите описание изображения здесь

Затем вы можете сказать «фиолетовые р волосы», и оно будет искать слово с фиолетовым подчеркиванием под «а» с диакритическим знаком, похожим на волосы, и наберите это слово для вас. Так что на приведенном выше скриншоте говорится, что emacs наберет для вас «regexp-quote».

Идея заключается в том, что это позволяет вам ссылаться на любое слово, которое вы уже использовали, на экране, используя конечный набор слов, которые распознаватель неизменно хорошо распознает.

Это работает довольно хорошо, за исключением случайного столкновения. Чтобы это сделать, я могу научиться последовательно ссылаться на слова так же, как я использую байты из хеша md5 слова вместо (random)алгоритма или присваиваю изменения таким образом, чтобы избежать коллизий. Я нашел только 6 легко различимых цветов (это трудно, когда подчеркивание имеет ширину всего в один символ и толщину в один пиксель) и 3 легко различимых диакритических знака (легко отличить друг от друга, а также не путать с подчеркиванием на приведенном выше рисунке). линия или перекрытие с подчеркиванием), видно в верхней части источника выше.

Мне нужно больше способов изменить рендеринг, чтобы уменьшить частоту столкновений. В идеале модификация рендеринга должна:

  • Не шуми от остального текста. Это привело меня к отклонению, например, свойства inverse-video.
  • Нельзя легко спутать с другими изменениями. Наложение легко принять за подчеркивание в предыдущей строке. Множество диакритических знаков выглядят одинаково, если только размер шрифта не слишком велик.
  • Будьте пространственно рядом с другими изменениями. Прямо сейчас, как только мой глаз находит целевой символ, вся информация там, маркер, подчеркивание и буква.
  • Хорошо работает со шрифтом фиксированной ширины (необходим для кодирования), который правильно отображает диакритические знаки (мне пришлось переключиться на DejaVu Sans Mono из Consolas, чтобы метки отображались правильно)
  • Работа над латинскими буквами алфавита. Например, есть арабские комбинирующие метки, но они не объединяются в латинских алфавитах.
  • Не изменять цвет букв, так как он уже используется для подсветки синтаксиса.
  • На самом деле быть выполнимым в Emacs с Emacs LISP;)

Может быть, есть специальные символы юникода, управляющие рендерингом, которые могут быть использованы для открытия новых возможностей? Или способ сгущения подчеркиваний, чтобы я мог легко различать больше цветов? Или какая-то другая неясная функция emacs, позволяющая вам отображать метки поверх символов помимо юникода?

Джозеф Гарвин
источник
Не прямой ответ на ваш вопрос, но, возможно, пара идей, использующих оверлеи для придания новых персонажей. Одна идея состояла бы в том, чтобы объединить / сэндвичить вместе два наложения - заставить их уместиться в том же пространстве, что и обычный символ - например, первый символ - это тонкая линия с добавленным цветом, (char-to-string ?\uFEFF)а другой - целевой символ, который уменьшен в размер, чтобы они оба подходят. Другой идеей было бы использовать вертикальный проход (доступен в некоторых шрифтах, но не во всех), аналогичный тому, что используется в библиотеке vline.el emacswiki.org/emacs/VlineMode
lawlist
@lawlist: Эта идея с юникодной линией интересна, она позволила бы мне создать «боковую линию». У вас есть идеи, как уменьшить размер следующего символа? Возможно, я мог бы сгенерировать изображение для использования со свойством display, но на самом деле нет способа заставить emacs визуализировать текст в изображение, поэтому я должен сделать изображения вне emacs.
Джозеф Гарвин
Этот комментарий заменяет предыдущий комментарий (который я удалил), а также обновлен код в следующей ссылке - он содержит три примера (один из которых идентичен ответу, который я разместил ниже в текущей теме): stackoverflow .com / questions / 23744237 /…
юрист

Ответы:

4

Другой возможностью было бы отобразить номера строк и сказать номер строки перед словом, или, поскольку поиск точного номера строки был бы утомительным, вы могли бы искать алгоритм в пределах + или - 5 или 10 строк от числа, которое вы сказать.

Или, возможно, объявите регион или функцию, в которой вы работаете, и все поиски будут искать только там. Я предполагаю, что это ограничит столкновения.

Вы также можете отображать символы Юникода после или перед словом заданного цвета, чтобы помочь им выделиться. А также вставьте или подчеркните слово другим цветом. Таким образом, вы могли бы иметь 6 цветов слова * 6 цветов символа * N возможностей символа. Вы могли бы вероятно найти 10 хороших символов и иметь 360 комбинаций. Например, вы можете сказать «сине-желтая звезда», чтобы обозначить здесь слово «кошка».

введите описание изображения здесь

Если звезда слишком резкая, вы можете соединить: поле и два разных: подчеркивание.

Таким образом, вы можете обратиться к дереву слов, используя «синий желтый красный», который даст вам 216 комбинаций.

введите описание изображения здесь

Джордон Биондо
источник
1
Я подождал некоторое время, чтобы увидеть, придут ли кому-нибудь другие уловки, но я, вероятно, собираюсь использовать цвет с двойным подчеркиванием, поскольку добавление символов может отбрасывать отступы. Принято, спасибо.
Джозеф Гарвин
2

Вы слышали о туз-прыжок-режиме ?

Он не соответствует ни одному из указанных вами требований, но, похоже, идеально соответствует тому, чего вы пытаетесь достичь. Это позволит пользователю указать любое слово, сказав только 2 или 3 слова.

Вы можете определить набор символов, которые он вам предлагает, так что вы можете избежать согласных, которые трудно различить. Тогда использование может просто сказать «исправить девятку» и исправить девятое слово, которое начинается с a.

Malabarba
источник
См. Мой комментарий к сообщению tmalsburg о том, почему не работает режим ace-jump.
Джозеф Гарвин
1

Интересный вопрос. Держу пари, вы получите интересные предложения.

Одно небольшое предложение, которое приходит мне в голову, - это использовать разные цвета и стили для подчеркивания. См Elisp вручную, узел Face Attributesоб атрибуте :underlineи его :colorи :styleкомпонентов.

Вы также можете поэкспериментировать с атрибутом :boxи различными ширинами линий и стилями для него, но это, возможно, слишком неприятно.

Нарисовалась
источник
1

Я отвечу, предложив альтернативный способ выбора целевого слова. Выделите половину слов (выбранных случайным образом). Пользователь говорит «да», если целевое слово выделено, и «нет» в противном случае. Если пользователь сказал «да», возьмите все слова, которые были выделены и случайным образом выделите половину из них. Если пользователь сказал «нет», случайным образом выделите половину слов, которые не были выделены. Снова пользователь указывает, выделено ли целевое слово, говоря «да» или «нет». Повторяйте это, пока не будет выделено только целевое слово.

Некоторые преимущества этого подхода:

  • Это работает, независимо от того, сколько слов у вас на экране.
  • Вам не нужны причудливые цвета, шрифты или символы. Достаточно монохромного дисплея.
  • Очень низкая когнитивная нагрузка, потому что легко определить, выделено слово или нет.

Недостаток: Вы должны говорить «да» и «нет» слишком часто. Однако это исправлено следующей вариацией идеи: не выделяйте слова, а используйте для них цвета. Вы говорите, что у вас есть 6 легко различимых цветов. Это означает, что если у вас есть 100 слов на экране, выбор целевого слова требует в среднем 2,6 цвета. Если есть 1000 слов, вы должны назвать в среднем 3,9 цвета.

tmalsburg
источник
1
К сожалению, количество произнесенных слов вводит в заблуждение. Проблема с этим стилем решения состоит в том, что он включает в себя восприятие / действие круговых поездок. Я должен видеть цвет, затем реагировать, затем видеть, реагировать, видеть. Сказать 3 слова, не останавливаясь, чтобы смотреть между ними, должно быть на практике быстрее, чем решение, которое вы делаете, особенно если у Дракона низкая задержка. Если бы эти круговые поездки не были проблемой, я бы просто использовал режим туза-прыжка. С диакритическими знаками я могу один раз посмотреть на экран и узнать всю цепочку того, что мне нужно сказать, не останавливаясь, чтобы Дракон реагировал на каждое слово.
Джозеф Гарвин
1

Ниже приведен пример использования наложения с изображением xpm для графических версий Emacs, которые поддерживают формат изображения xpm. Это 11 пикселей в ширину; Высота 20 пикселей; и имеет указанное пользователем количество из 4 возможных цветов. Я работаю на Mac под управлением Snow Leopard 10.6.8, и шрифт, который я предпочитаю при использовании Emacs, -*-Courier-normal-normal-normal-*-18-*-*-*-m-0-iso10646-1- frame-char-widthэто 11, а frame-char-heightэто 20. Я добавил тонкую вертикальную желтую линию слева от заглавной буквы «A» в виде пример того, как рисовать пользовательские изображения. Подстановка символа в точке может быть произведена программно с использованием (char-after (point))этого числа, которое в данном случае равно 65 для заглавной буквы «A», и замены соответствующей переменной, например, (cond ((eq (char-after (point)) 65) cap-ltr-a-xpm) . . .и использования этой переменной в размещение оверлея - например,(overlay-put (make-overlay (point) (1+ (point))) 'display cap-ltr-a-xpm), Это прекрасно работает как для усеченных буферов, так и для переноса слов, потому что displayсвойство overlay для символа в середине слова не заставляет перенос слов думать, что первая часть слова принадлежит в конце предыдущей строки. , Конечно, потребуется время, чтобы создать собственную библиотеку любимых изображений xpm.

ImageMagick способен генерировать полуточный xpm определенного символа на основе определенного семейства шрифтов и размера, но это не было так точно, как я надеялся - вот ссылка на инструкции по использованию этой внешней утилиты: https: / /stackoverflow.com/a/14168154/2112489 В двух словах, пользователь должен быть готов потратить время на настройку xpm-изображений по своему вкусу.

(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)))
lawlist
источник
@wasamasa - спасибо - я удалил ошибочное утверждение, касающееся растровых изображений XBM.
законник