DONE tangle entire org-mode file in comments

  • State "DONE" from "PROPOSED" 2010-09-04 Sat 08:47
  • State "PROPOSED" from "" 2010-06-16 Wed 20:37

The :comments header argument has been expanded to support the following options. These should implement at least a first pass at the functionality described below. The new header arguments are…

no
retains its behavior of not tangling any comments
yes
retains its behavior of wrapping the code in links back to the original org-mode file
link
is synonymous with "yes"
org
does not wrap the code in links back to the original org file, but does include preceding text from the org-mode file as a comment before the code block
both
turns on both the "link" and "org" options

examples are given of the effects of these header arguments (notice that the header arguments are contains as properties in the containing headline)

examples

tangling with no comments

This

**** tangling with no comments
   :PROPERTIES:
   :comments: no
   :tangle:   comments.el
   :END:
The top block
#+begin_src emacs-lisp
  (message "first block")
#+end_src

here's some text which won't be tangled

***** subheading
another block
| 1 | first  |
| 2 | second |
#+source: tangle-el-the-second
#+begin_src emacs-lisp
  (message "second")
#+end_src

and finally a block with a =:noweb= header argument
#+begin_src emacs-lisp :noweb yes
  (progn
    <<tangle-el-the-second>>)
#+end_src

results in

(message "first block")

(message "second")

(progn
  (message "second"))

tangling with yes or link comments

This

**** tangling with yes or link comments
   :PROPERTIES:
   :comments: yes
   :tangle:   comments.el
   :END:
The top block
#+begin_src emacs-lisp
  (message "first block")
#+end_src

here's some text which won't be tangled

***** subheading
another block
| 1 | first  |
| 2 | second |
#+source: tangle-el-the-second
#+begin_src emacs-lisp
  (message "second")
#+end_src

and finally a block with a =:noweb= header argument
#+begin_src emacs-lisp :noweb yes
  (progn
    <<tangle-el-the-second>>)
#+end_src

results in

;; [[file:~/src/babel-dev/development.org::*tangling%20with%20yes%20or%20link%20comments][tangling-with-yes-or-link-comments:1]]

(message "first block")

;; tangling-with-yes-or-link-comments:1 ends here

;; [[file:~/src/babel-dev/development.org::*subheading][tangle-el-the-second]]

(message "second")

;; tangle-el-the-second ends here

;; [[file:~/src/babel-dev/development.org::*subheading][subheading:2]]

(progn
  (message "second"))

;; subheading:2 ends here

tangling with org comments

This

**** tangling with org comments
   :PROPERTIES:
   :comments: org
   :tangle:   comments.el
   :END:
The top block
#+begin_src emacs-lisp
  (message "first block")
#+end_src

here's some text which won't be tangled

***** subheading
another block
| 1 | first  |
| 2 | second |
#+source: tangle-el-the-second
#+begin_src emacs-lisp
  (message "second")
#+end_src

and finally a block with a =:noweb= header argument
#+begin_src emacs-lisp :noweb yes
  (progn
    <<tangle-el-the-second>>)
#+end_src

results in

;; tangling with org comments
;;    :PROPERTIES:
;;    :comments: org
;;    :tangle:   comments.el
;;    :END:
;; The top block

(message "first block")

;; ***** subheading
;; another block
;; | 1 | first  |
;; | 2 | second |
;; #+source: tangle-el-the-second

(message "second")

;; and finally a block with a =:noweb= header argument

(progn
  (message "second"))

tangling with both comments

This

**** tangling with both comments
   :PROPERTIES:
   :comments: both
   :tangle:   comments.el
   :END:
The top block
#+begin_src emacs-lisp
  (message "first block")
#+end_src

here's some text which won't be tangled

***** subheading
another block
| 1 | first  |
| 2 | second |
#+source: tangle-el-the-second
#+begin_src emacs-lisp
  (message "second")
#+end_src

and finally a block with a =:noweb= header argument
#+begin_src emacs-lisp :noweb yes
  (progn
    <<tangle-el-the-second>>)
#+end_src

results in

;; tangling with both comments
;;    :PROPERTIES:
;;    :comments: both
;;    :tangle:   comments.el
;;    :END:
;; The top block

;; [[file:~/src/babel-dev/development.org::*tangling%20with%20both%20comments][tangling-with-both-comments:1]]

(message "first block")

;; tangling-with-both-comments:1 ends here

;; ***** subheading
;; another block
;; | 1 | first  |
;; | 2 | second |
;; #+source: tangle-el-the-second

;; [[file:~/src/babel-dev/development.org::*subheading][tangle-el-the-second]]

(message "second")

;; tangle-el-the-second ends here

;; and finally a block with a =:noweb= header argument

;; [[file:~/src/babel-dev/development.org::*subheading][subheading:2]]

(progn
  (message "second"))

;; subheading:2 ends here

preliminary discussion

TD notes that Babel already supports LP, which is designed to make excellent notes.

Belatedly documenting this issue from the mailing list. This issue has resurfaced on the mailing list, see

The main idea being that it would be nice to allow large chunks of an org-mode file to be exported as comments to tangled source code files. That way all the excellent documentation is not lost. The main questions seem to be about the best implementation. The entire thread is available on gmane at gmane.emacs.orgmode/25779.

some excerpts

Erik Iverson

Yes, your idea about prefixing every line in the org file behind a
comment except for the tangled code was the initial idea in my head.
I then thought that there may be several different languages of code
in an org-mode file, and even if there is only one language, the
tangling of that file could be generating multiple source files, for
example, one per function.  In addition, some of the org-mode material
I have in my file might not relate to a commented source file, per se.
For example, the org-mode file where I maintain my source for a
function might have links to emails discussing the implementation, or
internal dialogs relating to alternative approaches that were
abandoned.

So, I thought it might be neat to have some way of specifying which
subtrees would be a part of the comments for a source file, and for
which tangled file.  My guess as the easiest way to do that would be
through properties.  That is, you'd set a property for (sub)tree like,
for example:

:PROPERTIES:
:SrcComment: Yes
:SrcCommentTangleFile: cube.R
:SrcCommentCharacter: ##
:END:

These (sub)trees would then appear as comments in their respective
tangled source files in whatever order they appear in the org-mode
file.

Why am I suggesting this?

People obviously like commented code.  Writing a function in
org-babel, I am in effect using org-mode as the commenting system.
Giving someone who does not use Emacs an org-mode file to see how
something was implemented is not going to fly, to say the least :).
Giving them the tangled version of the code along with, say, an HTML
export of the org-mode buffer is a good start.  But if they're used to
reviewing code in the typical, "just send me the source file" manner,
they would appreciate comments in the code. This is one way they could
be automatically generated from org-mode/org-babel, which is, in my
mind, the ideal.

As I'm sure you have plenty to do, I would be happy to take a look at
this.  I'll give the requisite "I'm just getting started with elisp
..." warning though. :)
Tom Dye

I would pass the function an org-mode link then write out the contents
pointed at by the link inside a named code block, with each line
preceded by an optional comment character.  If this were written in a
general way, then it would be possible to include comments from any
link--on-line manuals, standards, blogs, etc.--in addition to notes in
the org-mode file.

If it were written in a very general way, with a transformation
function responsible for adding the comment character, then a variety
of transformations might be possible.