1

I want to use org-mode to compute long passages by concatenating snippets.

I'm open to a non-Babel approach. Tables occurred to me but I couldn't see how to reference a cell from outside the table in a way that imports the cell contents, not just links to it.

With Babel, I have text blocks that I reference via noweb in a final text block. I can't figure out how to make a text block emit something to #+RESULTS:. There's no eval engine. I tried using elisp but newlines trip it up, and I can't M-q format the output otherwise, since the builtin functions are interactive. For text mode, I can tangle to an external file, but not inline.

Any ideas? I must be missing something. I can't imagine this is hard.

[EDIT]:

#+NAME: abc
#+BEGIN_SRC text
  This is a string that is way too long to be on one line.
  The point of this whole question is that blocks with hard paragraph
  breaks don't work with the elisp noweb block.
#+END_SRC

#+NAME: def
#+BEGIN_SRC text
  This is also a string that is way too long to be on one line.
  Again, the point of this whole question is that blocks
  with hard paragraph breaks don't work with the elisp
  noweb block.
#+END_SRC

#+BEGIN_SRC elisp :noweb yes :results output
  (princ "<<abc>>")
  (princ "<<def>>")
#+END_SRC

When evaluating, I receive the message "End of file during parsing." When I tangle to an external file to inspect, what I see is this:

(princ "This is a string that is way too long to be on one line.
(princ "The point of this whole question is that blocks with hard paragraph
(princ "breaks don't work with the elisp noweb block.")
(princ "This is also a string that is way too long to be on one line.
(princ "Again, the point of this whole question is that blocks
(princ "with hard paragraph breaks don't work with the elisp
(princ "noweb block.")

Notice how the non-terminal lines in each text block don't get the double quote or closing parenthesis. This is obviously malformed elisp.

Again, I don't care how this is done. I just want to be able to compute long text passages that either line wrap well or preserve my hard-line-wraps.

It seems like neither org-mode tables nor org-mode babel can do this. I can't find an elisp function that does the equivalent of fill-paragraph on a string, for example, into a list. That would solve this.

3 Answers 3

3

Hopefully I have not misunderstood the question, but, here is an attempt:

I start with this in a org table:

#+BEGIN_SRC emacs-lisp
(setq s1 "hello")
(setq s2 " world")
(setq s3 "!")
(concat s1 s2 s3)
#+END_SRC 

#+RESULTS:
: hello world!

to get the results I placed my cursor within the SRC section and called the function:

M+x org-babel-execute-src-block

which for me is mapped to a keyboard shortcut CTRL+c CTRL+c (the default mapping)

it asks for confirmation to run the command. Or have I misunderstood the requirements? elisp should work with emacs without installing anything (for python, JS you will have to install stuff).

1
  • 1
    Thank you for responding. Not quite. I have separate blocks that are of type text that I pull together with noweb references. The idea is that I can reuse the text blocks in separate passages.
    – jennykwan
    Sep 5, 2018 at 21:26
1

Ah! literate programming. I thought it was a pure org-mode question. This might help:

#+NAME: getString1
#+BEGIN_SRC text
"do your homework"
#+END_SRC

#+NAME: getString2
#+BEGIN_SRC text
"if you want to learn computer science"
#+END_SRC

#+NAME: getString3
#+BEGIN_SRC text
"as well as Prof. D. Knuth"
#+END_SRC

#+NAME: elispProg
#+BEGIN_SRC elisp :noweb yes
(concat <<getString1>> " " <<getString2>> " " <<getString3>>)
#+END_SRC

#+RESULTS: elispProg
: do your homework if you want to learn computer science as well as Prof. D. Knuth

#+NAME: pythonProg
#+BEGIN_SRC python :noweb yes
return "{} {} {}".format(<<getString1>>, <<getString2>>, <<getString3>>)
#+END_SRC

#+RESULTS: pythonProg
: do your homework if you want to learn computer science as well as Prof. D. Knuth

In this example there are three strings (called "text") and two examples of programs that use those strings. You can see the pattern on type description. Some things are "text", "elisp" and python. elisp and python are two different programming languages. If you put your cursor in the section called elispProg or pythonProg and do a CTRL+c CTRL+c (aka org-babel-execute-src-block) you should see results. The flag in the code sections ":now yes" is from the documentation in the emacs editor: "Expansion of Noweb syntax references in the body of the ‘src’ code block when evaluating, tangling, or exporting". Tangling is Prof. Kunth's word for running the code sections. So long story short is that the double "<<" reference other blocks and expand if the flag ":now yes" is present. You can control exactly what happens when evaluation (exec src block) occurs. Here are the docs: https://www.gnu.org/software/emacs/manual/html_node/org/noweb.html

1
  • Thank you. I've edited my original post with more detail.
    – jennykwan
    Sep 7, 2018 at 22:40
1

I see that I misunderstood the problem. Here is another attempt. Its a bit quick/hacky, but, seems to work. Its just copying the long concatenated string into a tmp buffer marking the whole buffer, calling fill-paragraph, putting the result onto the clip ring and then returning the formatted string. So now its just fill-paragraph that consumes a string, formats it and returns the formatted string.

(setq noNewlines "This is a string that is way too long to be on one line. The point of this whole question is that blocks with hard paragraph  breaks don't work with the elisp noweb block.")

(setq newLines "This is also a string that is way too long to be on one line.
  Again, the point of this whole question is that blocks
                          with hard paragraph breaks don't work with the elisp
  noweb block.")

(setq my-paragraph (concat noNewlines newLines))

(defun wrap-string (str)
  "here we are going to wrap a long string so that is a nicely formatted paragraph"
  (interactive)
  (save-excursion
    (let* ((buf-name "*tmp-fill-paragraph*")
           (buffer (get-buffer-create buf-name))
           (result))
      (set-buffer buffer)
      (erase-buffer)
      (insert str)
      (mark-whole-buffer)
      (fill-paragraph)
      (copy-region-as-kill (point-min) (point-max))
      (kill-buffer buf-name)
      (car kill-ring-yank-pointer) )))

(wrap-string my-paragraph)

this is what I see as a result: enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .