Re: [O] Extract source code /with/ captions
Nick Dokos ndokos at gmail.com writes: Try: --8---cut here---start-8--- (defun hjh-print-src-blocks () Iterate src blocks from org-element and print them to *Messages*. (interactive) (let ((tree (org-element-parse-buffer))) (org-element-map tree 'src-block (lambda (element) (message \n\n\nELEMENT:) (print (substring-no-properties (plist-get (car (cdr element)) :caption))) --8---cut here---end---8--- Finally coming back to this. It seems that the actual string-with-properties may be nested at different levels within the :caption object. I tried Nick's version with a different test file, and it failed with a wrong type error. The while below seems to work, though I suppose it could throw an error under some circumstances. Is there an easier way to locate the real stringy-thingy in the middle of the structure, when you can't predict exactly what the structure will be? (defun hjh-print-src-blocks () Iterate src blocks from org-element and print them to *Messages*. (interactive) (let ((tree (org-element-parse-buffer))) (org-element-map tree 'src-block (lambda (element) (setq element (car (cdr element))) (let ((caption (plist-get element :caption))) (while (and caption (not (stringp caption))) (setq caption (car caption))) (message \n\n\nCAPTION:) (print (substring-no-properties caption))) hjh
Re: [O] Extract source code /with/ captions
For posterity, this is doing what I want. It's with some shock that I note, I'm actually starting to understand LISP. hjh (defun hjh-get-string-from-nested-thing (thing) Peel off 'car's from a nested list until the car is a string. (while (and thing (not (stringp thing))) (setq thing (car thing))) thing ) (defun hjh-src-blocks-to-string () Iterate src blocks from org-element and add them to a string. (interactive) (let ((tree (org-element-parse-buffer)) (string ) (counter 0)) (org-element-map tree 'src-block (lambda (element) (setq element (car (cdr element))) (let ((caption (hjh-get-string-from-nested-thing (plist-get element :caption))) (source (hjh-get-string-from-nested-thing (plist-get element :value (when caption (setq counter (1+ counter)) (setq string (concat string (format /* Listing %d. %s */ %s\n\n counter (substring-no-properties caption) (substring-no-properties source string)) (defun hjh-src-blocks-to-buffer () Put all the captioned source blocks from a buffer into another buffer. (interactive) (let* ((contents (hjh-src-blocks-to-string)) (bufpath (buffer-file-name)) (newname (concat (file-name-sans-extension bufpath) .scd)) (bufname (file-name-nondirectory newname)) (newbuf (get-buffer-create bufname))) (with-current-buffer newbuf (erase-buffer) (insert contents) (set-visited-file-name newname)) (switch-to-buffer-other-window newbuf)))
Re: [O] Extract source code /with/ captions
James Harkins jamshar...@gmail.com writes: ELEMENT: (((#(25% coin toss in SuperCollider 0 30 (:parent #2) This is correct, and I also see that I can use (plist-get ... :value) to get the code string. Here, I'm hung up on some (large?) gaps in my elisp knowledge. I have no idea what #(...) signifies, or what functions I can use to get the string out of it. # Is not an especially useful search term in google, bing etc... Can anyone help with my next step? Not sure whether this will help but these are basically just strings with text properties. See (info (elisp) Text Properties in Strings) Also, big thanks to Nicolas for org-element. The fact that an elisp novice can extract captions for source blocks in about half an hour of tinkering is nothing short of criminally easy. Spectacular. Oh, yes indeed! Nick
Re: [O] Extract source code /with/ captions
[I sent a follow-up that has not shown up yet(?) but perhaps this is more useful in any case] James Harkins jamshar...@gmail.com writes: ELEMENT: (((#(25% coin toss in SuperCollider 0 30 (:parent #2) This is correct, and I also see that I can use (plist-get ... :value) to get the code string. Here, I'm hung up on some (large?) gaps in my elisp knowledge. I have no idea what #(...) signifies, or what functions I can use to get the string out of it. # Is not an especially useful search term in google, bing etc... Can anyone help with my next step? Try: --8---cut here---start-8--- (defun hjh-print-src-blocks () Iterate src blocks from org-element and print them to *Messages*. (interactive) (let ((tree (org-element-parse-buffer))) (org-element-map tree 'src-block (lambda (element) (message \n\n\nELEMENT:) (print (substring-no-properties (plist-get (car (cdr element)) :caption))) --8---cut here---end---8--- Nick
Re: [O] Extract source code /with/ captions
Nick Dokos ndo...@gmail.com writes: James Harkins jamshar...@gmail.com writes: ELEMENT: (((#(25% coin toss in SuperCollider 0 30 (:parent #2) This is correct, and I also see that I can use (plist-get ... :value) to get the code string. Here, I'm hung up on some (large?) gaps in my elisp knowledge. I have no idea what #(...) signifies, or what functions I can use to get the string out of it. # Is not an especially useful search term in google, bing etc... Can anyone help with my next step? Not sure whether this will help but these are basically just strings with text properties. See (info (elisp) Text Properties in Strings) I should have added: o You can use substring-no-properties on a string to just get the sequence of characters it consists of without its text properties[fn:1] --8---cut here---start-8--- (setq s #(25% coin toss in SuperCollider 0 30 (face bold))) (substring-no-properties s) == 25% coin toss in SuperCollider --8---cut here---end---8--- o You can similarly use (buffer-substring-no-properties START END) if you want to extract a substring out of a buffer without its text properties. Footnotes: [fn:1] Note that I had to modify the properties a bit to make it into a string that the lisp reader could grok. When you print out the element, you get a shorthand representation of it: #(25% coin toss in SuperCollider 0 30 (:parent #2)) indicating the parent, but #2 is not legal as far as the lisp reader is concerned - it is just a useful shorthand for humans; however when you map your function on what org-element-parse-buffer returns, calling substring-no-properties on it before you print it (or whatever else you want to do to it) will do the right thing (modulo bugs of course). Nick
[O] Extract source code /with/ captions
I'm working on a set of Beamer presentations with a bunch of source code blocks. I would like to collect all the blocks into one text file per presentation, but I also need the captions and ideally a numeric index. That is, I'm *not* looking for the normal behavior of org-babel-tangle, which assembles only the source code itself without any other identifying information (on the assumption that the tangled file should be OK to be compiled). These code blocks are not part of one big program. They are examples that workshop participants should run interactively. So, for instance, where the slideshow and handouts would have a code block identified like so: Listing 3: Compare geometric vs. band-limited waves, aurally. ... a student should be able to open up the corresponding code file and find: // Listing 3: Compare geometric vs. band-limited waves, aurally. Just wondering if anyone has done this. If not, I'm sure I can hack something up but it would save some time if somebody has some code lying around. Thanks in advance -- hjh
Re: [O] Extract source code /with/ captions
I think I have done something like that before. What I did was make it so each code block would be written out to a file, e.g. course-notes/script-%d.py and a link would be put in the exported pdf right after that block. I do not know how you could get the captions though. In the header I have this: #+LATEX_HEADER: \newcommand{\LaunchBinary}[2]{% #+LATEX_HEADER: % #1: layer name, #+LATEX_HEADER: % #2: link text #+LATEX_HEADER: \leavevmode% #+LATEX_HEADER: \pdfstartlink attr{/C [0.9 0 0] /Border [0 0 2]} user { #+LATEX_HEADER: /Subtype /Link #+LATEX_HEADER: /A #+LATEX_HEADER: /F #+LATEX_HEADER: /DOS (#1) #+LATEX_HEADER: /Mac (#1) #+LATEX_HEADER: /Unix (#1) #+LATEX_HEADER: #+LATEX_HEADER: /S /Launch #+LATEX_HEADER: #+LATEX_HEADER: } #2% #+LATEX_HEADER: \pdfendlink% #+LATEX_HEADER: } Then this code for the export. (I pasted it from my build file, so there may be an extra parenthesis at the end) (setq counter 0) (defun ox-mrkup-filter-src-block (text back-end info) (setq counter (+ counter 1)) (let ((filename (format course-notes-scripts/script-%d.py counter))) (with-temp-buffer (insert (mapconcat 'identity (butlast (cdr (split-string text \n t))) \n)) (write-region (point-min) (point-max) filename)) (format %s \\LaunchBinary{%s}{Open the python script (%s).} text filename filename))) (let ((org-export-filter-src-block-functions '(ox-mrkup-filter-src-block))) (org-latex-export-to-latex async subtreep visible-only body-only '(:with-author t :with-date t :with-title t :with-timestamps t :with-todo-keywords t :with-toc nil maybe that is close to what you want? John --- John Kitchin Associate Professor Doherty Hall A207F Department of Chemical Engineering Carnegie Mellon University Pittsburgh, PA 15213 412-268-7803 http://kitchingroup.cheme.cmu.edu On Sun, Jan 12, 2014 at 9:49 AM, James Harkins jamshar...@gmail.com wrote: I'm working on a set of Beamer presentations with a bunch of source code blocks. I would like to collect all the blocks into one text file per presentation, but I also need the captions and ideally a numeric index. That is, I'm *not* looking for the normal behavior of org-babel-tangle, which assembles only the source code itself without any other identifying information (on the assumption that the tangled file should be OK to be compiled). These code blocks are not part of one big program. They are examples that workshop participants should run interactively. So, for instance, where the slideshow and handouts would have a code block identified like so: Listing 3: Compare geometric vs. band-limited waves, aurally. ... a student should be able to open up the corresponding code file and find: // Listing 3: Compare geometric vs. band-limited waves, aurally. Just wondering if anyone has done this. If not, I'm sure I can hack something up but it would save some time if somebody has some code lying around. Thanks in advance -- hjh
Re: [O] Extract source code /with/ captions
James Harkins jamshark70 at gmail.com writes: I'm working on a set of Beamer presentations with a bunch of source code blocks. I would like to collect all the blocks into one text file per presentation, but I also need the captions and ideally a numeric index. [deleted] So, for instance, where the slideshow and handouts would have a code block identified like so: Listing 3: Compare geometric vs. band-limited waves, aurally. ... a student should be able to open up the corresponding code file and find: // Listing 3: Compare geometric vs. band-limited waves, aurally. Can you make the 'caption' into a heading? If so, then ':comments org' will include it in output when you tangle. Or maybe ':comments link' or ':comments both' and some post-processing? HTH, Chuck
Re: [O] Extract source code /with/ captions
On Monday, January 13, 2014 1:19:28 AM HKT, John Kitchin wrote: I think I have done something like that before. What I did was make it so each code block would be written out to a file, e.g. course-notes/script-%d.py and a link would be put in the exported pdf right after that block. I do not know how you could get the captions though. Thanks for the suggestion. I think it might be overkill for my case. One thing is, I don't need links in the LaTeX output -- hence, no need to tie it to LaTeX export. So, after a night's sleep, I remembered something about org-element and took a look at some docstrings. A clever comment about The (almost) almighty `org-element-map' attracted particular attention :) and indeed, it turns out that it does almost all the hard work. Some progress, then: (defun hjh-print-src-blocks () Iterate src blocks from org-element and print them to *Messages*. (interactive) (let ((tree (org-element-parse-buffer))) (org-element-map tree 'src-block (lambda (element) (message \n\n\nELEMENT:) (print (plist-get (car (cdr element)) :caption)) I pulled one frame with two src blocks out of the presentation, put it in a separate file, and running this function from the buffer produces this in the messages buffer (omitting some blank lines, which I had inserted while running this under edebug): ELEMENT: (((#(25% coin toss in SmallTalk 0 26 (:parent #2) ELEMENT: (((#(25% coin toss in SuperCollider 0 30 (:parent #2) This is correct, and I also see that I can use (plist-get ... :value) to get the code string. Here, I'm hung up on some (large?) gaps in my elisp knowledge. I have no idea what #(...) signifies, or what functions I can use to get the string out of it. # Is not an especially useful search term in google, bing etc... Can anyone help with my next step? Also, big thanks to Nicolas for org-element. The fact that an elisp novice can extract captions for source blocks in about half an hour of tinkering is nothing short of criminally easy. Spectacular. hjh