Функція Emacs для перетворення довільної ORG IMPERTY в довільну рядок (а саме, мітка LaTeX)?


11

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

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

У цьому випадку файли потрібно експортувати як LaTeX, перекладаючи кожен CUSTOM_LABELяк \label{marker}. Наведений вище приклад повинен бути перекладений на \label{AP 1}.

Я вже знаю , як назвати призначені для користувача функції під час експорту, але я не фахівець досить , щоб написати визначення функції , щоб зробити це особливе перетворення, тобто CUSTOM_LABEL->\label{}

Як може розрядник ввести а так, custom_labelяк \label{}написано?

Я хотів би оцінити навіть якийсь псевдо-код або деякі покажчики.

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

Загальна функція для перетворення заданої ВЛАСНОСТІ при експорті (LaTeX, HTML або будь-який інший формат) була б ще кращою.

Дякую.


Назва видається вимкненою. Якщо я розумію питання, ви хочете перетворити властивість org в довільну рядок (а саме мітку LaTeX), а не в іншу властивість org.
Малабарба

@rasmus: Дякую за цей покажчик. Я читав про це лише кілька годин тому в emacs-orgmodeсписку (серед інших, list.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

Дякую за код, коментарі та допомогу. Це дуже корисно. Я багато чому теж навчився. Дякую.
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's для передачі будь-якого іншого органу власності. Я фактично використовую його таким чином, щоб передати поруч деякі інші властивості (наприклад, cite-ключі, жанр, місце проведення тощо) CUSTOM_ID.
gsl

1

Я не впевнений, але вам, ймовірно, потрібно порадити або навіть переписати функцію експортера. В Org 8, тобто org-latex-export-headline.

Функція отримує заголовок, вміст заголовка та додатковий список властивостей. У межах функції експортера ви можете отримати властивості елементів (включаючи власну мітку) за допомогою org-element-property.


Дуже дякую за покажчик. Наскільки я зрозумів з інших публікацій / статей, новий orgекспортер не надто працює над порадами, а швидше створює filterфункції, які потрібно викликати на певному етапі процесу експорту, приблизно так: `` `(eval-after -load 'ox-latex' (додавання до списку 'org-export-filter-final-output-функции' my-filter-function)) `` `(я не впевнений, чому синтаксис зворотного галочки не працює в коментарях?)
gsl
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.