Làm cách nào để xuất các tiêu đề cấp cao nhất của bộ đệm chế độ org để tách các tệp?


17

Làm thế nào mỗi tiêu đề cấp cao nhất của org-modebộ đệm có thể được xuất sang một tệp riêng được đặt tên theo giá trị của CUSTOM_IDtiêu đề + (được khử trùng) tương ứng ?

Giả sử một bộ đệm chứa:

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

Kết quả cuối cùng sẽ là một thư mục chứa hai tệp, một tệp cho mỗi trong hai tiêu đề cấp cao nhất, với định dạng được chọn tại thời điểm xuất (HTML, LaTeX, v.v.), với tên và nội dung tệp sau:

  1. Tên tệp của tiêu đề xuất đầu tiên: fibrillogenesis-title-of-heading-1.[ext]

    Đã xuất nội dung, tương ứng với tiêu đề cấp cao nhất ban đầu:

    * Title of Heading 1
      :PROPERTIES:
      :CUSTOM_ID: fibrillogenesis
      :END:
      Suspendisse potenti. Mauris ac felis vel velit tristique imperdiet.  
    
    ** Sub-Heading 
       Nullam rutrum.
    
  2. Tên tệp của tiêu đề xuất thứ hai: mitochondrion-another-title-for-heading-2.[ext]

    Nội dung được xuất, tương ứng với tiêu đề cấp cao thứ hai ban đầu:

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

Tôi sẽ rất biết ơn đối với bất kỳ gợi ý, hướng, mã giả, hoặc (tốt hơn) mã thực.

Câu trả lời:


27

Lệnh sau cho phép bạn chọn back-end và sau đó xuất từng cây con cấp cao nhất sang một tệp riêng:

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

Điều này hiện hỗ trợ xuất HTML ( html), LaTeX ( latex) và PDF ( pdf). Bạn có thể thêm hỗ trợ cho nhiều back-end bằng cách thêm nhiều mệnh đề vào cond.

Như docopes nói, đối với mỗi cây con, bạn cần đặt thuộc :EXPORT_FILE_NAME:tính thành tên tệp mà bạn muốn nó được xuất sang. (Xem bên dưới để biết các lựa chọn khác.)

Tự động tạo tên tệp xuất từ ​​văn bản tiêu đề

Nếu bạn không muốn thêm :EXPORT_FILE_NAME:thuộc tính vào mọi tiêu đề cấp cao nhất, bạn có thể sửa đổi org-export-allđể tự động tạo tên tệp từ ví dụ văn bản tiêu đề, tạm thời cài đặt :EXPORT_FILE_NAME:trong khi xuất:

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

Hàm này tạo tên tệp xuất bằng cách thay thế khoảng trắng bằng "_" trong văn bản tiêu đề. Nếu bạn muốn tạo tên tệp theo một cách khác, hãy thay đổi replace-regexp-in-stringsexp thành bất cứ thứ gì bạn thích.

Tạo :EXPORT_FILE_NAME:khi cài đặt:CUSTOM_ID:

Với lời khuyên sau, org-set-propertysẽ tự động đặt giá trị phù hợp :EXPORT_FILE_NAME:khi bạn đặt :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))))

Lưu ý rằng điều này sẽ không thêm phần mở rộng tệp vào giá trị của :EXPORT_FILE_NAME:nhưng điều đó không quan trọng bởi vì khi xuất sang một back-end cụ thể, org-mode sẽ tự động chọn phần mở rộng chính xác cho các tệp kết quả .


Thông tin thêm

Cập nhật số lượng lớn cây con hiện có

Nếu bạn có một số lượng lớn các cây con hiện có mà bạn cần đặt thuộc :EXPORT_FILE_NAME:tính, bạn có thể sử dụng macro bàn phím . Vị trí điểm trên cây con đầu tiên, sau đó làm như sau:

  • F3

    ... để bắt đầu ghi âm.

  • C-c C-x p CUSTOM_ID RET RET

    ... Để đặt Emacs :EXPORT_FILE_NAME:dựa trên :CUSTOM_ID:.

  • C-c C-f

    ... Để chuyển đến tiêu đề cấp cao nhất tiếp theo.

  • F4

    ... Dừng ghi âm.

Để lặp lại macro cho cây con tiếp theo, nhấn F4. Để lặp lại macro cho tất cả các cây con còn lại, nhấn M-0 F4(đó là số không).

Lưu macro cho các phiên trong tương lai

Theo mặc định, macro bàn phím không được lưu trong các phiên. Để lưu trữ macro trong tệp init của bạn để sử dụng sau, hãy làm điều này:

  1. Đặt tên cho macro:

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

  2. Tìm tập tin init của bạn và di chuyển đến một vị trí mà bạn muốn chèn macro.

  3. Chèn macro:

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

    Emacs sẽ chèn đoạn mã sau vào điểm:

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

    Nếu bạn nheo mắt đủ mạnh, bạn có thể thấy rằng đối số thứ hai fsetchứa chuỗi các phím mà bạn đã nhấn khi bạn ghi macro :)

  4. (Tùy chọn) Để có kết quả tốt nhất, bạn có thể muốn liên kết org-set-export-file-namevới khóa:

    (define-key org-mode-map (kbd "<f6>") 'org-set-export-file-name)
  5. Tiết kiệm.


1
Đẹp. Bạn có thể cho tôi một gợi ý về cách đặt thuộc :EXPORT_FILE_NAME:tính lập trình :CUSTOM_ID:+heading-title-lowercasedcho mỗi tiêu đề không?
gsl

1
@gsl Bạn có thể khuyên bạn nên org-set-propertytự động tạo thuộc :EXPORT_FILE_NAME:tính khi bạn đặt :CUSTOM_ID:.
itjeyd

1
Cám ơn bạn đã cho lời khuyên! Tôi không rành về điều đó elisp, nhưng tôi sẽ cố gắng. Tôi cần tìm hiểu cách chụp tiêu đề của từng tiêu đề, thay thế khoảng trắng bằng dấu gạch ngang, đặt thành chữ thường, thêm chuỗi được khử trùng vào :CUSTOM_ID:và cuối cùng đặt thuộc tính org.
gsl

1
@gsl Tôi đã thêm một defadvicecâu trả lời của tôi tự động đặt :EXPORT_FILE_NAME:thành <custom-id>-<heading>khi bạn đặt :CUSTOM_ID:.
itjeyd

1
Cảm ơn bạn rất nhiều, tôi đã học được rất nhiều với mã của bạn. Nếu một người đã có một org-modetập tin với tập hợp CUSTOM_IDs, làm thế nào một người có thể chạy mã để đặt "Billing_FILE_NAME"? Sẽ không có chèn thêm mới. Tôi đoán defadvicesẽ không làm việc? Có một cơ sở lặp để vượt qua tất cả các tiêu đề cấp cao nhất và áp dụng mã cho chúng không?
gsl
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.