¿Emacs funciona para convertir una PROPIEDAD ORG arbitraria en una cadena arbitraria (es decir, una etiqueta LaTeX)?

11

Tengo muchos documentos como archivos de organización que tienen una propiedad CUSTOM_LABEL, como

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

En este caso, los archivos deben exportarse como LaTeX, traduciéndose CUSTOM_LABELcomo a \label{marker}. El ejemplo anterior debería traducirse a \label{AP 1}.

Ya sé cómo llamar a funciones personalizadas en el momento de la exportación, pero no soy lo suficientemente experto como para escribir un defun para hacer esa conversión en particular, es decir CUSTOM_LABEL->\label{}

¿Cómo puede el defun inyectar un custom_labelcomo \label{}se escribe?

Agradecería incluso algunos pseudocódigos o algunos punteros.

Estoy haciendo esta pregunta aquí en lugar de otros lugares, porque esta es más una pregunta de Emacs, ya que busqué a fondo el manual del modo org, y ese tipo de característica no está disponible actualmente.

Una función genérica para convertir una PROPIEDAD dada al exportar (LaTeX, HTML o cualquier otro formato) sería aún mejor.

Gracias.

gsl
fuente
El título parece apagado. Si entiendo la pregunta, desea convertir una propiedad de la organización en una cadena arbitraria (es decir, una etiqueta LaTeX), no en otra propiedad de la organización.
Malabarba
@rasmus: Gracias por ese puntero. Estaba leyendo sobre eso hace unas horas en la emacs-orgmodelista (entre otras, lists.gnu.org/archive/html/emacs-orgmode/2014-09/msg00498.html ). Intenté ese código, y solo configuré org-latex-custom-id-as-label. Funciona bien con la exportación HTML, pero no tiene ningún efecto con la exportación LaTeX. Desearía poder confiar solo en org-modelas funciones principales, aún así me gusta la respuesta de @ malababrba, ya que permite una buena generalización.
gsl
@rasmus Ese es el comportamiento que necesito. Pero ejecuté su código, pero entiendo \section{h}\label{sec-1}que estoy 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.orgy Org-mode version 8.2.6 (release_8.2.6-1 @ /Applications/Emacs.app/Contents/Resources/lisp/org/). Además, para asegurarme, cambié el nombre de mi .emacs.d, por lo que se ejecutó sin cosas personalizadas.
gsl
¡Qué bueno cómo logró sintetizar un ejemplo de trabajo completo en solo una línea de código!
gsl
¡Ah, eso lo explicaría! Intenté instalar la última versión org-modeusando esta el-getreceta: github.com/dimitri/el-get/blob/master/recipes/org-mode.rcp , pero todavía obtengo Org-mode version 8.2.6 (release_8.2.6-1 @ /Users/gsl/.emacs.d/el-get/org-mode/lisp/¿ Sabrías cómo ajustar esa receta para poder usarla para el rama de desarrollo? También podría hacer esto como una nueva pregunta. Muchas gracias por señalar eso.
gsl

Respuestas:

10

He escrito una función que hace lo que quieres de una manera bastante extensible. Comprueba qué títulos contienen la propiedad CUSTOM_LABEL (o alguna otra propiedad que configure) y llama a la función endless/insert-org-label-latexen cada uno de ellos con el valor de la propiedad como argumento.

El fragmento de ejemplo también muestra cómo extenderlo para html u otros backends.

Configurar los reemplazos

Con esta variable puede configurar las propiedades que le interesan y qué funciones se llaman para manejar cada propiedad.

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

El trabajador pesado

Esta función es lo que debe agregar al enlace de exportación de la organización. Se encarga de verificar las propiedades enumeradas anteriormente y llamar a las funciones asociadas con esas propiedades.

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

Las funciones que define

Estos son los que hacen el reemplazo real. A continuación se muestra un ejemplo para el caso de látex.

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

Resultado

Evalúe todo este código anterior, luego exporte el siguiente búfer de organización a latex.

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

El búfer de látex resultante debería ser algo como esto.

\section{Test}
\label{sec-1}
\label{hi}
Test
Malabarba
fuente
Gracias por el código, los comentarios y la ayuda. Es de mucha ayuda. También aprendí mucho. Gracias.
gsl
5

Nota para los fragmentos de código que debe utilizar la corriente de desarrollo-versión, (org-version) => "8.3beta".

Utilice CUSTOM_IDy enlace interno. Ver (info "(org) Handling links").

En la mayoría de los casos, no debe preocuparse por el resultado exportado de la denominación interna en Org. Los enlaces a figuras y titulares, por ejemplo, serán correctos cuando se exporten. Ver (info "(org) Internal links").

Para LaTeX intente:

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

Resultado:

\section{h}
\label{h}

En los exportadores como ox-odty los ox-htmltitulares contienen tanto ID interna IDcomo CUSTOM_ID. El enlace utilizado depende del enlace:

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

Resultado:

<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
fuente
¡Gracias por señalar la forma predeterminada para> 8.3 usuarios! Uno podría usar la forma predeterminada para CUSTOM_ID, mientras todavía usa @ malabarba para pasar cualquier otra propiedad de organización. De hecho, lo estoy usando de esa manera para pasar algunas otras propiedades (como cite-keys, género, lugar, etc.), además CUSTOM_ID.
gsl
1

No estoy seguro, pero es probable que necesite aconsejar o incluso sobrescribir la función de exportador. En Org 8, eso es org-latex-export-headline.

La función obtiene el elemento de título, el contenido del título y una lista de propiedades adicional. Dentro de la función de exportador, puede obtener propiedades de elementos (incluida su etiqueta personalizada) con org-element-property.

Lunaryorn
fuente
Muchas gracias por el puntero. Por lo que entendí de otras publicaciones / artículos, el nuevo orgexportador no trabaja demasiado con el asesoramiento, sino que crea filterfunciones que se llamarán en una determinada etapa del proceso de exportación, más o menos así: `` `(eval-after -load 'ox-latex' (agregar a la lista 'org-export-filter-final-output-functions' my-filter-function)) `` (No estoy seguro de por qué la sintaxis de retroceso no funciona en comentarios?)
gsl