Fonction Emacs pour convertir une PROPRIÉTÉ ORG arbitraire en une chaîne arbitraire (à savoir, une étiquette LaTeX)?

11

J'ai de nombreux documents en tant que fichiers org qui ont une propriété CUSTOM_LABEL, comme

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

Dans ce cas, les fichiers doivent être exportés en tant que LaTeX, traduisant chacun CUSTOM_LABELen a \label{marker}. L'exemple ci-dessus devrait se traduire par \label{AP 1}.

Je sais déjà comment appeler des fonctions personnalisées au moment de l'exportation, mais je ne suis pas assez expert pour écrire un defun pour faire cette conversion particulière, c'est CUSTOM_LABEL-à- dire ->\label{}

Comment le defun pour injecter un custom_labeltel \label{}peut-il être écrit?

J'apprécierais même juste un pseudo-code ou des pointeurs.

Je pose cette question ici à la place d'autres endroits, car il s'agit plus d'une question Emacs, car j'ai cherché à fond dans le manuel du mode org, et ce type de fonctionnalité n'est actuellement pas disponible.

Une fonction générique pour convertir une PROPRIÉTÉ donnée lors de l'exportation (LaTeX, HTML ou tout autre format), serait encore mieux.

Je vous remercie.

gsl
la source
Le titre semble éteint. Si je comprends la question, vous voulez transformer une propriété d'organisation en une chaîne arbitraire (à savoir, une étiquette LaTeX), pas en une autre propriété d'organisation.
Malabarba
@rasmus: Merci pour ce pointeur. Je lisais à ce sujet il y a quelques heures sur la emacs-orgmodeliste (entre autres, lists.gnu.org/archive/html/emacs-orgmode/2014-09/msg00498.html ). J'ai essayé ce code, et juste le réglage org-latex-custom-id-as-label. Cela fonctionne très bien avec l'exportation HTML, mais cela n'a aucun effet avec l'exportation LaTeX. Je souhaite pouvoir compter uniquement sur org-modeles fonctions de base, j'aime toujours la réponse de @ malababrba, car elle permet une belle généralisation.
gsl
@rasmus C'est le comportement dont j'ai besoin. Mais j'ai exécuté votre code, mais je comprends que \section{h}\label{sec-1}j'utilise 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.orget Org-mode version 8.2.6 (release_8.2.6-1 @ /Applications/Emacs.app/Contents/Resources/lisp/org/). De plus, pour m'assurer que j'ai renommé mon .emacs.d, il a donc fonctionné sans aucun élément personnalisé.
gsl
Si bien comment vous avez réussi à synthétiser un exemple de travail complet en une seule ligne de code!
gsl
Ah, ça expliquerait ça! J'ai essayé d'installer la dernière en org-modeutilisant cette el-getrecette: github.com/dimitri/el-get/blob/master/recipes/org-mode.rcp , mais j'obtiens toujours SavezOrg-mode version 8.2.6 (release_8.2.6-1 @ /Users/gsl/.emacs.d/el-get/org-mode/lisp/ -vous comment modifier cette recette afin de pouvoir l'utiliser pour le dev-branch? Je pourrais aussi poser cette question comme nouvelle question. Merci beaucoup d'avoir souligné cela.
gsl

Réponses:

10

J'ai écrit une fonction qui fait ce que vous voulez d'une manière assez extensible. Il vérifie quels titres contiennent la propriété CUSTOM_LABEL (ou une autre propriété que vous configurez) et appelle la fonction endless/insert-org-label-latexsur chacun d'eux avec la valeur de la propriété comme argument.

L'extrait d'exemple montre également comment l'étendre pour le HTML ou d'autres backends.

Configurer les remplacements

Avec cette variable, vous pouvez configurer les propriétés qui vous intéressent et quelles fonctions sont appelées pour gérer chaque propriété.

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

Le travailleur lourd

Cette fonction est ce que vous devez ajouter au hook d'exportation de l'organisation. Il prend soin de vérifier les propriétés répertoriées ci-dessus et d'appeler les fonctions associées à ces propriétés.

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

Les fonctions que vous définissez

Ce sont eux qui effectuent le remplacement réel. Voici un exemple pour le boîtier en latex.

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

Résultat

Évaluez tout ce code ci-dessus, puis exportez le tampon d'organisation suivant vers latex.

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

Le tampon en latex résultant devrait ressembler à ceci.

\section{Test}
\label{sec-1}
\label{hi}
Test
Malabarba
la source
Merci pour le code, les commentaires et l'aide. C'est très utile. J'ai aussi beaucoup appris. Je vous remercie.
gsl
5

Note pour les extraits de code , vous devez utiliser le courant de développement version, (org-version) => "8.3beta".

Veuillez utiliser CUSTOM_IDet lien interne. Tu vois (info "(org) Handling links").

Dans la plupart des cas, vous ne devez pas vous inquiéter du résultat exporté de la dénomination interne dans Org. Les liens vers les chiffres et les titres, par exemple, seront corrects lors de l'exportation. Tu vois (info "(org) Internal links").

Pour LaTeX, essayez:

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

Résultat:

\section{h}
\label{h}

Dans les exportateurs tels que ox-odtet les ox-htmltitres contiennent à la fois l'ID interne IDet CUSTOM_ID. Le lien utilisé dépend du lien:

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

Résultat:

<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
la source
Merci d'avoir indiqué la voie par défaut pour> 8,3 utilisateurs! On pourrait utiliser la méthode par défaut pour CUSTOM_ID, tout en utilisant @ malabarba pour passer toute autre propriété organisationnelle. Je l'utilise en fait de cette façon pour passer quelques autres propriétés (comme les touches de citation, le genre, le lieu, etc.), à côté CUSTOM_ID.
gsl
1

Je ne suis pas sûr, mais vous devrez probablement conseiller ou même remplacer la fonction d'exportateur. Dans Org 8, c'est org-latex-export-headline.

La fonction obtient l'élément de titre, le contenu du titre et une liste de propriétés supplémentaires. Dans la fonction d'exportation, vous pouvez obtenir les propriétés des éléments (y compris votre étiquette personnalisée) avec org-element-property.

lunaryorn
la source
Merci beaucoup pour le pointeur. D'après ce que j'ai compris d'autres articles / articles, le nouvel orgexportateur ne travaille pas trop avec le conseil, mais plutôt on crée des filterfonctions à appeler à une certaine étape du processus d'exportation, à peu près comme ceci: `` (eval-after -load 'ox-latex' (add-to-list 'org-export-filter-final-output-functions' my-filter-function)) `` (Je ne sais pas pourquoi la syntaxe de retour à zéro ne fonctionne pas dans les commentaires?)
gsl