Функция Emacs для преобразования произвольной ORG PROPERTY в произвольную строку (а именно, метку LaTeX)?

11

У меня есть много документов в виде org-файлов, которые имеют свойство CUSTOM_LABEL, например

* Introduction :PROPERTIES: :CUSTOM_LABEL: AP 1 :END:

В этом случае файлы должны быть экспортированы как LaTeX, переводя каждый CUSTOM_LABELкак \label{marker}. Приведенный выше пример следует перевести на \label{AP 1}.

Я уже знаю, как вызывать пользовательские функции во время экспорта, но я не достаточно опытен, чтобы написать defun для выполнения этого конкретного преобразования, то есть CUSTOM_LABEL->\label{}

Как может defun вводить custom_labelкак \label{}написано?

Я был бы признателен даже за некоторый псевдокод или несколько указателей.

Я задаю этот вопрос здесь, а не в других местах, потому что это больше вопрос Emacs, так как я тщательно искал руководство по режиму org, и такая функция в настоящее время недоступна.

Универсальная функция для преобразования заданной НЕДВИЖИМОСТИ при экспорте (LaTeX, HTML или любой другой формат) была бы еще лучше.

Спасибо.

GSL
источник
Название кажется выключенным. Если я понимаю вопрос, вы хотите превратить свойство org в произвольную строку (а именно, метку LaTeX), а не в другое свойство org.
Малабарба
@rasmus: Спасибо за этот указатель. Я читал об этом всего несколько часов назад в emacs-orgmodeсписке (среди прочего, lists.gnu.org/archive/html/emacs-orgmode/2014-09/msg00498.html ). Я попробовал этот код, и просто настройки org-latex-custom-id-as-label. Он отлично работает с экспортом HTML, но не влияет на экспорт LaTeX. Я хотел бы полагаться только на org-modeосновные функции, но мне все равно нравится ответ @ malababrba, так как он позволяет сделать хорошее обобщение.
GSL
@rasmus Такое поведение мне нужно. Но я запустил ваш код, но я понял, \section{h}\label{sec-1}что я использую GNU Emacs 24.3.94.1 (x86_64-apple-darwin13.4.0, NS apple-appkit-1265.21) of 2014-10-04 on builder10-9.porkrind.orgи Org-mode version 8.2.6 (release_8.2.6-1 @ /Applications/Emacs.app/Contents/Resources/lisp/org/). Кроме того, чтобы убедиться, что я переименовал мой .emacs.d, так что он работал без каких-либо пользовательских вещей.
GSL
Как хорошо, что вам удалось синтезировать целый рабочий пример всего за одну строчку кода!
GSL
Ах, это объяснило бы это! Я попытался установить последнюю версию , org-modeиспользуя этот el-getрецепт: github.com/dimitri/el-get/blob/master/recipes/org-mode.rcp , но я все еще получаю. Org-mode version 8.2.6 (release_8.2.6-1 @ /Users/gsl/.emacs.d/el-get/org-mode/lisp/Вы знаете, как настроить этот рецепт, чтобы я мог использовать его для DEV-ветвь? Я мог бы также задать это как новый вопрос. Большое спасибо за указание на это.
GSL

Ответы:

10

Я написал функцию, которая делает то, что вы хотите, вполне расширяемым образом. Он проверяет, какие заголовки содержат свойство CUSTOM_LABEL (или другое настраиваемое свойство), и вызывает функцию endless/insert-org-label-latexдля каждого из них со значением свойства в качестве аргумента.

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

Настройте замены

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

(defcustom endless/org-property-mapping 
  '((latex ("CUSTOM_LABEL" . endless/insert-org-label-latex))
    (html ("CUSTOM_LABEL" . endless/insert-org-label-html)))
  "List of mappings from org property to arbitrary strings.
Each element is a list:
  (BACKEND (PROPERTY1 . FUNCTION1) (PROPERTY2 . FUNCTION2) ...)

FUNCTION are functions which get called with a single
argument (the value of PROPERTY) and are responsible for doing
whatever should be done."
  :type '(repeat (cons symbol (repeat (cons string string)))))

Тяжелый рабочий

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

(defun endless/replace-org-property (backend)
  "Convert org properties using `endless/org-property-mapping'.
Lookup BACKEND in `endless/org-property-mapping' for a list of
\(PROPERTY REPLACEMENT). For each healine being exported, if it has a
PROPERTY listed insert a string immediately after the healine given by
    (format REPLACEMENT PROPERTY-VALUE)"
  (let ((map (cdr (assoc backend endless/org-property-mapping)))
        value replacement)
    (when map      
      (org-map-entries
       (lambda () 
         (dolist (it map)
           (save-excursion
             (when (setq value (org-entry-get (point) (car it))) 
               (funcall (cdr it) value)))))))))

(add-hook 'org-export-before-processing-hook #'endless/replace-org-property)

Функции, которые вы определяете

Это те, которые делают фактическую замену. Ниже приведен пример для латекса.

(defun endless/insert-org-label-latex (label)
  "Insert \"\\\\label{LABEL}\\n\" after the :PROPERTY: drawer."
  (search-forward-regexp org-property-end-re)
  (forward-char 1)
  (insert (format "\\label{%s}\n" label)))

Результат

Оцените весь этот код выше, затем экспортируйте следующий буфер org в латекс.

* Test
  :PROPERTIES:
  :CUSTOM_LABEL: hi
  :END:
Test

Полученный латексный буфер должен быть примерно таким.

\section{Test}
\label{sec-1}
\label{hi}
Test
Malabarba
источник
Спасибо за код, комментарии и помощь. Это очень полезно. Я тоже многому научился. Спасибо.
GSL
5

Обратите внимание на фрагменты кода вы должны использовать текущую разработку-версию, (org-version) => "8.3beta".

Пожалуйста, используйте CUSTOM_IDи внутреннюю ссылку. См (info "(org) Handling links").

В большинстве случаев вас не должно беспокоить экспортированный результат внутреннего именования в Org. Ссылки на рисунки и заголовки, скажем, будут правильными при экспорте. См (info "(org) Internal links").

Для LaTeX попробуйте:

(with-temp-buffer
  (let ((org-latex-prefer-user-labels t))
(insert "
* h
:PROPERTIES:
:CUSTOM_ID: h
:END:")
(org-mode)
(org-latex-export-as-latex nil nil nil t)))

Результат:

\section{h}
\label{h}

В экспортерах такие как ox-odtи ox-htmlзаголовки содержат как внутренний идентификатор, так IDи CUSTOM_ID. Какая ссылка используется, зависит от ссылки:

(with-temp-buffer
  (let ((org-export-with-toc nil))
(insert "
* h
:PROPERTIES:
:CUSTOM_ID: h
:END:
[[*h]] [[#h]]")
(org-mode)
(org-html-export-as-html nil nil nil t)))

Результат:

<div id="outline-container-h" class="outline-2">
<h2 id="h"><a id="sec-1"></a><span class="section-number-2">1</span> h</h2>
<div class="outline-text-2" id="text-h">
<p>
<a href="#sec-1">1</a> <a href="#h">1</a>
</p>
</div>
</div>
Расмус
источник
Спасибо за указание пути по умолчанию для> 8,3 пользователей! Можно использовать способ по умолчанию для CUSTOM_ID, в то же время используя @ malabarba для передачи любого другого свойства org. Я на самом деле использую его таким образом, чтобы передать несколько других свойств (таких как cite-keys, жанр, место проведения и т. Д.), Кроме CUSTOM_ID.
gsl
1

Я не уверен, но вам, вероятно, нужно посоветовать или даже переписать функцию экспортера. Это в Орг 8 org-latex-export-headline.

Функция получает элемент заголовка, содержимое заголовка и список дополнительных свойств. В функции экспортера вы можете получить свойства элемента (включая вашу пользовательскую метку) с помощью org-element-property.

lunaryorn
источник
Большое спасибо за указатель. Насколько я понял из других постов / статей, новый orgэкспортер не слишком много работает с советами, а скорее создает filterфункции для вызова на определенной стадии процесса экспорта, примерно так: `` `(eval-after -load 'ox-latex' (add-to-list 'org-export-filter-final-output-functions' my-filter-function)) `` `(Я не уверен, почему синтаксис обратной галочки не работает в комментариях?)
gsl