Re: [O] Tangling org file with nested org source block
Following-up on the issue I reported some time ago with tangling of nested source blocks, I would like to propose a patch for review. Before the patch, the following file: , | #+PROPERTY: header-args :tangle output.org | | #+BEGIN_SRC org | | ,* Test | | ,#+BEGIN_SRC org | ,,#+BEGIN_SRC emacs-lisp | '(1 2 3) | ,,#+END_SRC | ,#+END_SRC | | #+END_SRC ` is tangled to: , output.org | * Test | | #+BEGIN_SRC org | #+BEGIN_SRC emacs-lisp | '(1 2 3) | #+END_SRC | #+END_SRC ` which misses the escaping (commas) for the inner source block. Tangling after applying the proposed patch results in: , output.org | * Test | | #+BEGIN_SRC org | ,#+BEGIN_SRC emacs-lisp | '(1 2 3) | ,#+END_SRC | #+END_SRC ` which is properly escaped. The patch also contains a simple test to validate tangling of nested blocks. Could this be considered for a merge? Thanks in advance thibault >From 6300856f8b9623b1ac0a40b7fe62751805159558 Mon Sep 17 00:00:00 2001 From: thibault Date: Fri, 20 Oct 2017 22:20:35 -0500 Subject: [PATCH] ob-tangle.el: Fix tangling of org block with nested source block * lisp/ob-tangle.el (org-babel-tangle-single-block): Prevent double unescaping of source block by removing unnecessary call to `org-unescape-code-in-string'. * testing/lisp/test-ob-tangle.el (ob-tangle/nested-block) New function. Test tangle of org block with nested source block. --- lisp/ob-tangle.el | 7 +++ testing/lisp/test-ob-tangle.el | 25 + 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/lisp/ob-tangle.el b/lisp/ob-tangle.el index adc680676..09d011fc3 100644 --- a/lisp/ob-tangle.el +++ b/lisp/ob-tangle.el @@ -494,10 +494,9 @@ non-nil, return the full association list to be used by link) source-name params - (org-unescape-code-in-string - (if org-src-preserve-indentation - (org-trim body t) - (org-trim (org-remove-indentation body + (if org-src-preserve-indentation + (org-trim body t) + (org-trim (org-remove-indentation body))) comment))) (if only-this-block (list (cons src-lang (list result))) diff --git a/testing/lisp/test-ob-tangle.el b/testing/lisp/test-ob-tangle.el index 06a73f063..73b75323e 100644 --- a/testing/lisp/test-ob-tangle.el +++ b/testing/lisp/test-ob-tangle.el @@ -197,6 +197,31 @@ another block (org-babel-tangle-jump-to-org) (buffer-string))) +(ert-deftest ob-tangle/nested-block () + "Test tangling of org file with nested block." + (should + (string= +"#+begin_src org +,#+begin_src emacs-lisp +1 +,#+end_src +#+end_src +" +(org-test-with-temp-text-in-file +"#+header: :tangle \"test-ob-tangle.org\" +#+begin_src org +,#+begin_src org +,,#+begin_src emacs-lisp +1 +,,#+end_src +,#+end_src +#+end_src" + (unwind-protect + (progn (org-babel-tangle) + (with-temp-buffer (insert-file-contents "test-ob-tangle.org") + (buffer-string))) +(delete-file "test-ob-tangle.org")) + (provide 'test-ob-tangle) ;;; test-ob-tangle.el ends here -- 2.14.1
Re: [O] function for inserting a block
On Fri, Oct 20, 2017 at 5:15 PM Eric Abrahamsen wrote: > The template really only inserts the block type, not anything specific > like the source language or export backend. Right, but based on the code you have, you can easily add "SRC org", "SRC emacs-lisp" to the default value of that list. Looking at that, users can also get an idea that they can add their favorite languages to that list too. > I think prompting for > "second-level" information like that might be a little overkill. > I second that. The first-level prompt also feels a bit slow, honestly, compared to using easy templates like "https://i.imgur.com/201TISW.gifv I use hydra to provide those awesome hints.. but the same can be done without hydras too. As for what should be escaped and what shouldn't, I defer to Nicolas, > let's see what he says. > -- Kaushal Modi
Re: [O] function for inserting a block
Kaushal Modi writes: > Also, if the type is "src", shouldn't the point end up after "#+BEGIN_SRC"? > Because the user will anyways need to type something there. My original version did that. It might be nice to still do that selectively if the user adds a SRC or EXPORT block. > Finally, I am trying to understand what this does: > > (if (bolp) > (progn > (skip-chars-backward " \n\t") > (forward-line)) > ;; snip > ) > > If the point is at BOL, wouldn't that progn bring the point exactly to where > it was, as the same BOL? Also isn't that progn equivalent to (forward-line 0)? > > I am probably missing something.. but seems to work the same with > > (unless (bolp) > (end-of-line) > (insert "\n")) > > replacing that whole (if ..) form. The case this is addressing is if there are multiple newlines after the org element we're wrapping (one of the clauses in the test shows this). The skip-chars-backward is there to go back over multiple newlines, so that the #+END_FOO string always comes right after the end of the text. Eric
Re: [O] function for inserting a block
Kaushal Modi writes: > On Fri, Oct 20, 2017 at 2:07 PM Eric Abrahamsen > wrote: > > Okay, here's another version, with a new keybinding and completion. The > completion strings are uppercase, which might not always be the right > thing, but probably more often than not. > > Hi Eric, > > I just tried it out, and it works great! > > I have a comment about > > (when (string-equal (downcase type) "example") > (org-escape-code-in-region s e)) > > I have never needed to escape org in example, blocks, but I *have* needed to > do that in org src blocks. > > Should type string be also matched with "src org"? > > Actually should the type string be matched only with "src org"? Because I see > the Org example blocks as blocks in HTML with no syntax > highlighting.. so > those can contain code from any language. > > Also as this is part of org and emacs, org-structure-predefined-blocks > deserves "SRC org" and "SRC emacs-lisp" too? :) The template really only inserts the block type, not anything specific like the source language or export backend. I think prompting for "second-level" information like that might be a little overkill. As for what should be escaped and what shouldn't, I defer to Nicolas, let's see what he says. Eric
Re: [O] function for inserting a block
Also, if the type is "src", shouldn't the point end up after "#+BEGIN_SRC"? Because the user will anyways need to type something there. Finally, I am trying to understand what this does: (if (bolp) (progn (skip-chars-backward " \n\t") (forward-line)) ;; snip ) If the point is at BOL, wouldn't that progn bring the point exactly to where it was, as the same BOL? Also isn't that progn equivalent to (forward-line 0)? I am probably missing something.. but seems to work the same with (unless (bolp) (end-of-line) (insert "\n")) replacing that whole (if ..) form. -- Kaushal Modi
Re: [O] function for inserting a block
On Fri, Oct 20, 2017 at 2:07 PM Eric Abrahamsen wrote: > Okay, here's another version, with a new keybinding and completion. The > completion strings are uppercase, which might not always be the right > thing, but probably more often than not. > Hi Eric, I just tried it out, and it works great! I have a comment about (when (string-equal (downcase type) "example") (org-escape-code-in-region s e)) I have never needed to escape org in example, blocks, but I *have* needed to do that in org src blocks. Should type string be also matched with "src org"? Actually should the type string be matched only with "src org"? Because I see the Org example blocks as blocks in HTML with no syntax highlighting.. so those can contain code from any language. Also as this is part of org and emacs, org-structure-predefined-blocks deserves "SRC org" and "SRC emacs-lisp" too? :) -- Kaushal Modi
Re: [O] function for inserting a block
Carsten Dominik writes: > Hi Eric, > > On Wed, Oct 18, 2017 at 4:58 PM, Eric Abrahamsen > wrote: > > Carsten Dominik writes: > > > Dear all, > > > > this is great added functionality that I have missed a lot myself. Thanks > for this! Also, I like the key binding. > > I do too, though I also notice it conflicts with inlinetask insertion. > > Ooops. I overlooked that. Hmmm, that is not ideal. > > Maybe then C-c C-x w would be better, w can stand for "wrap". > > > > One improvement I can think of it to read the block type with completion > (but still allow any word to be used). > > I'd be happy to do that. There would be a tiny bit of redundancy with > `org-structure-template-alist', but nothing too terrible. > > I agree. You could pull it would of the alist, but I am not sure it is worth > it. Okay, here's another version, with a new keybinding and completion. The completion strings are uppercase, which might not always be the right thing, but probably more often than not. Eric >From cb6f1815259094f7f9b68459dcded5dce14d3154 Mon Sep 17 00:00:00 2001 From: Eric Abrahamsen Date: Sat, 7 Oct 2017 13:01:14 -0700 Subject: [PATCH] New function org-insert-structure-template * lisp/org.el (org-insert-structure-template): New function for wrapping region (or element at point) in a begin/end block. (org-structure-predefined-blocks): New option holding predefined blocks, for completion. * doc/org.texi (Structure of code blocks, Easy templates): And in manual. * testing/lisp/test-org.el (test-org/insert-template): New test. --- doc/org.texi | 21 +++-- etc/ORG-NEWS | 4 lisp/org.el | 47 +++ testing/lisp/test-org.el | 42 ++ 4 files changed, 108 insertions(+), 6 deletions(-) diff --git a/doc/org.texi b/doc/org.texi index c54f2615a..6ad9d1c15 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -15242,12 +15242,13 @@ A @samp{src} block conforms to this structure: #+END_SRC @end example -Org mode's templates system (@pxref{Easy templates}) speeds up creating -@samp{src} code blocks with just three keystrokes. Do not be put-off by -having to remember the source block syntax. Org also works with other -completion systems in Emacs, some of which predate Org and have custom -domain-specific languages for defining templates. Regular use of templates -reduces errors, increases accuracy, and maintains consistency. +Do not be put off by having to remember the source block syntax. Org mode +offers two ways of speeding up the creation of src code blocks: a template +system that can create a new block with just three keystrokes, and a command +for wrapping existing text in a block (@pxref{Easy templates}). Org also +works with other completion systems in Emacs, some of which predate Org and +have custom domain-specific languages for defining templates. Regular use of +templates reduces errors, increases accuracy, and maintains consistency. @cindex source code, inline An inline code block conforms to this structure: @@ -17418,6 +17419,14 @@ Org comes with these pre-defined easy templates: More templates can added by customizing the variable @code{org-structure-template-alist}, whose docstring has additional details. +@findex org-insert-structure-template +@kindex C-c C-x w +Easy templates are ideal when writing new content, but sometimes it is +necessary to mark up existing content. For these cases, Org provides the +function @code{org-insert-structure-template}, which prompts for a block +type, and wraps either the active region or the current Org element in that +block. This command is bound to @kbd{C-c C-x w} by default. + @node Speed keys @section Speed keys @cindex speed keys diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 1076dd970..190a6b8bc 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -109,6 +109,10 @@ you should expect to see something like: #+END_EXAMPLE ** New functions +*** ~org-insert-structure-template~ + +This function can be used to wrap existing text of Org elements in +a #+BEGIN_FOO/#+END_FOO block. Bound to C-c C-x w by default. *** ~org-export-excluded-from-toc-p~ diff --git a/lisp/org.el b/lisp/org.el index 54687abc7..e1cf14cae 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -12117,6 +12117,13 @@ keywords relative to each registered export back-end." "PRIORITIES:" "SELECT_TAGS:" "SEQ_TODO:" "SETUPFILE:" "STARTUP:" "TAGS:" "TITLE:" "TODO:" "TYP_TODO:" "SELECT_TAGS:" "EXCLUDE_TAGS:")) +(defcustom org-structure-predefined-blocks + '("SRC" "EXAMPLE" "QUOTE" "VERSE" "VERBATIM" "CENTER" "COMMENT" "EXPORT") + "Block structure completion names." + :group 'org-completion + :type '(repeat string) + :package-version '(Org . "9.1.3")) + (defcustom org-structure-template-alist '(("s" "#+BEGIN_SRC ?\n\n#+END_SRC") ("e" "#+BEGIN_EXAMPLE\n?\n#+END_EXAMPLE") @@ -12189,6 +12196,45 @@ expands them."
Re: [O] OT: TUI applications
On 2017-10-18, at 18:47, Russell Adams wrote: > On Wed, Oct 18, 2017 at 10:55:26AM -0500, Grant Rettke wrote: >> On Wed, Oct 18, 2017 at 8:23 AM, Russell Adams >> >> https://www.gnu.org/software/emacs/manual/html_mono/widget.html > > That's cool! I didn't realize that Emacs had some of that built in. I'll read > up on that too! One problem with widget is that (AFAIR) it is fairly low-level. Still, you can do cool stuff with it. See e.g. http://mbork.pl/2015-11-21_The_Emacs_widget_library_and_automatic_modification_of_editing_fields Hth, -- Marcin Borkowski
Re: [O] workflow, matlab+latex in org file
> Here I obtain the following error: > Debugger entered--Lisp error: (void-function org-babel-execute:matlab) > org-babel-execute:matlab("x = [1, 2, 3, 4, 5];\nfprintf('|%d', x)" > ((:colname-names) (:rowname-names) (:result-params "replace" "output" > "drawer") (:result-type . output) (:results . "replace output drawer") > (:exports . "code") (:session . "matlab") (:kernel . "matlab") (:cache > . "no") (:noweb . "no") (:hlines . "no") (:tangle . "no"))) > org-babel-execute-src-block(nil ("matlab" "x = [1, 2, 3, 4, > 5];\nfprintf('|%d', x)" ((:colname-names) (:rowname-names) > (:result-params "drawer" "output" "replace") (:result-type . output) > (:results . "drawer output replace") (:exports . "code") (:tangle . > "no") (:hlines . "no") (:noweb . "no") (:cache . "no") (:kernel . > "matlab") (:session . "matlab")) "" nil 671 "(ref:%s)")) > org-ctrl-c-ctrl-c(nil) funcall-interactively(org-ctrl-c-ctrl-c nil) > call-interactively(org-ctrl-c-ctrl-c nil nil) > command-execute(org-ctrl-c-ctrl-c) Ok, I did not had ob-ipython installed. Now I did but obtain a different error Debugger entered--Lisp error: (error "There was a fatal error trying to process the request. See *ob-ipython-debug*") signal(error ("There was a fatal error trying to process the request. See *ob-ipython-debug*")) error("There was a fatal error trying to process the request. See *ob-ipython-debug*") ob-ipython--dump-error("Traceback (most recent call last):\n File \"/home/oub/.emacs.d/elpa/ob-ipython-20171008.1733/client.py\", line 60, in \n c = create_client(args.conn_file)\n File \"/home/oub/.emacs.d/elpa/ob-ipython-20171008.1733/client.py\", line 43, in create_client\n cf = find_connection_file('emacs-' + name)\n File \"/usr/local/lib/python2.7/dist-packages/jupyter_client/connect.py\", line 212, in find_connection_file\n raise IOError(\"Could not find %r in %r\" % (filename, path))\nIOError: Could not find 'emacs-matlab' in ['.', '/run/user/1000/jupyter']\n") ob-ipython--execute-request("x = [1, 2, 3, 4, 5];\nfprintf('|%d', x)" "matlab") ob-ipython--execute-sync("x = [1, 2, 3, 4, 5];\nfprintf('|%d', x)" ((:colname-names) (:rowname-names) (:result-params "replace" "output" "drawer") (:result-type . output) (:results . "replace output drawer") (:exports . "code") (:session . "matlab") (:kernel . "matlab") (:cache . "no") (:noweb . "no") (:hlines . "no") (:tangle . "no"))) org-babel-execute:matlab("x = [1, 2, 3, 4, 5];\nfprintf('|%d', x)" ((:colname-names) (:rowname-names) (:result-params "replace" "output" "drawer") (:result-type . output) (:results . "replace output drawer") (:exports . "code") (:session . "matlab") (:kernel . "matlab") (:cache . "no") (:noweb . "no") (:hlines . "no") (:tangle . "no"))) org-babel-execute-src-block(nil ("matlab" "x = [1, 2, 3, 4, 5];\nfprintf('|%d', x)" ((:colname-names) (:rowname-names) (:result-params "drawer" "output" "replace") (:result-type . output) (:results . "drawer output replace") (:exports . "code") (:tangle . "no") (:hlines . "no") (:noweb . "no") (:cache . "no") (:kernel . "matlab") (:session . "matlab")) "" nil 671 "(ref:%s)")) org-ctrl-c-ctrl-c(nil) funcall-interactively(org-ctrl-c-ctrl-c nil) call-interactively(org-ctrl-c-ctrl-c nil nil) command-execute(org-ctrl-c-ctrl-c)
Re: [O] workflow, matlab+latex in org file
>>> "John" == John Kitchin writes: This message is from July, but meanwhile I upgraded to Ubuntu 16.04 matlab 2016b which includes the python engine/kernel and finally I installed the Jupiter matlab kernel via pip, however I tried to follow your recommendations below: > You might dig around in ob-octave to see how it works. It should be able > to Matlab (and on Linux/Mac I believe it might). On Windows, it has been > broken for a long time due to the lack of a proper shell (maybe that can > be adapted in win10 though). > I vaguely recall making that matlab function to try it out on Windows > some years ago. > There is a Jupyter Matlab kernel now. > https://github.com/Calyro/matlab_kernel > I was able to use this (and installing the kernel, and making sure a > matlab is on the path): > #+BEGIN_SRC emacs-lisp > (add-to-list 'org-src-lang-modes '("matlab" . matlab)) > ;; set default headers for convenience > (setq org-babel-default-header-args:matlab > '((:results . "output replace") >(:session . "matlab") >(:kernel . "matlab") >(:exports . "code") >(:cache . "no") >(:noweb . "no") >(:hlines . "no") >(:tangle . "no"))) > (defalias 'org-babel-execute:matlab 'org-babel-execute:ipython) > (defalias 'org-babel-prep-session:matlab 'org-babel-prep-session:ipython) > (defalias 'org-babel-matlab-initiate-session 'org-babel-ipython-initiate-session) > #+END_SRC > #+RESULTS: > : org-babel-matlab-initiate-session That I obtain > To enable this: > #+BEGIN_SRC matlab :results output org drawer > x = [1, 2, 3, 4, 5]; > fprintf('|%d', x) > #+END_SRC Here I obtain the following error: Debugger entered--Lisp error: (void-function org-babel-execute:matlab) org-babel-execute:matlab("x = [1, 2, 3, 4, 5];\nfprintf('|%d', x)" ((:colname-names) (:rowname-names) (:result-params "replace" "output" "drawer") (:result-type . output) (:results . "replace output drawer") (:exports . "code") (:session . "matlab") (:kernel . "matlab") (:cache . "no") (:noweb . "no") (:hlines . "no") (:tangle . "no"))) org-babel-execute-src-block(nil ("matlab" "x = [1, 2, 3, 4, 5];\nfprintf('|%d', x)" ((:colname-names) (:rowname-names) (:result-params "drawer" "output" "replace") (:result-type . output) (:results . "drawer output replace") (:exports . "code") (:tangle . "no") (:hlines . "no") (:noweb . "no") (:cache . "no") (:kernel . "matlab") (:session . "matlab")) "" nil 671 "(ref:%s)")) org-ctrl-c-ctrl-c(nil) funcall-interactively(org-ctrl-c-ctrl-c nil) call-interactively(org-ctrl-c-ctrl-c nil nil) command-execute(org-ctrl-c-ctrl-c) What is the problem? Which package do I miss, ipython is installed in /usr/local/bin Thanks Uwe Brauer