* [TIP] Exporting Maxima results to LaTeX @ 2023-02-07 21:40 Leo Butler 2023-02-07 22:13 ` Thomas S. Dye 2023-02-08 15:43 ` Max Nikulin 0 siblings, 2 replies; 7+ messages in thread From: Leo Butler @ 2023-02-07 21:40 UTC (permalink / raw) To: Org Mode Mailing List [-- Attachment #1: Type: text/plain, Size: 118 bytes --] Attached is a self-documented setup to do what the subject line says. Comments/suggestions welcome. Best, Leo [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: tip.org --] [-- Type: text/x-org; name="maxima-tip.org", Size: 3910 bytes --] #+TITLE: Tip for exporting Maxima results to LaTeX #+AUTHOR: Leo Butler #+OPTIONS: H:2 toc:nil num:nil tags:nil todo:nil #+LATEX_CLASS: article #+LATEX_HEADER: \usepackage{color} #+LATEX_COMPILER: lualatex #+STARTUP: beamer #+PROPERTY: header-args:maxima :eval never-export :exports results :results raw drawer * Goal Generate @@latex:\LaTeX{}@@ code from Maxima code. * Setup ** maxima-init.lisp The command =org-babel-execute:maxima= in =lisp/ob-maxima.el= uses the Maxima command ~batchload~ to execute Maxima code. This is a very tight-lipped loader, so we over-write ~batchload~ with ~batch~. We also ~load~ an init file: #+begin_example ,#+begin_src maxima :tangle maxima-init.lisp :exports none (defun $batchload (file) (mfuncall '$batch file)) ($load "./maxima-init.mac") ,#+end_src #+end_example On tangling, this produces the ~common-lisp~ output file ~maxima-init.lisp~. It will be pre-loaded into Maxima. #+begin_src maxima :tangle maxima-init.lisp :exports none (defun $batchload (file) (mfuncall '$batch file)) ($load "./maxima-init.mac") #+end_src ** maxima-init.mac Next, we need to create an init file for Maxima that will provide an output printer that produces @@latex:\LaTeX{}@@ output. One option would be to use the ~imaxima~ printer. Here is another option that uses the ~alt-display~ package. The code replaces the default printer with ~org_tex_display~. It also sets the ~epilog~ prompt, so that the final ~#+begin_example~ is terminated. #+begin_example ,#+begin_src maxima :tangle maxima-init.mac :exports none load("alt-display.mac") $ set_prompt('epilog,printf(false,"~%#+end_example")) $ define_alt_display(org_tex_display(x), block([], printf(true,"#+end_example~%#+begin_export latex~%"), printf(true,"\\textcolor{blue}{(\\~a~d)} ",outchar,linenum-1), tex(second(x)), printf(true,"~&#+end_export~%#+begin_example~%(input) "))) $ set_alt_display(2,org_tex_display) $ display2d:true $ printf(true,"#+begin_example~%(input) ") $ linenum : 0 $ ,#+end_src #+end_example #+begin_src maxima :tangle maxima-init.mac :exports none load("alt-display.mac") $ set_prompt('epilog,printf(false,"~%#+end_example")) $ define_alt_display(org_tex_display(x), block([], printf(true,"#+end_example~%#+begin_export latex~%"), printf(true,"\\textcolor{blue}{(\\~a~d)} ",outchar,linenum-1), tex(second(x)), printf(true,"~&#+end_export~%#+begin_example~%(input) "))) $ set_alt_display(2,org_tex_display) $ display2d:true $ printf(true,"#+begin_example~%(input) ") $ linenum : 0 $ #+end_src * An example Here is an example that computes the derivative of a composite function. #+name: chain-rule #+begin_src maxima :exports results :results raw drawer :cmdline -p ./maxima-init.lisp (gradef(f(u,v),f_1(u,v),f_2(u,v)), 'done); diff(f(x^2-y^2,x*y),x); diff(f(x^2-y^2,x*y),y); #+end_src #+RESULTS: chain-rule :results: #+begin_example (input) read and interpret /tmp/babel-hhTrJS/maxima-0m0DnH.max (gradef(f(u,v),f_1(u,v),f_2(u,v)),'done) #+end_example #+begin_export latex \textcolor{blue}{(\%o1)} $$\mathbf{done}$$ #+end_export #+begin_example (input) diff(f(x^2-y^2,x*y),x) #+end_example #+begin_export latex \textcolor{blue}{(\%o2)} $$y\,f_{2}\left(x^2-y^2 , x\,y\right)+2\,x\,f_{1}\left(x^2-y^2 , x\,y \right)$$ #+end_export #+begin_example (input) diff(f(x^2-y^2,x*y),y) #+end_example #+begin_export latex \textcolor{blue}{(\%o3)} $$x\,f_{2}\left(x^2-y^2 , x\,y\right)-2\,y\,f_{1}\left(x^2-y^2 , x\,y \right)$$ #+end_export #+begin_example (input) gnuplot_close() #+end_example :end: ** Two annoyances The initial line =read and interpret...= and that final, dangling input line with ~gnuplot_close()~ are nuisances. They can be easily suppressed, but that requires patching ~ob-maxima.el~. That's another story. [-- Attachment #3: maxima-tip.pdf --] [-- Type: application/pdf, Size: 34392 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [TIP] Exporting Maxima results to LaTeX 2023-02-07 21:40 [TIP] Exporting Maxima results to LaTeX Leo Butler @ 2023-02-07 22:13 ` Thomas S. Dye 2023-02-08 15:43 ` Max Nikulin 1 sibling, 0 replies; 7+ messages in thread From: Thomas S. Dye @ 2023-02-07 22:13 UTC (permalink / raw) To: Leo Butler; +Cc: emacs-orgmode Aloha Leo, Leo Butler <Leo.Butler@umanitoba.ca> writes: > Attached is a self-documented setup to do what the subject line > says. > Comments/suggestions welcome. > > Best, > Leo > Please consider adding this to https://orgmode.org/worg/org-contrib/babel/languages/ob-doc-maxima.org, which also has some notes on how to export Maxima to LaTeX. All the best, Tom -- Thomas S. Dye https://tsdye.online/tsdye ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [TIP] Exporting Maxima results to LaTeX 2023-02-07 21:40 [TIP] Exporting Maxima results to LaTeX Leo Butler 2023-02-07 22:13 ` Thomas S. Dye @ 2023-02-08 15:43 ` Max Nikulin 2023-02-08 16:11 ` Fraga, Eric 2023-02-08 20:40 ` Leo Butler 1 sibling, 2 replies; 7+ messages in thread From: Max Nikulin @ 2023-02-08 15:43 UTC (permalink / raw) To: emacs-orgmode On 08/02/2023 04:40, Leo Butler wrote: > Generate @@latex:\LaTeX{}@@ code from Maxima code. You can write just LaTeX, ox-latex recognizes such pattern. The bonus is the it will be literally exported to HTML. > #+begin_example > ,#+begin_src maxima :tangle maxima-init.lisp :exports none > (defun $batchload (file) (mfuncall '$batch file)) > ($load "./maxima-init.mac") > ,#+end_src > #+end_example > > On tangling, this produces the ~common-lisp~ output file ~maxima-init.lisp~. It will be pre-loaded into Maxima. > > #+begin_src maxima :tangle maxima-init.lisp :exports none > (defun $batchload (file) (mfuncall '$batch file)) > ($load "./maxima-init.mac") > #+end_src I am curious if it is possible to avoid duplication by e.g. using noweb. > #+begin_src maxima :tangle maxima-init.mac :exports none At first glance :prologue header argument might be an alternative, but likely I have missed something obvious. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [TIP] Exporting Maxima results to LaTeX 2023-02-08 15:43 ` Max Nikulin @ 2023-02-08 16:11 ` Fraga, Eric 2023-02-08 20:40 ` Leo Butler 1 sibling, 0 replies; 7+ messages in thread From: Fraga, Eric @ 2023-02-08 16:11 UTC (permalink / raw) To: Max Nikulin; +Cc: emacs-orgmode@gnu.org On Wednesday, 8 Feb 2023 at 22:43, Max Nikulin wrote: > At first glance :prologue header argument might be an alternative, but > likely I have missed something obvious. Indeed. I use, for instance, the following #+PROPERTY: header-args:maxima :prologue "fpprintprec: 2; linel: 50;" for my teaching slides to ensure that Maxima output fits on my slides (and only print relevant digits in the answers). There's also an epilogue which I use to automatically format the solution of my Maxima codes (all my examples have a particular form): #+PROPERTY: header-args:maxima :epilogue "for j: 1 thru length(solution) do (print(\"\"), print(\"Solution\", j), print(\"\"), for i: 1 thru length(solution[j]) do grind(solution[j][i]))$" All my Maxima blocks define a "solution" variable. -- : Eric S Fraga, with org release_9.6-201-gb58fba in Emacs 30.0.50 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [TIP] Exporting Maxima results to LaTeX 2023-02-08 15:43 ` Max Nikulin 2023-02-08 16:11 ` Fraga, Eric @ 2023-02-08 20:40 ` Leo Butler 2023-02-11 11:39 ` Max Nikulin 1 sibling, 1 reply; 7+ messages in thread From: Leo Butler @ 2023-02-08 20:40 UTC (permalink / raw) To: Max Nikulin; +Cc: emacs-orgmode@gnu.org On Wed, Feb 08 2023, Max Nikulin <manikulin@gmail.com> wrote: > On 08/02/2023 04:40, Leo Butler wrote: >> Generate @@latex:\LaTeX{}@@ code from Maxima code. > > You can write just LaTeX, ox-latex recognizes such pattern. The bonus > is the it will be literally exported to HTML. Thanks. > >> #+begin_example >> ,#+begin_src maxima :tangle maxima-init.lisp :exports none >> (defun $batchload (file) (mfuncall '$batch file)) >> ($load "./maxima-init.mac") >> ,#+end_src >> #+end_example >> On tangling, this produces the ~common-lisp~ output file >> ~maxima-init.lisp~. It will be pre-loaded into Maxima. >> #+begin_src maxima :tangle maxima-init.lisp :exports none >> (defun $batchload (file) (mfuncall '$batch file)) >> ($load "./maxima-init.mac") >> #+end_src > > I am curious if it is possible to avoid duplication by e.g. using noweb. I am not sure what you think is being duplicated. Do you mean the duplication of the example and src blocks? I am not aware of how to remove that duplication--all the examples I have found in the worg source do what I have done above. > >> #+begin_src maxima :tangle maxima-init.mac :exports none > > At first glance :prologue header argument might be an alternative, but > likely I have missed something obvious. The prologue header is put into a temporary source file, along with the body and epilogue and it is read by Maxima's `batchload' command. So using a prologue is too late, because I need to overwrite `batchload' by its more verbose companion `batch'. That is why `maxima-init.lisp' is pre-loaded. Leo ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [TIP] Exporting Maxima results to LaTeX 2023-02-08 20:40 ` Leo Butler @ 2023-02-11 11:39 ` Max Nikulin 2023-02-14 15:13 ` Leo Butler 0 siblings, 1 reply; 7+ messages in thread From: Max Nikulin @ 2023-02-11 11:39 UTC (permalink / raw) To: emacs-orgmode; +Cc: Leo Butler On 09/02/2023 03:40, Leo Butler wrote: > On Wed, Feb 08 2023, Max Nikulin wrote: >> I am curious if it is possible to avoid duplication by e.g. using noweb. > > ... I am not aware of how to > remove that duplication--all the examples I have found in the worg > source do what I have done above. I have tried ---- >8 ---- #+begin_src elisp :exports results :results silent (require 'ob-org) #+end_src #+begin_src org :exports both :results drawer replace ,#+begin_src elisp :exports results '((1 2 3) (4 5 6)) ,#+end_src #+end_src ---- 8< ---- It is exported to LaTeX as ---- >8 ---- \begin{verbatim} #+begin_src elisp :exports results '((1 2 3) (4 5 6)) #+end_src \end{verbatim} \begin{center} \begin{tabular}{rrr} 1 & 2 & 3\\[0pt] 4 & 5 & 6\\[0pt] \end{tabular} \end{center} ---- 8< ---- For debugging of the inner src block it is necessary to swap escaping with the outer #+begin_src. I have not figured out how to add some text in between of the exported source code example and its result. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [TIP] Exporting Maxima results to LaTeX 2023-02-11 11:39 ` Max Nikulin @ 2023-02-14 15:13 ` Leo Butler 0 siblings, 0 replies; 7+ messages in thread From: Leo Butler @ 2023-02-14 15:13 UTC (permalink / raw) To: Max Nikulin; +Cc: emacs-orgmode@gnu.org [-- Attachment #1: Type: text/plain, Size: 1020 bytes --] On Sat, Feb 11 2023, Max Nikulin <manikulin@gmail.com> wrote: > On 09/02/2023 03:40, Leo Butler wrote: >> On Wed, Feb 08 2023, Max Nikulin wrote: >>> I am curious if it is possible to avoid duplication by e.g. using noweb. >> >> ... I am not aware of how to >> remove that duplication--all the examples I have found in the worg >> source do what I have done above. > > I have tried <snip> Recursive evaluation of code blocks! Of course! THANK YOU! > > For debugging of the inner src block it is necessary to swap escaping > with the outer #+begin_src. Yes, it should be possible to recursive edit in indirect buffers. I don't see how to do that. > I have not figured out how to add some text in between of the exported > source code example and its result. See the attached. You need to name a code block and manually insert the #+RESULT: stanza where you want the result put. Thanks to Max and Eric for their comments. I have incorporated the comments in the attached. Leo [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: maxima-tip.org --] [-- Type: text/x-org; name="maxima-tip.org", Size: 7145 bytes --] #+TITLE: Tip for exporting Maxima results to LaTeX #+AUTHOR: Leo Butler #+OPTIONS: H:3 toc:t num:t tags:nil todo:nil #+LATEX_CLASS: article #+LATEX_HEADER: \usepackage{color} \usepackage[margin=2cm]{geometry} #+LATEX_COMPILER: lualatex #+PROPERTY: header-args:maxima :eval export :exports results :results raw drawer * Goal Generate LaTeX code from Maxima code. * Setup ** maxima-init.lisp The command =org-babel-execute:maxima= in =lisp/ob-maxima.el= uses the Maxima command ~batchload~ to execute Maxima code. This is a very tight-lipped loader, so we over-write ~batchload~ with ~batch~. We also ~load~ an init file: #+name: maxima-init.lisp.org #+begin_src org :exports code :results replace ,#+name: maxima-init.lisp ,#+begin_src maxima :tangle maxima-init.lisp :exports none (defun $batchload (file) (mfuncall '$batch file)) ($load "./maxima-init.mac") ,#+end_src #+end_src On tangling, this produces the ~common-lisp~ output file ~maxima-init.lisp~. It will be pre-loaded into Maxima. #+RESULTS: maxima-init.lisp.org #+name: maxima-init.lisp #+begin_src maxima :tangle maxima-init.lisp :exports none (defun $batchload (file) (mfuncall '$batch file)) ($load "./maxima-init.mac") #+end_src ** maxima-init.mac Next, we need to create an init file for Maxima that will provide an output printer that produces @@latex:\LaTeX{}@@ output. One option would be to use the ~imaxima~ printer. Here is another option that uses the ~alt-display~ package. The code replaces the default printer with ~org_tex_display~. It also sets the ~epilog~ prompt, so that the final ~#+begin_example~ is terminated. #+name: maxima-init.mac.org #+begin_src org :exports code :results replace ,#+name: maxima-init.mac ,#+begin_src maxima :tangle maxima-init.mac :exports none :eval none load("alt-display.mac") $ set_prompt('epilog,printf(false,"~%#+end_example")) $ define_alt_display(org_tex_display(x), block([], printf(true,"#+end_example~%#+begin_export latex~%"), printf(true,"\\textcolor{blue}{(\\~a~d)} ",outchar,linenum-1), tex(second(x)), printf(true,"~&#+end_export~%#+begin_example~%(input) "))) $ set_alt_display(2,org_tex_display) $ display2d:true $ printf(true,"#+begin_example~%(input) ") $ linenum : 0 $ ,#+end_src #+end_src #+RESULTS: maxima-init.mac.org #+name: maxima-init.mac #+begin_src maxima :tangle maxima-init.mac :exports none :eval none load("alt-display.mac") $ set_prompt('epilog,printf(false,"~%#+end_example")) $ define_alt_display(org_tex_display(x), block([], printf(true,"#+end_example~%#+begin_export latex~%"), printf(true,"\\textcolor{blue}{(\\~a~d)} ",outchar,linenum-1), tex(second(x)), printf(true,"~&#+end_export~%#+begin_example~%(input) "))) $ set_alt_display(2,org_tex_display) $ display2d:true $ printf(true,"#+begin_example~%(input) ") $ linenum : 0 $ #+end_src * An example Here is an example that computes the partial derivatives of a composite function. ** Org code #+name: chain-rule.org #+begin_src org :exports both :results replace ,#+name: chain-rule ,#+begin_src maxima :exports both :cmdline -p ./maxima-init.lisp (gradef(f(u,v),f_1(u,v),f_2(u,v)), 'done); diff(f(x^2-y^2,x*y),x); diff(f(x^2-y^2,x*y),y); ,#+end_src #+end_src ** Maxima code #+RESULTS: chain-rule.org The first line defines the partial derivatives of \(f(u,v)\) with repect to \(u\) and \(v\). The second and third lines compute the partial derivatives of the composite \(f(x²-y²,xy)\). ** Result of evaluation; LaTeX output The ~batch~ printer echos each input line; it prints the output of each command line that ends in a semi-colon (=;=). The result of a line ending in a dollar sign (=$=) is not printed. The ~org_tex_display~ printer wraps each echoed input line in an ~example~ block and prints the output as it would appear in an =imaxima= session. #+RESULTS: chain-rule ** Two annoyances The initial line =read and interpret...= and that final, dangling input line with ~gnuplot_close()~ are nuisances. They can be easily suppressed, but that requires patching ~ob-maxima.el~. That's another story. * Epilogue After sending my initial draft to the =Org= mailing list, I received some feedback. ** Eric Fraga's suggestion :PROPERTIES: :header-args:maxima: :END: On the mailing list, Eric Fraga suggested adding the prologue/epilogue: #+begin_example #+PROPERTY: header-args:maxima :prologue "fpprintprec: 2; linel: 50;" #+PROPERTY: header-args:maxima :epilogue "for j: 1 thru length(solution) do (\ print(\"\"), print(\"Solution\", j), \ print(\"\"), for i: 1 thru length(solution[j]) do grind(solution[j][i]))$" #+end_example \normalsize Let's redo the example above with those settings and incorporating Eric's design that the results need to be collected in the ~solution~ list: #+name: fraga-example.org #+begin_src org :exports both :results replace :noweb yes ,#+name: chain-rule-redo ,#+header: :prologue "fpprintprec: 2; linel: 50;" ,#+header: :epilogue "for j: 1 thru length(solution) do (print(\"\"), print(\"Solution\", j), print(\"\"), for i: 1 thru length(solution[j]) do grind(solution[j][i]));" ,#+begin_src maxima :exports results :results table (gradef(f(u,v),f_1(u,v),f_2(u,v)), 'done); fx:diff(f(x^2-y^2,x*y),x); fy:diff(f(x^2-y^2,x*y),y); solution:[fx,fy]; ,#+end_src #+end_src #+RESULTS: fraga-example.org Here is the result: #+RESULTS: chain-rule-redo ** Max Nikulin's idea Max Nikulin remarked that the ~org~ code in this file contains redundancy. He suggested trying: #+name: elisp-in-org-in-org #+begin_src org :exports both :results replace ,#+begin_src elisp :exports results :results silent (require 'ob-org) ,#+end_src ,#+name: elisp-in-org ,#+begin_src org :exports both :results replace ,,#+name: elisp-block ,,#+begin_src elisp :exports results '((1 2 3) (4 5 6)) ,,#+end_src ,#+end_src #+end_src The block named ~elisp-in-org~ is exported to: #+RESULTS: elisp-in-org-in-org The ~elisp~ code block exports to a named block of =elisp= code. #+RESULTS: elisp-in-org That exports to: #+RESULTS: elisp-block *** A bug // Feature request =Org= does a good job of recursively evaluating code blocks, as can be seen by the examples here (Thanks, Max!). But, two things are not done quite correctly: 1. When editing ~org~ code blocks in an indirect buffer, it should be possible to recursively edit a code block. That does not appear to work at the moment. 2. Noweb expansion does not work correctly in combination with recursive evaluation of code blocks. In the ~org~ block named =fraga-example.org=, a noweb reference =<<chain-rule>>= to the Maxima code block =chain-rule= is not expanded correctly (it leaves a blank line). * How to reproduce the pdf 1. In this =org= file, do ~C-c C-v t~ to tangle the two code blocks. 2. Then, do ~C-c C-e l p~ to export to pdf. Each time you are prompted about evaluating a code block, answer ~y~ or ~yes~. [-- Attachment #3: maxima-tip.pdf --] [-- Type: application/pdf, Size: 53439 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2023-02-14 15:19 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-02-07 21:40 [TIP] Exporting Maxima results to LaTeX Leo Butler 2023-02-07 22:13 ` Thomas S. Dye 2023-02-08 15:43 ` Max Nikulin 2023-02-08 16:11 ` Fraga, Eric 2023-02-08 20:40 ` Leo Butler 2023-02-11 11:39 ` Max Nikulin 2023-02-14 15:13 ` Leo Butler
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).