Funkcja Emacsa do konwersji dowolnego WŁAŚCIWOŚCI ORG na dowolny ciąg znaków (mianowicie etykietę LaTeX)?

11

Mam wiele dokumentów jako pliki organizacji, które mają właściwość CUSTOM_LABEL, na przykład

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

W takim przypadku pliki należy wyeksportować jako LaTeX, tłumacząc każdy CUSTOM_LABELjako \label{marker}. Powyższy przykład powinien zostać przetłumaczony na \label{AP 1}.

Wiem już, jak wywoływać funkcje niestandardowe w czasie eksportu, ale nie jestem wystarczająco ekspertem, aby napisać defun, aby wykonać tę konkretną konwersję, tj. CUSTOM_LABEL->\label{}

Jak odmówić wstrzyknięcia, custom_labeljak \label{}napisano?

Byłbym wdzięczny nawet za jakiś pseudo-kod lub jakieś wskazówki.

Zadaję to pytanie tutaj, a nie w innych miejscach, ponieważ jest to bardziej pytanie Emacsa, ponieważ dokładnie przeszukałem instrukcję trybu org, a tego rodzaju funkcja jest obecnie niedostępna.

Ogólna funkcja do konwersji danego PROPERTY podczas eksportowania (LaTeX, HTML lub dowolny inny format) byłaby jeszcze lepsza.

Dziękuję Ci.

gsl
źródło
Tytuł wydaje się wyłączony. Jeśli rozumiem pytanie, chcesz przekształcić właściwość org w dowolny ciąg (mianowicie etykietę LaTeX), a nie w inną właściwość org.
Malabarba
@rasmus: Dziękuję za ten wskaźnik. Czytałem o tym zaledwie kilka godzin temu na emacs-orgmodeliście (między innymi lists.gnu.org/archive/html/emacs-orgmode/2014-09/msg00498.html ). Próbowałem tego kodu i właśnie ustawiałem org-latex-custom-id-as-label. Działa dobrze z eksportem HTML, ale nie ma żadnego wpływu na eksport LaTeX. Chciałbym móc polegać tylko na org-modepodstawowych funkcjach, ale podoba mi się odpowiedź @ malababrba, ponieważ pozwala to na miłe uogólnienie.
gsl
@rasmus Takie zachowanie jest mi potrzebne. Ale uruchomiłem twój kod, ale \section{h}\label{sec-1}używam 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.orgi Org-mode version 8.2.6 (release_8.2.6-1 @ /Applications/Emacs.app/Contents/Resources/lisp/org/). Ponadto, aby się upewnić, zmieniłem nazwę pliku .emacs.d, więc działał bez żadnych niestandardowych plików.
gsl
Tak fajnie, jak udało ci się zsyntetyzować cały działający przykład w jednym wierszu kodu!
gsl
Ach, to by to wyjaśniało! Próbowałem zainstalować najnowszą org-modeprzy użyciu tego el-getprzepisu: github.com/dimitri/el-get/blob/master/recipes/org-mode.rcp , ale wciąż otrzymuję Org-mode version 8.2.6 (release_8.2.6-1 @ /Users/gsl/.emacs.d/el-get/org-mode/lisp/Czy wiesz, jak dostosować ten przepis, aby móc go użyć do oddział deweloperów? Mógłbym również zadać to jako nowe pytanie. Dziękuję bardzo za zwrócenie na to uwagi.
gsl

Odpowiedzi:

10

Napisałem funkcję, która robi to, co chcesz w dość rozszerzalny sposób. Sprawdza, które nagłówki zawierają właściwość CUSTOM_LABEL (lub inną skonfigurowaną właściwość) i wywołuje funkcję endless/insert-org-label-latexna każdej z nich z wartością właściwości jako argumentem.

Przykładowy fragment pokazuje również, jak go rozszerzyć dla html lub innych backendów.

Skonfiguruj zamienniki

Za pomocą tej zmiennej możesz konfigurować właściwości, na których Ci zależy, i które funkcje są wywoływane do obsługi każdej właściwości.

(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)))))

Ciężki pracownik

Tę funkcję należy dodać do haka eksportu organizacji. Zajmuje się sprawdzaniem właściwości wymienionych powyżej i wywoływaniem funkcji powiązanych z tymi właściwościami.

(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)

Funkcje, które definiujesz

Są to te, które faktycznie zastępują. Poniżej znajduje się przykład przypadku lateksu.

(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)))

Wynik

Oceń cały ten kod powyżej, a następnie wyeksportuj następujący bufor organizacji do lateksu.

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

Powstały bufor lateksowy powinien być mniej więcej taki.

\section{Test}
\label{sec-1}
\label{hi}
Test
Malabarba
źródło
Dziękujemy za kod, komentarze i pomoc. To bardzo pomocne. Wiele się też nauczyłem. Dziękuję Ci.
gsl
5

Uwaga dla fragmentów kodu należy użyć bieżącej rozwojowych wersji (org-version) => "8.3beta".

Proszę używać CUSTOM_IDi wewnętrznego linkowania. Zobaczyć (info "(org) Handling links").

W większości przypadków nie powinieneś się przejmować wyeksportowanym wynikiem wewnętrznego nazewnictwa w organizacji. Na przykład linki do rycin i nagłówków będą poprawne po wyeksportowaniu. Zobaczyć (info "(org) Internal links").

W przypadku LaTeX spróbuj:

(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)))

Wynik:

\section{h}
\label{h}

W eksporterach takich jak ox-odti ox-htmlnagłówki zawierają zarówno wewnętrzny identyfikator, jak IDi CUSTOM_ID. To, który link zostanie użyty, zależy od linku:

(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)))

Wynik:

<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>
rasmus
źródło
Dziękujemy za wskazanie domyślnego sposobu dla> 8,3 użytkowników! Można użyć domyślnego sposobu dla CUSTOM_ID, przy jednoczesnym użyciu @ malabarba do przekazywania dowolnej innej właściwości org. Właściwie używam go w ten sposób, aby przekazać kilka innych właściwości (takich jak klawisze cytowania, gatunek, miejsce itp.) CUSTOM_ID.
gsl
1

Nie jestem pewien, ale prawdopodobnie musisz doradzić lub nawet zastąpić funkcję eksportera. To znaczy w Org 8 org-latex-export-headline.

Funkcja pobiera element nagłówka, treść nagłówka i dodatkową listę właściwości. W ramach funkcji eksportera możesz uzyskać właściwości elementu (w tym własną etykietę) za pomocą org-element-property.

księżycowy
źródło
Dziękuję bardzo za wskaźnik. O ile rozumiem z innych postów / artykułów, nowy orgeksporter nie pracuje zbyt wiele z doradztwem, ale raczej tworzy filterfunkcje, które można wywołać na pewnym etapie procesu eksportu, mniej więcej tak: `` (eval-after -load 'ox-latex' (add-to-list 'org-export-filter-final-output-functions' my-filter-function)) `` (Nie jestem pewien, dlaczego składnia zaznaczania wstecznego nie działa w komentarzach?)
gsl