2014-05-17 14 views
5

In Orgmode, esiste un modo per creare il groviglio solo in corrispondenza di un sottoalbero corrispondente (o non corrispondente) a un tag specifico?Orgmode: come filtrare i blocchi per essere groviglio?

Per esempio con il seguente codice

* A 
#+BEGIN_SRC c 
    printf("Not exported"); 
#+END_SRC 

* B    :D: 

#+BEGIN_SRC c 
    printf("Exported"); 
#+END_SRC 

esportazione lungo tag D, il file groviglio C Volontà contiene solo printf("Exported");

sto usando org-mode di organizzare il mio emacs di configurazione, e il mio obiettivo è a derivare diverse configurazioni da quella principale emacs-config.org. (per esempio un lightconfig segnando solo lo specifico)

risposta

2

Ho provato a fare ricerche un po 'di tempo fa e non ho trovato risposta rapida. Ho finito per modificare org-babel-tangle-collect-blocks per implementare questa funzionalità

Ecco la funzione modificata. L'elenco org-babel-tags è un elenco di tag ok. Per il vostro esempio, è necessario impostare con (setq org-babel-tags '("D"))

(ho aggiunto le prime 4 righe dopo la prima chiamata a 'meno')

(defvar org-babel-tags nil 
    "only tangle entries that has a tag in this list") 

(defun org-babel-tangle-collect-blocks (&optional language) 
    "Collect source blocks in the current Org-mode file. 
Return an association list of source-code block specifications of 
the form used by `org-babel-spec-to-string' grouped by language. 
Optional argument LANG can be used to limit the collected source 
code blocks by language." 
    (let ((block-counter 1) (current-heading "") blocks) 
    (org-babel-map-src-blocks (buffer-file-name) 
     ((lambda (new-heading) 
     (if (not (string= new-heading current-heading)) 
      (progn 
       (setq block-counter 1) 
       (setq current-heading new-heading)) 
      (setq block-counter (+ 1 block-counter)))) 
     (replace-regexp-in-string "[ \t]" "-" 
           (condition-case nil 
            (or (nth 4 (org-heading-components)) 
             "(dummy for heading without text)") 
            (error (buffer-file-name))))) 
     (let* ((start-line (save-restriction (widen) 
              (+ 1 (line-number-at-pos (point))))) 
      (file (buffer-file-name)) 
      (info (org-babel-get-src-block-info 'light)) 
      (src-lang (nth 0 info))) 
     (unless (or (string= (cdr (assoc :tangle (nth 2 info))) "no") 
        (null (intersection (mapcar 'intern org-babel-tags) 
             (save-excursion 
              (org-back-to-heading) 
              (mapcar 'intern (org-get-tags)))))) 

        (unless (and language (not (string= language src-lang))) 
         (let* ((info (org-babel-get-src-block-info)) 
          (params (nth 2 info)) 
          (extra (nth 3 info)) 
          (cref-fmt (or (and (string-match "-l \"\\(.+\\)\"" extra) 
               (match-string 1 extra)) 
              org-coderef-label-format)) 
          (link ((lambda (link) 
             (and (string-match org-bracket-link-regexp link) 
              (match-string 1 link))) 
            (org-no-properties 
            (org-store-link nil)))) 
          (source-name 
           (intern (or (nth 4 info) 
              (format "%s:%d" 
                current-heading block-counter)))) 
          (expand-cmd 
           (intern (concat "org-babel-expand-body:" src-lang))) 
          (assignments-cmd 
           (intern (concat "org-babel-variable-assignments:" src-lang))) 
          (body 
           ((lambda (body) ;; run the tangle-body-hook 
           (with-temp-buffer 
            (insert body) 
            (when (string-match "-r" extra) 
            (goto-char (point-min)) 
            (while (re-search-forward 
              (replace-regexp-in-string "%s" ".+" cref-fmt) nil t) 
             (replace-match ""))) 
            (run-hooks 'org-babel-tangle-body-hook) 
            (buffer-string))) 
           ((lambda (body) ;; expand the body in language specific manner 
            (if (assoc :no-expand params) 
             body 
            (if (fboundp expand-cmd) 
             (funcall expand-cmd body params) 
             (org-babel-expand-body:generic 
             body params 
             (and (fboundp assignments-cmd) 
              (funcall assignments-cmd params)))))) 
           (if (org-babel-noweb-p params :tangle) 
            (org-babel-expand-noweb-references info) 
            (nth 1 info))))) 
          (comment 
           (when (or (string= "both" (cdr (assoc :comments params))) 
             (string= "org" (cdr (assoc :comments params)))) 
           ;; from the previous heading or code-block end 
           (funcall 
           org-babel-process-comment-text 
           (buffer-substring 
            (max (condition-case nil 
              (save-excursion 
              (org-back-to-heading t) ; sets match data 
              (match-end 0)) 
             (error (point-min))) 
             (save-excursion 
             (if (re-search-backward 
               org-babel-src-block-regexp nil t) 
              (match-end 0) 
              (point-min)))) 
            (point))))) 
          by-lang) 
         ;; add the spec for this block to blocks under it's language 
         (setq by-lang (cdr (assoc src-lang blocks))) 
         (setq blocks (delq (assoc src-lang blocks) blocks)) 
         (setq blocks (cons 
             (cons src-lang 
              (cons (list start-line file link 
                 source-name params body comment) 
                by-lang)) blocks))))))) 
    ;; ensure blocks in the correct order 
    (setq blocks 
      (mapcar 
      (lambda (by-lang) (cons (car by-lang) (reverse (cdr by-lang)))) 
      blocks)) 
blocks)) 
+0

hey @ mike, quale versione di orgmode hai basato? Sono andato a 'ob-tangle' da cui proviene la funzione, e sia il codice che la firma sono diversi: signature' (defun org-babel-tangle-collect-blocks (& file-tangle opzionale della lingua) ' – AdrieanKhisbe

+0

@AdrieanKhisbe Sto usando 7.9.3f – michaelJohn

+0

Okey dokey, in modo che possano avere refactoring l'intera funzione per la versione principale 8. Ho perso la ricerca di un modo per ottenerlo per ora dato che con 'use-package' ho una soluzione. Grazie ancora! :) – AdrieanKhisbe

3

Per ottenere questo comportamento si può fare uso del fatto che a parte yes e no, l'argomento dell'intestazione :tangle per i blocchi di codice di Org Babel è anche understands file names; Ad esempio, per ogni dato blocco di codice puoi dire a Org Babel quale file vuoi che il blocco venga aggrovigliato. La mia idea è quella di impostare automaticamente il nome del file per ogni blocco di codice sotto un certo titolo quando si aggiunge un tag per il titolo:

(defun org-babel-set-tangle-file() 
    (let ((tag (car (org-get-local-tags)))) 
    (org-narrow-to-subtree) 
    (while (re-search-forward "\\(:tangle \\).*" nil t) 
     (replace-match (concat "\\1" tag ".el"))) 
    (widen))) 

(add-hook 'org-after-tags-change-hook 'org-babel-set-tangle-file) 

Il comportamento risultante è che quando si chiama org-babel-tangle per il file corrente, tutto il codice blocchi appartenenti a

  • titoli senza un tag saranno aggrovigliate al file di default groviglio (s)
  • un titolo etichettato sarà aggrovigliato in un file denominato dopo il tag.

Si noti che la funzione precedente imposta l'estensione del file di file di tangenti specifici del tag su .el; dal momento che dici che ti piacerebbe produrre diverse configurazioni di Emacs, ho pensato che sarebbe stato un valore predefinito ragionevole (anche se nel tuo esempio stai mostrando codice C).

+0

Ho appena provato ma non ha funzionato come previsto.(dal momento che si sta escludendo che ci sia: tag tangle, e preferisco non aggiungere tutto a tutti il ​​blocco) Preferisco l'idea di mike per filtrare il blocco raccolto. si sente più flessibile e può averne più logica – AdrieanKhisbe

Problemi correlati