Tệp Tangle Org chứa các lệnh # + INCLUDE và nhiều mục tiêu rối
Bối cảnh
Tôi đang sử dụng org-babel-tangleđể tạo cấu hình của mình từ tệp Tổ chức config.org. Gần đây, tôi đã thực hiện một số công việc dọn dẹp
- gửi
config.orgđến nhiều tệp Tổ chứcconfig/*.org; - thay thế nội dung của
config.orgbằng nhiều#+INCLUDE: config/*.orgchỉ thị.
Để minh họa một chút, cây thư mục như sau:
config/
|______ A.org
|______ B.org
|______ C.org
|
config.org
Ở đâu
## config.org
#+INCLUDE: config/A.org
#+INCLUDE: config/B.org
#+INCLUDE: config/C.org
...
và
## [ABC].org
#+BEGIN_SRC emacs-lisp :tangle target1.el
;; elisp code
#+END_SRC
#+BEGIN_SRC emacs-lisp :tangle target2.el
;; elisp code
#+END_SRC
...
Sự cố và sự cố
Tuy nhiên, tôi đã gặp phải sự cố org-babel-tanglekhông xử lý lệnh #+INCLUDE. Vì vậy, tôi làm theo ý tưởng của bài đăng này bao gồm
- xuất
config.orgsang tệp Orgconfig-export.orgvớiorg-export-to-file; org-babel-tangletệp Tổ chức đã xuất sangconfig-export.orgcác mục tiêu rối.
Cách tiếp cận này thay thế nhiều #+INCLUDEchỉ thị của config.orgnội dung của config/*.org, nhưng tất cả các tùy chọn rối đều bị xóa . Cụ thể, config-export.orgtệp được xuất trông như thế này (tất cả tên tệp mục tiêu rối emacs-lisp đều bị mất):
## config-export.org
#+BEGIN_SRC emacs-lisp
;; elisp code for target1.el
#+END_SRC
#+BEGIN_SRC emacs-lisp
;; elisp code for target2.el
#+END_SRC
...
Câu hỏi
Làm cách nào để org-babel-tangletệp Tổ chức có #+INCLUDEcác lệnh như dự kiến?
( nghĩa là (1) bao gồm tất cả các tệp Tổ chức (bảo toàn :tangle target.el), sau đó (2) org-babel-tangletoàn bộ tệp Tổ chức.)
Câu hỏi liên quan
Một câu hỏi tương tự đã được đưa ra trong danh sách gửi thư của Chế độ tổ chức.
Trả lời
Tôi không biết làm thế nào để thực hiện việc này mà không cần thay đổi mã (có thể có org-babel-pre-tangle-hooknhưng nó có vẻ không đơn giản chút nào, vì vậy tôi đã không thử điều đó). Nhưng ngay sau khi bạn chấp nhận thay đổi mã, nó có vẻ không quá tệ.
Cách đơn giản nhất có thể mà tôi có thể nghĩ ra là mô phỏng org-babel-tanglenhững gì org-export-asđang thực hiện trong các tệp bao gồm WRT. Một thử nghiệm đơn giản (tương tự như những gì bạn mô tả ở trên) đã thành công một cách dễ dàng (nhưng hãy xem cảnh báo ở cuối), vì vậy nếu bạn muốn thử tái tạo thay đổi, tôi bao gồm bản vá bên dưới.
Bản thân bản vá sẽ trông lớn, nhưng đó chỉ là do tôi đang lấy tất cả mã của org-babel-tanglevà bao bọc nó trong một lớp khác, lớp này sẽ thay đổi thụt lề và đó là phần lớn sự thay đổi. Bỏ qua các thay đổi về khoảng trắng, thay đổi "thực" nhỏ hơn nhiều: Tôi đã nhận bản vá bên dưới với git diff -bđể bỏ qua khoảng trắng. Sau đó bạn có thể thấy rằng nó là rất nhỏ: chúng ta chỉ cần gửi kèm theo gần như toàn bộ cơ thể của org-babel-tangletrong (org-export-with-buffer-copy ...), để chúng ta có thể làm biến đổi cho văn bản trong một bộ đệm tạm thời và không làm phiền bản gốc và sau đó thêm một chuyển đổi hơn để xử lý các #+INCLUDE:chỉ thị, trước khi bộ đệm kết quả sau đó bị rối:
diff --git a/lisp/ob-tangle.el b/lisp/ob-tangle.el
index b74b3fa0c..5e6eebf63 100644
--- a/lisp/ob-tangle.el
+++ b/lisp/ob-tangle.el
@@ -206,6 +206,9 @@ export file for all source blocks. Optional argument LANG-RE can
be used to limit the exported source code blocks by languages
matching a regular expression."
(interactive "P")
+ (org-export-with-buffer-copy
+ (org-export-expand-include-keyword)
+
(run-hooks 'org-babel-pre-tangle-hook)
;; Possibly Restrict the buffer to the current code block
(save-restriction
@@ -306,7 +309,7 @@ matching a regular expression."
(mapc (lambda (pair)
(when (cdr pair) (set-file-modes (car pair) (cdr pair))))
path-collector)
- (mapcar #'car path-collector)))))
+ (mapcar #'car path-collector))))))
(defun org-babel-tangle-clean ()
"Remove comments inserted by `org-babel-tangle'.
Điều đó tạo ra kết quả mong đợi WRT các tệp rối mà tôi nghĩ, nhưng bạn nên kiểm tra để đảm bảo rằng nó hoạt động đúng trong trường hợp của bạn: các bài kiểm tra của tôi là bài kiểm tra đồ chơi nên chúng có thể bỏ lỡ các tình huống khó khăn có thể phát sinh trong các bài kiểm tra "thế giới thực" của bạn .
Có một vấn đề mà tôi chưa hiểu: config.orgbản thân bộ đệm đã bị thay đổi trong các thử nghiệm của tôi, mặc dù org-export-with-copy-buffervậy, khi kết thúc sự cố, tôi phải hoàn tác thay đổi với C-x uvà lưu nó. Đó có thể là do tôi không hiểu org-export-with-copy-bufferthực sự đang làm gì, nhưng tôi vẫn chưa kiểm tra mã đó.
OTOH, nếu điều đó được giải quyết và tất cả các bài kiểm tra đều vượt qua, chúng tôi có thể đề xuất điều này như một cải tiến cho danh sách gửi thư của Chế độ tổ chức và đặt vấn đề đó (từ năm 2010!) Sau lưng chúng tôi.
CHỈNH SỬA: Tôi không thấy có vấn đề gì với org-babel-tangle-file- nó gọi org-babel-tanglebên dưới, vì vậy về lý thuyết, nó sẽ làm đúng (gần như) và thử nghiệm nó bằng một ví dụ đơn giản phù hợp với tôi. Có thể bạn có thể đăng một ví dụ (nhỏ) cho bạn vấn đề bằng cách chỉnh sửa câu hỏi của bạn?
Tôi cũng đang thử nghiệm với giải pháp sau để khắc phục sự cố config.orgthay đổi:
#+begin_src emacs-lisp
(copy-file "./config.org.orig" "./config.org")
(org-babel-tangle-file "./config.org")
(delete-file "./config.org")
#+end_src
Xấu xí, nhưng nó có vẻ hoạt động (ngoại trừ việc tôi phải trả lời câu hỏi "đã thay đổi trên đĩa").
Phương pháp 1
Phương pháp thủ công sử dụng liên kết khóa ở chế độ tổ chức mặc định
Thiết lập
Thêm
OrgvàoOrg Babel Load Languagescấu hình, sau đó áp dụng và lưu cấu hình mới.Thêm
#+EXPORT_FILE_NAME:từ khóa gần đầuconfig.org.ví dụ
#+EXPORT_FILE_NAME: temp.orgThêm
#+PROPERTY: header-args:org :results drawer replacetừ khóa gần đầuconfig.org.ví dụ
#+PROPERTY: header-args:org :results drawer replaceCập nhật
#+INCLUDE:để bao gồmsrc orgcú pháp.ví dụ
#+INCLUDE: config/A.org src org #+INCLUDE: config/B.org src org #+INCLUDE: config/C.org src orgThêm
:eval nevertiêu đề vào từngSRCkhối sẽ được gắn vào bên trong cácconfig/*.orgtệp được bao gồm .ví dụ
#+BEGIN_SRC elisp :tangle tangle1.el :eval never ;; Code goes here #+END_SRC
Các bước thực hiện thủ công
Mở
config.orgtrong emacs.Các
config.orgtập tin sẽ trông giống như ví dụ dưới đây:#+EXPORT_FILE_NAME: temp.org #+PROPERTY: header-args:org :results drawer replace #+INCLUDE: config/A.org src org #+INCLUDE: config/B.org src org #+INCLUDE: config/C.org src orgXuất
config.orgbằng cách sử dụngC-cC-eOvhợp âm chính. Thao tác này sẽ tạo mộttemp.orgtệp mới và mở trong emacs.Các
temp.orgtập tin sẽ trông giống như ví dụ dưới đây:#+export_file_name: temp.org #+property: header-args:org :results drawer replace #+begin_src org ,#+BEGIN_SRC elisp :tangle tangle1.el :eval never ;; Code goes here ,#+END_SRC #+end_src #+begin_src org ,#+BEGIN_SRC elisp :tangle tangle2.el :eval never ;; Code goes here ,#+END_SRC #+end_src #+begin_src org ,#+BEGIN_SRC elisp :tangle tangle3.el :eval never ;; Code goes here ,#+END_SRC #+end_srcThực hiện tất cả các khối trong hợp âm phím
temp.orgbằng cách sử dụngC-cC-vC-b.Các
temp.orgtập tin sẽ trông giống như ví dụ dưới đây:#+export_file_name: temp.org #+property: header-args:org :results drawer replace #+begin_src org ,#+BEGIN_SRC elisp :tangle tangle1.el :eval never ;; Code goes here ,#+END_SRC #+end_src #+RESULTS: :results: #+BEGIN_SRC elisp :tangle tangle1.el :eval never ;; Code goes here #+END_SRC :end: #+begin_src org ,#+BEGIN_SRC elisp :tangle tangle2.el :eval never ;; Code goes here ,#+END_SRC #+end_src #+RESULTS: :results: #+BEGIN_SRC elisp :tangle tangle2.el :eval never ;; Code goes here #+END_SRC :end: #+begin_src org ,#+BEGIN_SRC elisp :tangle tangle3.el :eval never ;; Code goes here ,#+END_SRC #+end_src #+RESULTS: :results: #+BEGIN_SRC elisp :tangle tangle3.el :eval never ;; Code goes here #+END_SRC :end:Thực hiện rối trong hợp âm phím
temp.orgbằng cách sử dụngC-cC-vC-t. Điều này sẽ làm rối cácSRCkhối đã nhập từ cácconfig/*.orgtệp.Điều này sẽ tạo ra các tệp rối tương tự như các tệp được liệt kê bên dưới:
config.org tangle1.el tangle2.el tangle3.el temp.org ./config: A.org B.org C.org
Câu trả lời này đã được kiểm tra bằng cách sử dụng:
phiên bản emacs: GNU Emacs 27.1
phiên bản chế độ tổ chức: 9.3.7