Funzione Emacs per convertire una PROPRIETÀ ORG arbitraria in una stringa arbitraria (ovvero un'etichetta LaTeX)?


11

Ho molti documenti come file org che hanno una proprietà CUSTOM_LABEL, come

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

In questo caso, i file devono essere esportati come LaTeX, traducendoli CUSTOM_LABELcome a \label{marker}. L'esempio sopra dovrebbe tradursi in \label{AP 1}.

So già come chiamare le funzioni personalizzate al momento dell'esportazione, ma non sono abbastanza esperto da scrivere un defun per fare quella conversione particolare, cioè CUSTOM_LABEL->\label{}

Come può il defun iniettare un custom_labelcome \label{}scritto?

Gradirei anche solo alcuni pseudo-codici o alcuni puntatori.

Sto ponendo questa domanda qui invece di altri posti, perché questa è più una domanda Emacs, poiché ho cercato a fondo il manuale della modalità org e quel tipo di funzionalità non è al momento disponibile.

Una funzione generica per convertire una determinata PROPRIETÀ durante l'esportazione (LaTeX, HTML o qualsiasi altro formato) sarebbe ancora migliore.

Grazie.


Il titolo sembra spento. Se capisco la domanda, vuoi trasformare una proprietà org in una stringa arbitraria (ovvero un'etichetta LaTeX), non in un'altra proprietà org.
Malabarba,

@rasmus: grazie per quel puntatore. Ne stavo leggendo qualche ora fa sulla emacs-orgmodelista (tra gli altri, lists.gnu.org/archive/html/emacs-orgmode/2014-09/msg00498.html ). Ho provato quel codice e ho appena impostato org-latex-custom-id-as-label. Funziona bene con l'esportazione HTML, ma non ha alcun effetto con l'esportazione LaTeX. Vorrei poter fare affidamento solo sulle org-modefunzioni di base, tuttavia mi piace la risposta di @ malababrba, in quanto consente una buona generalizzazione.
gsl

@rasmus Questo è il comportamento di cui ho bisogno. Ma ho eseguito il tuo codice, ma capisco \section{h}\label{sec-1}che sto usando 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.orge Org-mode version 8.2.6 (release_8.2.6-1 @ /Applications/Emacs.app/Contents/Resources/lisp/org/). Inoltre, per essere sicuro, ho rinominato il mio .emacs.d, quindi è stato eseguito senza roba personalizzata.
gsl

Così bello come sei riuscito a sintetizzare un intero esempio funzionante in una sola riga di codice!
gsl

Ah, questo lo spiegherebbe! Ho provato a installare l'ultima volta org-modeusando questa el-getricetta: github.com/dimitri/el-get/blob/master/recipes/org-mode.rcp , ma ottengo ancora Org-mode version 8.2.6 (release_8.2.6-1 @ /Users/gsl/.emacs.d/el-get/org-mode/lisp/Sapresti come modificare quella ricetta in modo da poterla usare per il dev-ramo? Potrei anche fare questa domanda come nuova domanda. Grazie mille per averlo sottolineato.
gsl

Risposte:


10

Ho scritto una funzione che fa quello che vuoi in modo abbastanza estensibile. Verifica quali titoli contengono la proprietà CUSTOM_LABEL (o qualche altra proprietà configurata) e chiama la funzione endless/insert-org-label-latexsu ciascuno di essi con il valore della proprietà come argomento.

Lo snippet di esempio mostra anche come estenderlo per HTML o altri backend.

Configura le sostituzioni

Con questa variabile puoi configurare le proprietà che ti interessano e quali funzioni vengono chiamate per gestire ogni proprietà.

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

Il lavoratore pesante

Questa funzione è ciò che dovresti aggiungere al hook di esportazione dell'organizzazione. Si occupa di verificare le proprietà sopra elencate e di chiamare le funzioni associate a tali proprietà.

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

Le funzioni che definisci

Questi sono quelli che effettuano la sostituzione effettiva. Di seguito è riportato un esempio per il caso in lattice.

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

Risultato

Valuta tutto questo codice sopra, quindi esporta il seguente buffer organizzativo in lattice.

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

Il buffer di lattice risultante dovrebbe essere qualcosa del genere.

\section{Test}
\label{sec-1}
\label{hi}
Test

Grazie per il codice, i commenti e l'aiuto. È molto utile. Ho anche imparato molto. Grazie.
gsl,

5

Nota per i frammenti di codice è necessario utilizzare lo sviluppo della versione corrente, (org-version) => "8.3beta".

Si prega di utilizzare CUSTOM_IDe collegamento interno. Vedere (info "(org) Handling links").

Nella maggior parte dei casi non dovresti preoccuparti del risultato esportato della denominazione interna in Org. I collegamenti a figure e titoli, diciamo, saranno corretti quando esportati. Vedere (info "(org) Internal links").

Per LaTeX provare:

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

Risultato:

\section{h}
\label{h}

Negli esportatori come ox-odte i ox-htmltitoli contengono sia ID interno, IDsia CUSTOM_ID. Il collegamento utilizzato dipende dal collegamento:

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

Risultato:

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

Grazie per aver indicato la modalità predefinita per> 8.3 utenti! Si potrebbe usare il modo predefinito per CUSTOM_ID, pur usando @ malabarba per passare qualsiasi altra proprietà org. In realtà lo sto usando in questo modo per passare alcune altre proprietà (come cite-keys, genere, luogo, ecc.), A fianco CUSTOM_ID.
gsl

1

Non ne sono sicuro, ma probabilmente è necessario avvisare o addirittura sovrascrivere la funzione di esportazione. In Org 8, cioè org-latex-export-headline.

La funzione ottiene l'elemento del titolo, il contenuto del titolo e un elenco di proprietà aggiuntivo. All'interno della funzione esportatore, puoi ottenere le proprietà dell'elemento (inclusa la tua etichetta personalizzata) con org-element-property.


Grazie mille per il puntatore. Per quanto ho capito da altri post / articoli, il nuovo orgesportatore non lavora troppo con la consulenza, ma piuttosto si creano filterfunzioni da chiamare in una certa fase del processo di esportazione, più o meno così: `` (eval-after -load 'ox-latex' (aggiungi alla lista 'org-export-filter-final-output-funzioni' my-filter-function)) `` (non sono sicuro del motivo per cui la sintassi back-tick non funziona nei commenti?)
gsl
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.