Bagaimana cara mengekspor judul tingkat atas dari buffer mode-org ke file yang terpisah?


17

Bagaimana setiap tajuk tingkat atas dari org-modebuffer diekspor ke file terpisah yang dinamai sesuai dengan nilai judul CUSTOM_ID+ yang disanitasi?

Katakanlah buffer berisi:

* Title of Heading 1
  :PROPERTIES:
  :CUSTOM_ID: fibrillogenesis
  :END:
  Suspendisse potenti. Mauris ac felis vel velit tristique imperdiet.  

** Sub-Heading
   Nullam rutrum.

* Another Title for Heading 2
  :PROPERTIES:
  :CUSTOM_ID: mitochondrion
  :END:
  Mauris mollis tincidunt felis.  Sed bibendum.

Hasil akhirnya adalah direktori yang berisi dua file, satu untuk masing-masing dari dua judul tingkat atas, dengan format yang dipilih pada waktu ekspor (HTML, LaTeX, dll.), Dengan nama file dan konten berikut:

  1. Nama file dari pos yang diekspor pertama: fibrillogenesis-title-of-heading-1.[ext]

    Konten yang diekspor, sesuai dengan tajuk tingkat atas pertama asli:

    * Title of Heading 1
      :PROPERTIES:
      :CUSTOM_ID: fibrillogenesis
      :END:
      Suspendisse potenti. Mauris ac felis vel velit tristique imperdiet.  
    
    ** Sub-Heading 
       Nullam rutrum.
    
  2. Nama file dari pos yang diekspor kedua: mitochondrion-another-title-for-heading-2.[ext]

    Konten yang diekspor, sesuai dengan tajuk tingkat atas kedua asli:

    * Another Title for Heading 2
    :PROPERTIES:
    :CUSTOM_ID: mitochondrion
    :END:
    Mauris mollis tincidunt felis.  Sed bibendum. 
    

Saya akan sangat berterima kasih atas petunjuk, arah, kodesemu, atau kode nyata (lebih baik).

Jawaban:


27

Perintah berikut memungkinkan Anda memilih back-end dan kemudian mengekspor setiap subtree tingkat atas ke file terpisah:

(defun org-export-all (backend)
  "Export all subtrees that are *not* tagged with :noexport: to
separate files.

Note that subtrees must have the :EXPORT_FILE_NAME: property set
to a unique value for this to work properly."
  (interactive "sEnter backend: ")
  (let ((fn (cond ((equal backend "html") 'org-html-export-to-html)
                  ((equal backend "latex") 'org-latex-export-to-latex)
                  ((equal backend "pdf") 'org-latex-export-to-pdf))))
    (save-excursion
      (set-mark (point-min))
      (goto-char (point-max))
      (org-map-entries (lambda () (funcall fn nil t)) "-noexport" 'region-start-level))))

Ini saat ini mendukung ekspor HTML ( html), LaTeX ( latex), dan PDF ( pdf). Anda dapat menambahkan dukungan untuk back-end lainnya dengan menambahkan lebih banyak klausa cond.

Seperti kata docstring, untuk setiap subtree Anda perlu mengatur :EXPORT_FILE_NAME:properti ke nama file yang Anda inginkan untuk diekspor. (Lihat di bawah untuk opsi lain.)

Secara otomatis menghasilkan nama file ekspor dari teks judul

Jika Anda tidak ingin menambahkan :EXPORT_FILE_NAME:properti ke setiap tajuk tingkat atas, Anda dapat memodifikasi org-export-alluntuk membuat nama file secara otomatis dari misalnya teks tajuk, pengaturan sementara :EXPORT_FILE_NAME:selama ekspor:

(defun org-export-all (backend)
  "Export all subtrees that are *not* tagged with :noexport: to
separate files.

Subtrees that do not have the :EXPORT_FILE_NAME: property set
are exported to a filename derived from the headline text."
  (interactive "sEnter backend: ")
  (let ((fn (cond ((equal backend "html") 'org-html-export-to-html)
                  ((equal backend "latex") 'org-latex-export-to-latex)
                  ((equal backend "pdf") 'org-latex-export-to-pdf)))
        (modifiedp (buffer-modified-p)))
    (save-excursion
      (set-mark (point-min))
      (goto-char (point-max))
      (org-map-entries
       (lambda ()
         (let ((export-file (org-entry-get (point) "EXPORT_FILE_NAME")))
           (unless export-file
             (org-set-property
              "EXPORT_FILE_NAME"
              (replace-regexp-in-string " " "_" (nth 4 (org-heading-components)))))
           (funcall fn nil t)
           (unless export-file (org-delete-property "EXPORT_FILE_NAME"))
           (set-buffer-modified-p modifiedp)))
       "-noexport" 'region-start-level))))

Fungsi ini menghasilkan nama file ekspor dengan mengganti spasi dengan "_" dalam teks judul. Jika Anda ingin membuat nama file dengan cara lain, ubah replace-regexp-in-stringsexp menjadi apa pun yang Anda suka.

Menghasilkan :EXPORT_FILE_NAME:saat pengaturan:CUSTOM_ID:

Dengan saran berikut, org-set-propertysecara otomatis akan menetapkan nilai yang sesuai :EXPORT_FILE_NAME:ketika Anda menetapkan :CUSTOM_ID::

(defadvice org-set-property (after set-export-file-name
                                   (property value) activate compile)
  (when (equal org-last-set-property "CUSTOM_ID")
    (let ((export-file-name
           (concat (org-entry-get nil "CUSTOM_ID")
                   "-"
                   (replace-regexp-in-string " " "-" (downcase (org-get-heading t t))))))
      (org-entry-put nil "EXPORT_FILE_NAME" export-file-name))))

Perhatikan bahwa ini tidak akan menambahkan ekstensi file ke nilai :EXPORT_FILE_NAME:tetapi itu tidak masalah karena ketika mengekspor ke back-end tertentu, org-mode secara otomatis akan memilih ekstensi yang benar untuk file yang dihasilkan .


Informasi tambahan

Memperbarui subtree yang ada secara massal

Jika Anda memiliki banyak subtree yang ada yang perlu Anda atur :EXPORT_FILE_NAME:untuk properti, Anda bisa menggunakan makro keyboard . Posisikan titik pada subtree pertama, lalu lakukan hal berikut:

  • F3

    ... untuk mulai merekam.

  • C-c C-x p CUSTOM_ID RET RET

    ... untuk membuat Emacs ditetapkan :EXPORT_FILE_NAME:berdasarkan :CUSTOM_ID:.

  • C-c C-f

    ... untuk pindah ke tajuk tingkat atas berikutnya.

  • F4

    ... untuk berhenti merekam.

Untuk mengulang makro untuk subtree berikutnya, tekan F4. Untuk mengulang makro untuk semua subtrees yang tersisa, tekan M-0 F4(itu nol).

Menyimpan makro untuk sesi mendatang

Secara default, makro keyboard tidak disimpan di seluruh sesi. Untuk menyimpan makro di file init Anda untuk digunakan nanti, lakukan ini:

  1. Beri nama makro:

    M-x name-last-kbd-macro RET org-set-export-file-name RET

  2. Temukan file init Anda dan pindah ke tempat di mana Anda ingin memasukkan makro.

  3. Masukkan makro:

    M-x insert-kbd-macro RET org-set-export-file-name RET

    Emacs akan menyisipkan kode berikut pada titik:

    (fset 'org-set-export-file-name
       "\C-c\C-xpCUSTOM_ID\C-m\C-m\C-c\C-f")
    

    Jika Anda menyipitkan mata cukup keras, Anda dapat melihat bahwa argumen kedua fsetberisi urutan tombol yang Anda tekan saat Anda merekam makro :)

  4. (Opsional) Untuk hasil terbaik, Anda mungkin ingin mengikat org-set-export-file-namekunci:

    (define-key org-mode-map (kbd "<f6>") 'org-set-export-file-name)
  5. Menyimpan.


1
Bagus. Bisakah Anda memberi saya petunjuk tentang cara mengatur :EXPORT_FILE_NAME:properti secara terprogram :CUSTOM_ID:+heading-title-lowercaseduntuk setiap heading?
gsl

1
@gsl Anda dapat menyarankan org-set-propertyuntuk membuat :EXPORT_FILE_NAME:properti secara otomatis ketika Anda mengatur :CUSTOM_ID:.
itsjeyd

1
Terima kasih atas sarannya! Saya tidak fasih dengan itu elisp, tetapi saya akan mencoba. Saya perlu mencari tahu bagaimana cara menangkap judul masing-masing judul, mengganti ruang putih dengan tanda hubung, dimasukkan ke huruf kecil, menambahkan string yang bersih ke :CUSTOM_ID:dan akhirnya mengatur properti org.
gsl

1
@gsl saya menambahkan defadviceuntuk jawaban saya yang secara otomatis set :EXPORT_FILE_NAME:untuk <custom-id>-<heading>ketika Anda mengatur :CUSTOM_ID:.
itsjeyd

1
Terima kasih banyak, saya telah belajar banyak dengan kode Anda. Jika seseorang sudah memiliki org-modefile dengan CUSTOM_IDset, bagaimana seseorang dapat menjalankan kode untuk mengatur "EXPORT_FILE_NAME"? Tidak akan ada sisipan baru. Saya defadvicekira tidak akan berhasil? Apakah ada fasilitas pengulangan untuk melintasi semua judul tingkat atas dan menerapkan kode tersebut kepada mereka?
gsl
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.