[Перевод] Как я пишу на LaTeX в Emacs быстрее, чем от руки

image-loader.svg

Когда Жиль Кастель задокументировал метод ведения математических записей в Vim в реальном времени, многие захотели добиться тех же скорости и удобства ввода LATEX в Emacs1.

Я работаю на LaTeX весь день: уравнения пишу так же быстро, как на бумаге. И даже быстрее. Почему? За размышлением всегда следует работа пальцев. И это — та ситуация, когда количество переходит в качество. Хотя мои рекомендации — лишь 90% решения.


Когда математические записи ведутся достаточно быстро, чтобы этот этап работы пальцев исчез (или так же быстро, как это делают у классной доски), тогда открываются новые возможности. Запись уроков по техническим предметам в цифровой архив с гиперссылками, индексированием и/или возможностью поиска становится автоматической — не нужно выделять на это время. А письменная коммуникация упрощается: полностью отформатированное, простое для парсинга электронное письмо или сообщение создаётся быстро и без усилий. При публикации материала намного быстрее цикл «написать → проверить → переписать», а значит — больше итераций и обратной связи.

Ввод LaTeX для нетерпеливых


Смотрите примеры ниже:
Матрицы в спешке:
Типичное выражение:

Просто дайте мне код


Рассмотрим компоненты редактирования LaTeX в Emacs и функции для ускорения текстового и математического ввода. Цель — сделать его таким же быстрым, как ввод обычного текста или написание уравнений на бумаге. Достаточно хотя бы, чтобы делать быстрые записи. Инструменты смотрите в оглавлении (справа или ниже) или в демо.

Кодом конфигурации в едином файле — здесь — будут установлены три пакета Emacs: AucTeX, CDLaTeX и YaSnippet, но без YaS-сниппетов. Я беру сниппеты отсюда, но рекомендую писать те, которые подходят вам. Одна из функций в этом коде для быстрого ввода на LaTeX таблиц или массивов доступна в отдельном пакете.

Состояние редактирования LaTeX в Emacs


Редактирование LaTeX в Emacs в моём понимании:

image-loader.svg


В центре — структура документа в TeX: дерево документа, текст и плавающие элементы, класс и стиль документа, перекрёстные ссылки и цитаты, другие метаданные и версии документа2. А вокруг — островки, нужные при использовании текстового редактора для создания этого документа: ввод и редактирование текста, навигация по документу, внешний вид, статический анализ кода и компиляция. Стрелки между островками — это пакеты Emacs, библиотеки или их функционал, позволяющие выполнять или ускорять эти задачи.

По многим элементам этой карты лучше обратиться к кому-нибудь, кто написал 1–2 книги по Emacs. Перед вами не исчерпывающее руководство по редактированию LaTeX в Emacs, а рекомендации по его ускорению, чтобы делать быстрые записи. 

Главный акцент сделан на блоке Text Input (ввод текста) с быстрыми переходами в разделы Appearance (внешний вид) и Text Editing (редактирование текста). Хотите полную картину? Начните с руководства по AucTeX (C-h i m auctex в Emacs). Вполне удобное для восприятия и — если у вас есть редкий ген, позволяющий переваривать руководства, — довольно приятное! По причине моего невежества в этой схеме нет пары важных элементов:  

  • Digestif — языковой сервер для LaTeX. Вместе с Eglot или LSP он должен выполнять многие из этих задач: перекрёстные ссылки, цитаты, статанализ кода, автозавершение и т. д.
  • Xenops — полный набор инструментов поверх AucTeX, в котором этот функционал собран в единый пакет, устанавливаемый и используемый без настройки. Кроме того, в него добавлена поддержка грамотного программирования.


С более удобными или быстрыми способами выполнения других задач можно ознакомиться по ссылкам на схеме.

В следующей статье этой серии рассмотрим блок Text Editing (редактирование текста). В отличие от блока ввода он связан прежде всего с манипулированием имеющейся структурой документа без значительного добавления к ней чего-либо. Завершим серию совершенно другим набором инструментов, нежели те, о которых пойдёт речь сейчас.

Основные составляющие


image-loader.svg


Здесь нам нужно лишь несколько ингредиентов и Emacs. Создаём окружение ввода текста в три этапа:

  • В AucTeX — основе редактирования LaTeX (а также в ConText) в Emacs — есть команды и второстепенные режимы для всех аспектов создания документов со всеми составляющими. Много лет я был полностью доволен скоростью ввода текста и удобством редактирования с помощью AucTeX.
  • CDLaTeX — набор команд и удобных функций для уменьшения объёма ввода. Это один из самых больших секретов Emacs и секретный соус нашего рецепта.
  • YaSnippet — пакет Emacs для вставки сниппетов, т. е. шаблонов с полями для заполнения. Он применяется много для чего ещё и не очень удачно дублирует функционал CDLaTeX. Но что поделаешь? Сразу же с ним и разберёмся: поисковик обычно выдаёт в результатах Yasnippet и более современные пакеты auto-activating-snippets. Хотя я использую Yasnippet в демо выше (и ниже), интенсивно применять разворачивающиеся сниппеты, чтобы ускорить редактирование LaTeX, — неправильный подход. Подробнее об этом — позже.

Остальные пакеты в блоке Text Input (ввод текста) в основном перекрываются по функциям с вышеуказанными:

  • tempo, skeleton и abbrev придают вкус вставки или расширения шаблона. Но это же делают YaSnippet и CDLaTeX, и даже гораздо больше этого.
  • AucTeX предоставляет capfs или completion-at-point (завершение в точке), но он нужен редко из-за того, каким образом вводится текст. Если нужно завершить ключевое слово? Вызывайте completion-at-point или используйте один из многочисленных пакетов, выступающих в роли фронтендов, например company-mode или corfu.
  • auto-activating-snippets (автоматически активирующиеся сниппеты) и его расширение LaTeX-auto-activating-snippets — это более чистая и быстрая реализация конкретной функциональности, для которой используется YaSnippet. Если бы начать всё сначала, я выбрал бы их, так что ознакомьтесь с ними.
  • LaTeX-math-mode (часть AUCTeX) — это метод эффективной вставки математических символов. Но у CDLaTeX это получается лучше.


Итак, начинаем с AucTeX, добавляем CDLaTeX и сверху ещё YaSnippet. Добавляя эти пакеты, увеличиваем скорость ввода LaTeX, но конструкция становится похожей на Пизанскую башню. Первые два я использую давно, а YaS добавил несколько лет назад и сейчас уже устранил большинство багов в системе. Тем не менее будьте бдительны.

Всё готово? Тогда поехали.

Вниманию пользователей org-mode

Org-mode имеет очень хорошую поддержку ввода LaTeX из коробки, поэтому вы можете использовать советы в этой статье с минимальными изменениями. При необходимости я добавляю детали, специфичные для оргрежима, ниже.


Этап 1: AucTeX


AucTeX делает большую часть работы, создавая полноценную среду редактирования LaTeX, — остаётся лишь добавить удобные функции для экономии времени.

AucTeX отвечает за завершение при вводе текста. Самые общие и всегда доступные варианты ввода текста:

  • вставка произвольного окружения с помощью LaTeX-environment (C-c C-e);
  • или макрос TeX-insert-macro (C-c C-m): делает вставку, запросив аргументы;
  • вставка заголовка раздела с помощью LaTeX-section (C-c C-s).


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

Вот пара удобных функций AucTeX, не относящихся к вводу текста:

Режимы Outline


Я включаю outline-minor-mode в буферах TeX, чтобы свёртывать разделы, перемещаться по заголовкам разделов и т. д. В Emacs 28 или новее это активирует команду outline-cycle, чтобы одной клавишей зациклить видимость раздела, как в Org-mode. Привязываю её к TAB, как в Org-mode 3.

Счётчик TAB: 2 (outline-cycle, LaTeX-indent-line)

Вот пара полезных связанных с внешним видом функций AucTeX, которые привносят концепцию WYSIWYG:

Красивые символы (M-x prettify-symbols-mode)


prettify-symbols-mode в буферах LaTeX заменит математические символы более удобными для восприятия эквивалентами в Юникоде. Это сильно упрощает парсинг уравнений:

image-loader.svg


Основной текст не меняется, и его можно искать в этих символах. Настраивать ничего не нужно: AucTeX автоматически эти замены. Просто включаем prettify-symbols-mode:

(add-hook 'LaTeX-mode-hook 'prettify-symbols-mode)


Org имеет свою собственную версию режима prettify-symbols-mode. Вместо него используйте M-x org-toggle-pretty-entities. По умолчанию он привязан к C-c C-x \.


Предварительный просмотр в буфере (M-x preview-buffer)


Что может быть лучше замены отдельных символов символами Юникода? Замена целых уравнений и изображений на скомпилированные версии для предварительного просмотра:

image-loader.svg


Наведя курсор на уравнение, временно удалим наложение изображения и отредактируем окружение:
Просмотрим окружение в точке, активной области, в разделе или во всём буфере — все они привязаны к карте предварительного просмотра (C-c C-p). Обычная практика — автоматический предварительный просмотр математических окружений при выходе из одного из них (во многих пакетах есть эта функция).

Но вместо удобства она приносит мне скорее раздражение: я предпочитаю свободно редактировать (с включёнными pretty-symbols), а по завершении вызвать preview-section. В демо этой статьи я использую оба улучшения внешнего вида.

Возможно, вам захочется изменить размер отображаемых изображений предварительного просмотра. Замените число на то, которое вам больше подходит:
(add-hook 'LaTeX-mode-hook
          (defun preview-larger-previews ()
            (setq preview-scale-function
                  (lambda () (* 1.25
                           (funcall (preview-scale-from-face)))))))


Org также имеет свою версию предварительного просмотра LaTeX в буфере. Вместо preview-region можно использовать M-x org-latex-preview. (Привязанные к C-c C-x C-l)


Оставшаяся часть AucTeX


AucTeX — это комплексный инструмент. Например, TeX-fold-mode добавляет ещё один способ скрыть визуальный шум при просмотре документа, позволяя легко переходить к шумным частям:
TeX-error- и TeX-command- работают с компиляцией и отладкой, TeX-view — с просмотром выходных PDF-файлов, TeX-master — с документами из нескольких файлов, TeX-documentation — со справкой и т. д. Но всё это — темы отдельных статей.

Этап 2: CDLaTeX


Сказать, что CDLaTeX даёт набор удобных функций, ускоряющих редактирование документов на LaTeX, — всё равно что ничего не сказать. Пара дней практики — и вы будете управляться с фрагментами LaTeX, как мотоциклист, лавирующий в трафике.

Технически AucTeX большую часть этого уже делает, но в тяжеловесном стиле 90-х. Хотите вводить C-c C-o C-o после заполнения каждого математического окружения? Вот и я не хочу.

Вместо установки CDLaTeX вы включите режим org-cdlatex-mode. Вам даже не нужно устанавливать CDLaTeX, он уже есть в вашей системе! Org-cdlatex-mode является частью Org. Это не случайное совпадение. CDLaTeX был написан Карстеном Домиником (отсюда и CD), который также был основным автором Org-mode.


TABинатор


Лучший трюк с CDLaTeX — активное использование клавиши TAB. При её нажатии происходит переход к следующей «точке интереса»: курсор помещается в удобные для ввода текста места. Это проще показать. Здесь я перемещаюсь по фрагменту документа с сотней нажатий только клавиши TAB и никакой больше:
Эвристический подход для определения того, куда TAB приведёт в каждый следующий момент, в целом довольно хорош и умело применяется к разделителям и макросам LaTeX:
В этом примере он приводит из \left( к интегралу, затем к подынтегральному выражению, к переменной интегрирования и, наконец, к \right). В руководстве сказано:

«Если сомневаетесь, нажимайте TAB».


Ввод символов


При вводе символа (`) и буквы происходит вставка символов в буфер, при необходимости автоматически добавляются встроенные математические символы доллара $:
Здесь выбраны назначенные клавиши:

` и a-z (A-Z) вставляют греческие буквы (заглавные), так `a даёт \alpha, `L даёт \Lambda и т.д. Плюс клавиши ??? для вставки стрелок:

image-loader.svg

Имеются сопоставления символов для других операций, например над множествами и т. д. Но запоминать их не нужно: поможет меню с подсказками. Есть три слоя символов, причём менее распространённые из них доступны при повторном нажатии клавиши обратного апострофа: ```key:


Через пару дней использования CDLaTeX я автоматически набирал первый слой символов (одиночный обратный апостроф `) и ждал, когда появятся подсказки для менее распространённых символов в меню двойного `` или тройного ``` обратного апострофа.

Символы в этом списке можно поменять или добавить, настроив cdlatex-math-symbol-alist. Чтобы набрать в документе символьную константу обратного апострофа, надо добавить впереди C-q.

Внимание: в AucTeX есть ещё TeX-math-mode (он делает нечто очень похожее).

org-cdlatex вставляет символы в org-режиме без математических разделителей. Это связано с тем, что так меньше визуально отвлекает внимание, а бекенд экспорта LaTeX в Org автоматически добавляет разделители.


Математические и текстовые модификаторы


Модификаторы добавляются к набранному тексту с помощью одинарной кавычки ('). Это относится к циркумфлексу, точке, тильде, обратному апострофу и над/подчёркиванию на символах, а также изменению стилей шрифта в математическом и текстовом режимах:
Снова набираем кавычку 'и ждём, когда появится окно с подсказками. (Доступно ещё много модификаторов, я использую лишь несколько). В другом направлении это тоже работает. Начинаем с модификатора, затем вводим символ или текст:
Символы в списке можно поменять или добавить, настроив cdlatex-math-modify-alist. Чтобы набрать символьную константу кавычки, используют ''.

10 лет назад функция онлайн-справки CDLaTeX была сенсацией. Сегодня эта функция есть в Emacs благодаря which-key и другим пакетам.

Окружения и математические шаблоны


CDLaTeX определяет набор шаблонов, развёртывающихся в окружениях с помощью TAB. В этом развёртывании можно, применяя TAB, переходить по текстовым полям. Например, в текстовом режиме набираете equ[tab], чтобы создать окружение уравнений, или sn[tab] — для раздела, fg[tab] — для изображения и inc[tab] — для макроса \includegraphics. А env[tab] или beg[tab] вставит любое окружение на выбор. Вот примеры:
Внимание: здесь я использовал TAB, чтобы вставлять шаблоны и перемещаться по документу.

Похожие клавиши быстрого доступа для разделителей и макросов есть в математических окружениях. Например, он изменяет ^ и подчёркивание _, вставляя ^{} и _{}, и изящно работает с фигурными скобками:


Можете добавить свои. Я добавил окружения для ввода матриц в стиле AMSMATH, настроив cdlatex-command-alist.

Это знакомо и ожидаемо: эти сниппеты подобны сниппетам других пакетов. Но есть важное отличие: текстовые поля в таком вставщике шаблонов/сниппетов, как YaSnippet, после завершения вставки теряют своё особое значение.

В CDLaTeX с помощью TAB используются не специальные маркеры в шаблоне, а эвристический метод для перемещений вперёд. Так можно возвращаться к этим полям (и промежуточным) в том же порядке в любое время.

Здесь мы могли бы уже остановиться


Благодаря быстрой вставке символов, модификаторов и окружения AucTeX и CDLaTeX вместе обеспечивают стабильный, быстрый ввод и редактирование LaTeX. Полная настраиваемость этих функций позволяет оставить далеко позади онлайн-пакеты (например, Overleaf) или интегрированные среды разработки LaTeX (например, TeXStudio), это касается большинства задач редактирования4.

Но лень и нетерпение не знают границ. Без конца нажимать TAB и вводить мудрёные модификаторы '^ или'} — слишком утомительно, а от клавиши Shift болят мизинцы, особенно если работать на LaTeX весь день. Пришло время для…

Этап 3: Yasnippet и автоматические сниппеты


Yasnippet используется прежде всего для автоматического развёртывания фрагментов (без нажатия TAB), чтобы делать записи на лекции, например. Но я использую его лишь для немногих избранных случаев5. Если AucTeX и CDLaTeX — это суп, то YaSnippet — это гарнир. Чтобы YaSnippet автоматически развёртывал сниппеты, приведём его в надлежащий вид. Вот код автоматического развёртывания с помощью YaSnippet:

;; Function that tries to autoexpand YaSnippets
;; The double quoting is NOT a typo!
(defun my/yas-try-expanding-auto-snippets ()
  (when (bound-and-true-p 'yas-minor-mode)
      (let ((yas-buffer-local-condition ''(require-snippet-condition . auto)))
        (yas-expand))))

;; Try after every insertion
(add-hook 'post-self-insert-hook #'my/yas-try-expanding-auto-snippets)


Добавление этой проверки в post-self-insert-hook может показаться безумием, но это не вызывает замедления, которое я заметил. Посмотрите пакет auto-activating-snippets или встроенный в Emacs abbrev-mode для другого подхода, если вас это беспокоит.


Следующий шаг — объявить сниппет расширяющимся автоматически. Для этого вы добавляете #condition: строку в определениях фрагментов. Например, вот фрагмент для автоматического расширения левой и правой фигурных скобок:

# key: set
# name: set
# condition: (and (texmathp) 'auto)
# group: math
# --
\\left\\{ $0 \\right\\}


Более подробную информацию о написании сниппетов см. в документации YaSnippet.

Чтобы использовать ваши LaTeX Yasnippets в Org, вы можете скопировать их в раздел org вашего каталога сниппетов, или, что ещё лучше, добавить файл с именем .yas-parents в папку сниппетов org с содержанием
latex-mode

Это делает все фрагменты в режиме latex доступными и в Org.


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

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

Создание математических окружений


mk и dm создают встроенные окружения и окружения уравнений. Здесь нет ничего особенного: набирать их проще, чем $, $$ или \[ \], или сами слова. YaSnippet развёртывается только на границах слов, поэтому слова типа admin или gymkhana не задействуют эти сниппеты.

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


Более быстрые математические модификаторы


Заменим '^ cdlatex на \hat{}, просто набрав hat после символа. Так я набираю то, как читаю или слышу математику: a hat даёт мне a^ и т. д.:
Делаю ещё несколько таких автоматических переводов:

image-loader.svg

Где x — любой символ или s-выражение (т. е. выражение с разделителями).

Внимание: это поведение связано с редактированием буфера до точки и невозможно со встроенной библиотекой abbrev в Emacs. В большинстве других случаев abbrev-mode для автоматического развёртывания достаточно.

YaSnippet жалуется, если мы используем сниппет для прямого редактирования буфера, как это происходит в приведённых выше примерах обёртывания символов в \hat{} и т.д. Возможно, это плохая практика, но у меня пока не было проблем. Я подавляю эти предупреждения с помощью такого кода:
(with-eval-after-load 'warnings
  (cl-pushnew '(yasnippet backquote-change) warning-suppress-types
              :test 'equal))


Ускорение \frac


Делаем настройку //выражением \frac:

Простые и полезные замены


Вот простые, но полезные автозамены для моих целей:

image-loader.svg

И так далее. Эта функциональность несколько перекрывается с командой ввода символов cdlatex (`) — вместо неё и добавляем туда автозамены. Смысл: не в целях экономии времени, а чтобы сохранить поток мыслей при написании. Набираю их, как слышу (то есть leq вместо \le, x adj вместо x^{\dag}), и они автоматически меняются на правильные символы. Многие из этих замен есть в демо в начале статьи.

Дополнительно: обычные сниппеты с несколькими заполнителями


В смесь можно ещё добавить обычные фрагменты. Я часто использую их, например, для определённых интегралов и производных:
В принципе, их можно просто добавить в cdlatex-command-alist (его легче настроить), но всё это осталось со старых времён, и мне было лень менять.

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

Сниппеты: легко и просто


Вставка на основе шаблона или фрагмента — это очень ограниченная (во времени и пространстве) форма взаимодействия с документом. Поля для заполнения сохраняют особое поведение при переходах и вставках, лишь пока фрагмент «существует». Это поведение доступно только в этом месте документа.

Фрагменты жёсткие и монолитные: в определении учитываются все переменные (расположение полей, зеркала или преобразования) и его нельзя поменять на ходу. Но они хрупкие: часто ломаются при отклонении от ожидаемого поведения, то есть TAB → вставить текст → TAB → вставить текст. Пример: когда курсор убирается, чтобы скопировать что-то из другой части документа в поле фрагмента. Они модальны: выйдя из режима фрагмента, нельзя восстановить их состояние, не начав сначала.

Идеал — перемещение между полями, как между фрагментами, в том числе с преобразованиями полей, но в любое время, в любом месте документа и без такого понятия, как «активный» сниппет. TAB в CDlatex идёт к этому идеалу, но его эвристический подход для перемещений на основе регулярных выражений весьма ограничен по сравнению с тем, что вообще возможно.

Система лучше — это сочетание текстовых объектов в стиле Vim/ evil-mode, семантически совместимого парсера LaTeX на основе tree-sitter (генератора парсеров) и улучшенного набора команд DWIM в стиле CDLaTeX, интегрированного в AucTeX. И это без привлечения вспомогательных средств ИИ. Возможно, что-то подобное уже существует или разрабатывается для $MODERN_EDITOR. Но следует помнить, что лучшее — враг хорошего. Чтобы заделать бреши, вполне хватит немного YaS.

Применение на практике


Окружение, плавающие элементы и математический ввод


Цель — писать LaTeX (и особенно математики), передавая поток мыслей, когда глаза, пальцы и курсор скользят по разметке. Описанный выше процесс ещё не совсем завершён, но уже почти. Обобщённо он выглядит так:

  • Чтобы сделать процесс приятнее, включается prettify-symbols-mode.
  • С помощью обратного апострофа (``) вводятся символы, а с помощью кавычек (») меняется текст или макросы.
  • Чтобы при наборе перейти к следующей «точке интереса», используется TAB.
  • Чтобы вставить окружение и шаблоны с плавающими элементами, применяются команды CDLaTeX или фрагменты YaS. env[tab] для произвольного окружения (с завершением).
  • Чтобы набрать текст, не нарушая поток, используются автоматически развёртывающиеся фрагменты YaS (или сокращения abbrev-mode). Особенно удобны они для математических операторов.
  • Предварительный просмотр осуществляется с помощью команд preview- (очень удобна команда preview-at-point).
  • В отсутствие других возможностей используются не такие быстрые, но полностью совместимые с документом команды AucTeX: LaTeX-environment (C-c C-e) и TeX-insert-macro (C-c C-m).


Вот как я ввожу простое уравнение:

  1. Начните уравнение env с dm (YaS)
  2. Разверните интегральный сниппет с помощью intl [tab] (cdlatex, но вы можете определить для этого YaS)
  3. Проложите путь через пределы интегрирования, использовать ` 8, чтобы ввести ∞ как верхний (символ CDLaTeX)
  4. Получите e{} путём авторасширения e td (YaS)
  5. Получите −x2 как экспоненту из -x sr (YaS)
  6. Получите \mathrm{d} из следующего d с помощью математического модификатора CDLaTeX 'r
  7. Введите π с правой стороны как `p (символ CDLaTeX)
  8. Получите π{} авторасширением \pi td (YaS)
  9. Получите $1/2$ как экспоненту π при помощи авторасширения 1 // 2 (YaS)
  10. Вызовите preview-at-point для предварительного просмотра уравнения с помощью привязки клавиш.


Ввод таблицы, матрицы или массива


В серии Batteries Included («Батарейки в комплекте») кратко написано о orgtbl-mode. Это мощная, но нечасто применяющаяся встроенная функция Emacs, обеспечивающая редактирование таблиц в стиле org-mode для всех буферов. Используем её для написания LaTeX.

В org-mode очень широкие возможности, позволяющие работать даже с электронными таблицами. Нам будет важно перемещаться по таблице и редактировать её структурно, переходить по ячейкам с помощью TAB, перемещать столбцы/ячейки, удалять или добавлять новые, транспонировать таблицу и т.д. Свободный ввод матриц или массивов с этими манипуляциями будет очень естественным. А в итоге — ускорение ввода. Здесь я настроил фрагменты CDLaTeX для ввода матриц, чтобы автоматически запустить orgtbl-mode. По завершении после нажатия C-c C-c таблица будет преобразована в массив LaTeX:


Вот как это работает с полным матричным уравнением:
А здесь применяется к текстовой таблице. Начинаю с развёртывания шаблона tbl в cdlatex (уже настроенный для запуска таблицы org-mode). По завершении нажимаю C-c C-c, чтобы создать табличное окружение LaTeX:
Я переместил код из конфигурации в отдельный пакет, хотя для этого нужно установить CDLaTeX. Смотрите таблицу LazyTab здесь. Преобразование массива или матрицы LaTeX обратно в org-mode таблицу ещё не реализовано.

Перекрёстные ссылки и цитаты


Для Emacs есть много инструментов, чтобы без проблем вставлять цитаты и перекрёстные ссылки. Они даны на этой схеме.

Нам важен метод вызова этих функций. Вместо того чтобы привязывать эти команды к клавишам (как обычно используемые C-c ] и C-c )), вызываем команды с помощью сниппета. Чтобы не нарушать поток, используем CDLaTeX для развёртывания слов ref и cite в вызовы в обработчики ссылок и цитат:


Математический ввод с калькулятором


Как и в других статьях об Emacs, я не мог обойтись без калькулятора. Что он здесь делает? Много чего.

У него встроенный парсер для математической работы на LaTeX. Он очень прост, но может преобразовывать несложные объекты и уравнения из их представления на «языке программирования» (которое обычно намного легче вводить с клавиатуры) в LaTeX. Здесь я вызываю вспомогательную функцию, чтобы вызвать калькулятор в матрице и уравнении:


При этом калькулятор выполняет вычисления — это дополнительное преимущество. Здесь я инвертирую матрицу в процессе её отображения в виде массива LaTeX.
Также показаны разложение в ряд Тейлора и интегрирование.

(defun latex-math-from-calc ()
  "Evaluate `calc' on the contents of line at point."
  (interactive)
  (cond ((region-active-p)
         (let* ((beg (region-beginning))
                (end (region-end))
                (string (buffer-substring-no-properties beg end)))
           (kill-region beg end)
           (insert (calc-eval `(,string calc-language latex
                                        calc-prefer-frac t
                                        calc-angle-mode rad)))))
        (t (let ((l (thing-at-point 'line)))
             (end-of-line 1) (kill-line 0)
             (insert (calc-eval `(,l
                                  calc-language latex
                                  calc-prefer-frac t
                                  calc-angle-mode rad)))))))

(define-key LaTeX-mode-map (kbd "C-S-e") 'latex-math-from-calc)
(define-key org-mode-map (kbd "C-S-e") 'latex-math-from-calc)


Вызов других парсеров


Калькулятор — это замечательный программный компонент, вот только находится он где-то между программируемым вычислительным устройством и полноценной автоматизированной системой или системой цифровых вычислений. То есть постоянно удивляет своими возможностями, но слишком ограничен, чтобы использовать его полный рабочий день. Встроенный синтаксический анализатор LaTeX довольно жёсткий, и при неинтерактивном использовании встроенные функции имеют нестандартные, трудно запоминающиеся имена. Транспонирование, например, — trn.

Хотя я не настроил его, можно также преобразовать формулы стиля программирования в строки LaTeX — используя аналогичный интерфейс, как приведённая выше команда калькулятора, но с более полнофункциональной внешней программой. Парсеры для этого доступны, например, в составе Mathematica, Python (с Sympy) и Julia (с Latexify.jl). А в Xenops есть поддержка.

Настройка TAB


Назначение разных клавиш для outline-cycle, cdlatex-tab, yas-expand и т.д. — это простой подход. Не хочется всякий раз останавливаться и думать, какую клавишу нажать дальше при вводе LaTeX. Поэтому я настраиваю клавишу TAB, чтобы делать всё в таком порядке:

  1. Если в заголовке outline, как в разделе, то зацикливаем outline, как в Org-mode.
  2. Есть текст, развёртываемый CDLaTeX? Развёртываем его.
  3. Оказались в конце поля Yasnippet? Тогда переходим к следующему.
  4. Вы в поле Yasnippet? Пробуем перейти на CDLaTeX с TAB. Оказываемся за пределами поля? Идём в его конец.
  5. Оказываемся в конце текста в ячейке org-mode таблицы? Переходим к следующей ячейке, как в обычной таблице.
  6. Оказываемся в ячейке таблицы? Пробуем перейти на CDLaTeX с TAB. Оказываемся за пределами ячейки? Идём в её конец.


Похоже на машину Руба Голдберга, но на практике в любом месте она делает именно то, что ожидается. Её код находится в gist, но ещё могут быть пограничные случаи, которые надо учесть, прежде чем работать в каждом контексте.

Сноски
  1. Отныне просто LaTeX, потому что, черт возьми. ︎
  2. Не включена в таблицу: грамотное программирование в документе или в качестве документа. Это в основном покрывается PythonTeX в файлах LaTeX и org-babel в org-mode. ︎
  3. Если вы используете Emacs 27.2 или ниже, есть пакеты Outshine и Bicycle для одноклавишных циклов в стиле Org. ︎
  4. Конечно, это предполагает, что пользователь хорошо знаком с Emacs. И альтернативы значительно опережают AucTeX в других аспектах, например, в совместной работе. ︎
  5. Можно также пойти другим путём, отказаться от cdlatex и автоматически расширять все фрагменты с помощью YaS. Но у пакетов сниппетов есть фундаментальная проблема, смотрите «Сниппеты: легко и просто».

Попробовать рекомендации в деле вы сможете на наших курсах:


image-loader.svg

Узнайте подробности здесь.

Другие профессии и курсы
Data Science и Machine Learning
Python, веб-разработка
Мобильная разработка
Java и C#
От основ — в глубину
А также

© Habrahabr.ru