diff --git a/doc/emacs-notes.org b/doc/emacs-notes.org index 827f772..5f5a71e 100644 --- a/doc/emacs-notes.org +++ b/doc/emacs-notes.org @@ -1,190 +1,6 @@ #+title: Notes on Emacs #+author: Daniel -* Introduction to Babel - -Tutorial from http://orgmode.org/worg/org-contrib/babel/intro.html - -** Source Code Execution - -#+begin_src hy - (print "Hello, There!") -#+end_src - -#+RESULTS: -: Hello, There! - -#+begin_src sh - echo "This file takes up `du -h emacs-org-babel-tutorial.org | sed 's/\([0-9k]*\)[ ]*emacs-org-babel-tutorial.org/\1/'`" -#+end_src - -#+RESULTS: -: This file takes up 4.0K - -#+begin_src R :colnames yes - words <- tolower(scan("emacs-org-babel-tutorial.org", what="", na.strings=c("|",":"))) - t(sort(table(words[nchar(words) > 3]), decreasing=TRUE)[1:10]) -#+end_src - -#+RESULTS: -| #+begin_src | #+end_src | #+results: | date | plus | today's | :results | hello, | import | is") | -|-------------+-----------+------------+------+------+---------+----------+--------+--------+------| -| 5 | 5 | 4 | 3 | 3 | 3 | 2 | 2 | 2 | 2 | - -*** Capturing the Results of Code Evaluation - -#+begin_src python :results value - import time - print("Hello, today's date is %s" % time.ctime()) - print("Two plus two is") - return 2 + 2 -#+end_src - -#+RESULTS: -: 4 - -#+begin_src python :results output - import time - print("Hello, today's date is %s" % time.ctime()) - print("Two plus two is") - 2 + 2 -#+end_src - -#+RESULTS: -: Hello, today's date is Sun Jun 26 16:04:36 2016 -: Two plus two is - -*** Session-based Evaluation - -Have a look into /Emacs Speaks Statistics/ - -*** Arguments to Code Blocks - -#+name: square -#+header: :var x = 0 -#+begin_src python - return x*x -#+end_src - -#+call: square(x=6) - -#+RESULTS: -: 36 - -#+tblname: fibonacci-inputs -| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -| 2 | 4 | 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | - -#+name: fibonacci-seq -#+begin_src emacs-lisp :var fib-inputs=fibonacci-inputs - (defun fibonacci (n) - (if (or (= n 0) (= n 1)) - n - (+ (fibonacci (- n 1)) - (fibonacci (- n 2))))) - - (mapcar (lambda (row) - (mapcar #'fibonacci row)) - fib-inputs) -#+end_src - -#+RESULTS: fibonacci-seq -| 1 | 1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 | 55 | -| 1 | 3 | 8 | 21 | 55 | 144 | 377 | 987 | 2584 | 6765 | - -*** In-line Code Blocks - -In-line code can be call without header arguments (like so: src_sh{date}) or -with header arguments (like so: src_python[:results value]{return 10 + 10}). - -*** Code Block Body Expansion - -Preview: =C-c C-v v=, bound to =org-babel-expand-src-block= - -#+tblname: data -| username | john-doe | -| password | abc123 | - -#+begin_src emacs-lisp :var data=data -(setq my-special-username (first (first data))) -(setq my-special-password (first (second data))) -#+end_src - -*** A Meta-programming Language for Org-mode - -#+name: directories -#+begin_src sh :results replace - cd ~ && du -sc * | grep -v total -#+end_src - -#+RESULTS: directories -| 538604 | Desktop | -| 77332656 | Documents | -| 1206668 | Mail | -| 8 | News | - -#+name: directory-pie-chart -#+begin_src R :session R-pie-example :var dirs=directories - pie(dirs[,1], labels = dirs[,2]) -#+end_src - -#+RESULTS: directory-pie-chart - -Note: the syntax =#+name: directory-pie-chart(dirs=directories)= did not work. - -*** Using Code Blocks in Org Tables - -**** Example 1: Data Summaries Using R - -#+name: tbl-example-data -#+begin_src R - runif(n=5, min=0, max=1) -#+end_src - -#+name: R-mean -#+begin_src R :var x="" - colMeans(x) -#+end_src - -#+tblname: summaries -| mean | -|-------------------| -| 0.574235895462334 | -#+TBLFM: @2$1='(org-sbe "R-mean" (x "tbl-example-data()")) - -**** Example 2: Babel Test Suite - -/No notes/ - -** The Library of Babel - -#+lob: square(x=6) - -Does not do what I expected … - -** Literate Programming - -#+name: hello-world-prefix -#+begin_src sh :exports none - echo "/-----------------------------------------------------------\\" -#+end_src - -#+name: hello-world-postfix -#+begin_src sh :exports none - echo "\-----------------------------------------------------------/" -#+end_src - -#+name: hello-world -#+begin_src sh :tangle hello.sh :exports none :noweb yes - <> - echo "| hello world |" - <> -#+end_src - -Tangling with =C-c C-v t=. - -** Reproducible Research - * Emacs Calc Tutorials By Andrew Hyatt, found here: https://github.com/ahyatt/emacs-calc-tutorials. @@ -1800,6 +1616,269 @@ Result: Calc, you're sooo coool! +* Irreal + +A random collection of notes from [[https://irreal.org/blog][Irreal's Blog]]. + +** Insert URL from Safari :IRREAL:NOTE: +:PROPERTIES: +:CREATED: [2018-08-04 Sat 17:44] +:END: +:LOGBOOK: +CLOCK: [2018-08-04 Sat 17:44]--[2018-08-04 Sat 17:45] => 0:01 +:END: + +Responding to [[http://irreal.org/blog/?p=6924][yesterday's post]], Sacha asks if I could post the code for +=jcs-insert-url= for others to use. I thought I'd already done that but +apparently not. That's probably because except for the part identical to +=jcs-get-link=, which I /did/ [[http://irreal.org/blog/?p=2895][write about]], it's pretty trivial. In any event, +here it is: + +#+BEGIN_SRC emacs-lisp +(defun jcs-insert-url () + "Insert URL of current browser page into Emacs buffer." + (interactive) + (insert (jcs-retrieve-url))) +#+END_SRC + +The =jcs-retrieve-url= function does all the work, of course, and is +just the code that I abstracted out of =jcs-get-link= to actually +retrieve the URL from Safari: + +#+BEGIN_SRC emacs-lisp +(defun jcs-retrieve-url () + "Retrieve the URL of the current Safari page as a string." + (org-trim (shell-command-to-string + "osascript -e 'tell application \"Safari\" to return URL of document 1'"))) +#+END_SRC + +One obvious problem with all this is that it works only for macOS. Not to +despair, though, because in the comments to the original post, [[http://irreal.org/blog/?p=6924#comment-3732979999][Brad Collins +suggests a solution]] that uses [[https://github.com/xuchunyang/grab-x-link][grab-x-link]] to do the same thing for FireFox and +Chrome on other systems. Be sure to read Brad's comment because there is---or at +least was---an issue with the MELPA version. + +Finally, Sacha took the part about looking for ways to make your workflow easier +seriously and came up with a bit of Elisp to [[http://sachachua.com/blog/2018/01/org-mode-inserting-a-function-definition/][insert a function definition at the +point]], regardless of where it's defined. That's very handy and I immediately +stole her code and used it to insert the two functions above. My old method was +to switch to =init.el=, find the function, copy it to the kill ring, switch back +to the original buffer, add the source block fences, and insert the code between +them. Sacha's code did all of that for me and I didn't even have to leave my +current buffer. That's splendid. If you find yourself having to add function +definitions to your text, be sure to read Sacha's post. It will save you a lot +of time. + +[[http://irreal.org/blog/?p=6926][Link]] + +** Calc for Programmers :IRREAL:NOTE: +:PROPERTIES: +:CREATED: [2018-08-05 Sun 10:04] +:END: +:LOGBOOK: +CLOCK: [2018-08-05 Sun 10:04]--[2018-08-05 Sun 10:05] => 0:01 +:END: + +After writing about Florian Adamsky's post on [[http://irreal.org/blog/?p=7040][acronyms in AUCTeX]], I snooped +around on his site and came across a [[https://florian.adamsky.it/2016/03/31/emacs-calc-for-programmers-and-cs.html][nice post]] on [[https://www.gnu.org/software/emacs/manual/html_node/calc/index.html][Emacs Calc]] from a programmer's +and computer scientist's point of view. As regular readers know, I've been +working to increase my calc-fu lately so I read the post with interest. + +Adamsky demonstrates some of the Calc functions that are useful to programmers +and computer scientists. This includes such things as entering and displaying +numbers in various radixes and performing the standard logical operations on +(the usually binary representation of) numbers. He even shows how to add a new +“units” representation to Calc---in this case bits/bytes/bits per second. + +Calc is a large subsystem and famously hard to master but worth the effort. It's +been described as a “poor man's Mathematica.” It's not nearly as powerful as +Mathematica, of course, but it's surprising how many things it can do. If you're +a programmer/computer scientist and an Emacs user you should spend a little time +investigating Calc. It really can make your life easier. An easy way to get +started is to read Adamsky's post. It covers only a small slice of Calc but will +give you an idea of its power. + +[[http://irreal.org/blog/?p=7044][Link]] + +** Parsing with Org-Element :IRREAL:NOTE: +:PROPERTIES: +:CREATED: [2018-08-10 Fri 17:55] +:END: + +The other day, I saw [[https://www.reddit.com/r/emacs/comments/89bxe0/org_mode_longterm_time_tracking_for_freelancers/][this query]] on the reddit Emacs subreddit. I already have +solutions for this type of problem but I'm always interested in the how people +use Org mode to record and report data so I followed the link that primitiveinds +provided for [[https://alexpeits.github.io/programming/2017/02/12/org-timesheets.html][his solution]] to generating time reports. + +Even if, like me, you already have your time tracking and reporting needs under +control, primitiveinds' solution is worth looking at for its own sake. It works +by looking for CLOCK entries in an Org buffer and accumulating the relevant +information in the CLOCK line as well data about the associated task. That might +seem like it would require routine but tedious text manipulation but +primitiveinds leverages the org-element functionality to easily handle the task. + +He starts by calling =org-element-parse-buffer= to generate a tree +representation of the Org buffer. Then he uses =org-element-map= to examine each +CLOCK element (and only CLOCK elements) to extract the necessary +information. It's a great technique that can easily be adapted for other parsing +of Org data. The code that primitiveinds presents is easy to follow and he +provides a nice explanation of what it's doing. + +If you need to programmatically examine Org data for further processing, you +should take a look at primitiveinds' post. It's definitely worth a read. + +[[http://irreal.org/blog/?p=7073][Link]] + +The relevant code: + +#+begin_src emacs-lisp +(nconc + '(("date" "project" "hours" "task")) + '(hline) + (let ((ast (org-element-parse-buffer 'element))) + (org-element-map ast 'clock + (lambda (x) + (let* ((val (org-element-property :value x)) + (task (org-element-property :parent (org-element-property :parent x)))) + `(,(let ((year (org-element-property :year-start val)) + (month (calendar-month-name + (org-element-property :month-start val))) + (day (org-element-property :day-start val))) + ;; (insert (org-element-property :raw-value val)) + (format "%s %s, %s" month day year)) + ,(org-element-property :PROJECT task) + ,(org-element-property :duration x) + ,(org-element-property :title task) + ))))) + '(hline) + '(("" "total:" ":=vsum(@2..@-1);T" ""))) +#+end_src + +** Emacs Lisp Byte-Code :NOTE: +:PROPERTIES: +:CREATED: [2018-08-11 Sat 21:40] +:END: + +Very few Emacs users---no matter how advanced---ever need to worry about the +specifics of the Elisp bytecode, or even, for that matter, that it +exists. Still, as guys like Chris Wellons [[http://nullprogram.com/blog/2014/01/04/][have shown]], it can sometimes be useful +to have a basic understanding of the bytecodes. + +R Bernstein has put together a comprehensive, book-length [[http://rocky.github.io/elisp-bytecode.pdf][documentation on Elisp +bytecodes]]. After a short introduction, the documentation considers the bytecode +environment including the compiler, interpreter, and bytecode optimization. Then +there's a long section on the individual bytecode instructions. + +Finally, there are sections on the changes in bytecodes between Emacs versions, +a table of opcodes, and a reference section. There's also a GitHub repository of +the [[https://github.com/rocky/elisp-bytecode][document source]]. + +As I said, you probably will never need this but if you do, you'll be /very/ +glad to have Bernstein's documentation. It's another example of the vibrant +Emacs community. + +[[http://irreal.org/blog/?p=7166][Link]] +** Formatting Tables :IRREAL:NOTE: +:PROPERTIES: +:CREATED: [2018-10-28 Sun 09:13] +:END: + +If you're like me, you automatically think of the Org mode table editor (or +Orgtbl minor mode) when you think of tables in Emacs. It's hard to beat that +functionality and Orgtbl mode makes it available everywhere in Emacs, even if +you're not in an Org buffer. Sometimes, though, you'd like to have special +formatting for some or all of the table. That's where =delim-col= comes in. + +=Delim-col= is /built-in/ Emacs functionality that allows you to do things like +adjust what string separates the columns, add a beginning or ending string to +each item, add an ending string for each row, and adjust the padding in the +table. It can be really handy for copying and pasting and then reformatting +tables from an external source. + +I didn't know about =delim-col= until I read about it [[https://emacsnotes.wordpress.com/2018/09/24/delim-col-a-handy-tool-for-creating-pretty-tables-and-converting-those-to-different-table-formats/][over at Emacs Notes]], where +you'll find a good explanation of the facility and what it can do. The Emacs +Notes post also offers at bit of Elisp to make choosing the strings and +delimiters a bit easier. By default you have to set them using a series of +=setq= statements if you want something different from the built-in choices. The +Emacs Notes codes arranges for you to be prompted for the values. + +You probably won't need the =delim-col= functionality very often but when you do +it's much easier than using something like a keyboard macro. Take a look at the +post and see if you don't agree. + +[[http://irreal.org/blog/?p=7540][Link]] + +** Inserting a function definition :CHUA:NOTE: +:PROPERTIES: +:CREATED: [2018-08-04 Sat 17:40] +:END: +:LOGBOOK: +CLOCK: [2018-08-04 Sat 17:40]--[2018-08-04 Sat 17:42] => 0:02 +:END: + +While nudging jcs to add a definition of =jcs-insert-url= to the blog post about +[[http://irreal.org/blog/?p=6924][Making Things Easier]], I realized it might be handy to have a quick function for +inserting a function definition without thinking about where it's defined. This +tries to use the definition from the source, and it can fall back to using the +stored function definition if necessary. There's probably a better way to do +this, but this was small and fun to write. =) + +Naturally, I used it to insert itself: + +#+begin_src emacs-lisp +(defun my/org-insert-defun (function) + "Inserts an Org source block with the definition for FUNCTION." + (interactive (find-function-read)) + (let* ((buffer-point (condition-case nil + (find-definition-noselect function nil) + (error nil))) + (new-buf (car buffer-point)) + (new-point (cdr buffer-point)) + definition) + (if buffer-point + (with-current-buffer new-buf ;; Try to get original definition + (save-excursion + (goto-char new-point) + (setq definition (buffer-substring-no-properties + (point) + (save-excursion (end-of-defun) (point)))))) + ;; Fallback: Print function definition + (setq definition (concat (prin1-to-string + (symbol-function function)) + "\n"))) + (insert "#+begin_src emacs-lisp\n" definition "#+end_src\n"))) +#+end_src + +[[http://sachachua.com/blog/2018/01/org-mode-inserting-a-function-definition/][Link]] +** Org Mode Cookbook :NOTE: +:PROPERTIES: +:CREATED: [2018-08-04 Sat 12:51] +:END: +:LOGBOOK: +CLOCK: [2018-08-04 Sat 12:51]--[2018-08-04 Sat 12:54] => 0:03 +:END: + +Way back in 2014, I [[http://irreal.org/blog/?p=2575][posted]] about Eric Neilsen's excellent [[http://ehneilsen.net/notebook/orgExamples/org-examples.html][Emacs org-mode +examples and cookbook]]. I recently came across a reference to it and was reminded +what a great resource it is. It's easy to browse through and just read one or +two entries when you have time. In skimming through it, I learned---or perhaps +relearned---how to [[http://ehneilsen.net/notebook/orgExamples/org-examples.html#sec-10][insert in-line calculations in a document]]. + +As I wrote in the original post, Neilsen is a researcher and his cookbook is +oriented at using Org mode to produce documents of various types. Still, that +covers a lot of territory and there are many good examples of powerful Org mode +use cases in it. The Document has moved or, really, taken up a second +residence. It was originally hosted at [[http://fnal.gov/][Fermilab]], where Neilsen works, and it's +still there but it's also available at his own site. The two documents are +identical so it doesn't matter if you use the new link or the original one +pointing to FNAL. + +If you're an Org user, especially if you use Org to produce documents, +you should take a look at Neilsen's cookbook and bookmark it for future +use. + +[[http://irreal.org/blog/?p=6894][Link]] + * Random Notes ** How to paste then copy :NOTE: :PROPERTIES: @@ -1869,3 +1948,643 @@ From https://nullprogram.com/blog/2012/09/14/ (insert-char (floor (* 256 (/ v 1.0 d))) 3)))) (image-mode))) #+end_src +** Introduction to Babel + +Tutorial from http://orgmode.org/worg/org-contrib/babel/intro.html + +*** Source Code Execution + +#+begin_src hy + (print "Hello, There!") +#+end_src + +#+RESULTS: +: Hello, There! + +#+begin_src sh + echo "This file takes up `du -h emacs-org-babel-tutorial.org | sed 's/\([0-9k]*\)[ ]*emacs-org-babel-tutorial.org/\1/'`" +#+end_src + +#+RESULTS: +: This file takes up 4.0K + +#+begin_src R :colnames yes + words <- tolower(scan("emacs-org-babel-tutorial.org", what="", na.strings=c("|",":"))) + t(sort(table(words[nchar(words) > 3]), decreasing=TRUE)[1:10]) +#+end_src + +#+RESULTS: +| #+begin_src | #+end_src | #+results: | date | plus | today's | :results | hello, | import | is") | +|-------------+-----------+------------+------+------+---------+----------+--------+--------+------| +| 5 | 5 | 4 | 3 | 3 | 3 | 2 | 2 | 2 | 2 | + +**** Capturing the Results of Code Evaluation + +#+begin_src python :results value + import time + print("Hello, today's date is %s" % time.ctime()) + print("Two plus two is") + return 2 + 2 +#+end_src + +#+RESULTS: +: 4 + +#+begin_src python :results output + import time + print("Hello, today's date is %s" % time.ctime()) + print("Two plus two is") + 2 + 2 +#+end_src + +#+RESULTS: +: Hello, today's date is Sun Jun 26 16:04:36 2016 +: Two plus two is + +**** Session-based Evaluation + +Have a look into /Emacs Speaks Statistics/ + +**** Arguments to Code Blocks + +#+name: square +#+header: :var x = 0 +#+begin_src python + return x*x +#+end_src + +#+call: square(x=6) + +#+RESULTS: +: 36 + +#+tblname: fibonacci-inputs +| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | +| 2 | 4 | 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | + +#+name: fibonacci-seq +#+begin_src emacs-lisp :var fib-inputs=fibonacci-inputs + (defun fibonacci (n) + (if (or (= n 0) (= n 1)) + n + (+ (fibonacci (- n 1)) + (fibonacci (- n 2))))) + + (mapcar (lambda (row) + (mapcar #'fibonacci row)) + fib-inputs) +#+end_src + +#+RESULTS: fibonacci-seq +| 1 | 1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 | 55 | +| 1 | 3 | 8 | 21 | 55 | 144 | 377 | 987 | 2584 | 6765 | + +**** In-line Code Blocks + +In-line code can be call without header arguments (like so: src_sh{date}) or +with header arguments (like so: src_python[:results value]{return 10 + 10}). + +**** Code Block Body Expansion + +Preview: =C-c C-v v=, bound to =org-babel-expand-src-block= + +#+tblname: data +| username | john-doe | +| password | abc123 | + +#+begin_src emacs-lisp :var data=data +(setq my-special-username (first (first data))) +(setq my-special-password (first (second data))) +#+end_src + +**** A Meta-programming Language for Org-mode + +#+name: directories +#+begin_src sh :results replace + cd ~ && du -sc * | grep -v total +#+end_src + +#+RESULTS: directories +| 538604 | Desktop | +| 77332656 | Documents | +| 1206668 | Mail | +| 8 | News | + +#+name: directory-pie-chart +#+begin_src R :session R-pie-example :var dirs=directories + pie(dirs[,1], labels = dirs[,2]) +#+end_src + +#+RESULTS: directory-pie-chart + +Note: the syntax =#+name: directory-pie-chart(dirs=directories)= did not work. + +**** Using Code Blocks in Org Tables + +***** Example 1: Data Summaries Using R + +#+name: tbl-example-data +#+begin_src R + runif(n=5, min=0, max=1) +#+end_src + +#+name: R-mean +#+begin_src R :var x="" + colMeans(x) +#+end_src + +#+tblname: summaries +| mean | +|-------------------| +| 0.574235895462334 | +#+TBLFM: @2$1='(org-sbe "R-mean" (x "tbl-example-data()")) + +***** Example 2: Babel Test Suite + +/No notes/ + +*** The Library of Babel + +#+lob: square(x=6) + +Does not do what I expected … + +*** Literate Programming + +#+name: hello-world-prefix +#+begin_src sh :exports none + echo "/-----------------------------------------------------------\\" +#+end_src + +#+name: hello-world-postfix +#+begin_src sh :exports none + echo "\-----------------------------------------------------------/" +#+end_src + +#+name: hello-world +#+begin_src sh :tangle hello.sh :exports none :noweb yes + <> + echo "| hello world |" + <> +#+end_src + +Tangling with =C-c C-v t=. + +** Presentations with ~org-reveal~ + +Website: https://github.com/yjwen/org-reveal + +Sample: + +#+BEGIN_SRC org + #+title: Foo! + #+author: bar + + #+options: author:t toc:t num:nil date:nil timestamp:nil + #+reveal_theme: sky + + * Slide 1 + * Slide 2 + ** Subslide 1 + ** Subslide 2 + - Item 1 + - Item 2 + + | a | b | d | + |---+---+---| + | 1 | 2 | 3 | + * Slide 3 +#+END_SRC +** Writing a PhD thesis with Org Mode +:PROPERTIES: +:LINK: https://write.as/dani/writing-a-phd-thesis-with-org-mode +:END: + +*TLDR*: I started using Emacs about 3 years ago. I couldn't be more grateful to +have seen the light, and to have been rescued from the darkness of Windoze, +Goggle and/or friends. After enlightenment, I've taken upon myself the task of +customising an environment to write my PhD thesis with Org Mode.* + +*** Why + +Post created in response to the [[https://www.reddit.com/r/emacs/comments/9ynsvc/write_a_thesis_using_emacs_and_orgmode/][current thread]] in /r/emacs/ on thesis writing +with Org Mode.\\ I see most people's reason to avoid Org mode for scientific +writing is the fact that supervisors or co-authors use Mic. Word. I'll try to +argue that that's not enough reason to accept subpar tools. + +*** What I'll talk about + +I'll mention a bit of my motivations, and then I'll discuss how to make use of +(mostly) built in Org functionality such as tagging, export, [[https://orgmode.org/manual/In_002dbuffer-settings.html][setupfiles]] and +includes, reference management, keyboard shortcuts and advanced searching; all +with the purpose of building a useful thesis writing environment. Readers should +have a minimum knowledge of Org mode, the Org export system and LaTeX. + +*** My requirements + +Here in the Netherlands, most PhD thesis consist of an introduction, 3 to 4 +research chapters (as submitted for publication), a summary, bibliography and +appendices. What this means for me is that my writing environment has to +/necessarily/ satisfy the following *minimum requirements*: + +- Inclusion of (parts of) external files +- Keeping track of references +- Include and reference figures +- Version control documents +- Support for sharing with my supervisor in whatever format he wants + +Failure to comply with any of these means the editor is unfit for +purpose^{#fn.1”>1}. Unfortunately, this set of requirements are not seamlessly +satisfied by likes of Mic. Word or G. Docs. I reckon they can probably be +configured to satisfy them, but why bother. + +Additionally, a PhD thesis writing environment should also provide the following +features: + +- Extended searching facilities for both text and references +- Simple syntax for tables and equations +- Support within a proper text editor +- Shortcuts to reach my files and build the thesis + +To the best of my knowledge, /only/ Emacs with Org Mode + ox-latex provide all +of these out of the box. + +*** Moulding Org Mode for thesis writing + +Most of my inspiration comes from reading Kitchin's blogs and code, and reading +the Org Mode documentation, mailing list and Emacs Stack Exchange. Here' I'll go +one by one through all of the requirements listed above, and how to deal with +them. + +**** Prelude: File structure + +I have a main /thesis.org/ document, with latex heading declarations and a +commented setup file. I also have /research.org/ files, in different +directories, with their own latex heading declarations and commented setup +files. + +The first lines of /thesis.org/ look like the following: + +#+BEGIN_src org + # -*- mode: org; org-latex-title-command: ""; org-latex-toc-command: "" -*- + #+TITLE: Thesis Title + #+LATEX_CLASS: mimosis + # Setupfile with #+LATEX_HEADER, #+OPTIONS and explanations + #+SETUPFILE: thesis.setup + #+LATEX_HEADER: \KOMAoptions{fontsize=12pt,headings=small} + #+LATEX_HEADER: \bibliography{~/Papers/bibtex/Publications} + #+EXCLUDE_TAGS: journal noexport + + * Frontmatter :ignore: + #+LATEX: \frontmatter + #+INCLUDE: ./Title.org + #+LATEX: \tableofcontents + + * Mainmatter :ignore: + #+LATEX: \mainmatter + + * Introduction + * Research 1 + #+INCLUDE: "../research1/research.org::*Abstract" :only-contents t + Some stuff. + #+INCLUDE: "../research1/research.org" :lines "5-" + + * Research 2 + ... +#+END_src + +And the first lines and structure overview of the multiple /research.org/ files: + +#+BEGIN_src org + #+TITLE: Research + #+LATEX_CLASS: elsarticle + #+LATEX_CLASS_OPTIONS: [authoryear,preprint,11pt] + #+SETUPFILE: paper.setup + #+LATEX_HEADER:\bibliography{./ref/Publications-research} + #+EXCLUDE_TAGS: thesis noexport + + * Frontmatter :ignore:journal: + #+LATEX: \begin{frontmatter} + ** Author List :ignore: Abstract :ignore: Keywords :ignore: + #+LATEX: \end{frontmatter} + * Introduction + ... +#+END_src + +**** Inserting (parts of) external files + +I write my research chapters with LaTeX classes targeting the journal's +format. That means that a research chapter may be written with the =elsarticle= +class, whereas the thesis as a whole is written with the =mimosis= [[https://github.com/Submanifold/latex-mimosis][class]], a +derivative of KOMA =scrbook=. Here's the class configuration for both: + +#+begin_src emacs-lisp +(add-to-list 'org-latex-classes + '("elsarticle" + "\\documentclass{elsarticle} + [NO-DEFAULT-PACKAGES] + [PACKAGES] + [EXTRA]" + ("\\section{%s}" + . "\\section*{%s}") ("\\subsection{%s}" + . "\\subsection*{%s}") ("\\subsubsection{%s}" + . "\\subsubsection*{%s}") ("\\paragraph{%s}" + . "\\paragraph*{%s}") ("\\subparagraph{%s}" + . "\\subparagraph*{%s}"))) +(add-to-list 'org-latex-classes + '("mimosis" + "\\documentclass{mimosis} + [NO-DEFAULT-PACKAGES] + [PACKAGES] + [EXTRA] + \\newcommand{\\mboxparagraph}[1]{\\paragraph{#1}\\mbox{}\\\\} + \\newcommand{\\mboxsubparagraph}[1]{\\subparagraph{#1}\\mbox{}\\\\}" + ("\\chapter{%s}" . "\\chapter*{%s}") + ("\\section{%s}" + . "\\section*{%s}") ("\\subsection{%s}" + . "\\subsection*{%s}") ("\\subsubsection{%s}" + . "\\subsubsection*{%s}") ("\\mboxparagraph{%s}" + . "\\mboxparagraph*{%s}") ("\\mboxsubparagraph{%s}" + . "\\mboxsubparagraph*{%s}"))) +#+END_src + +Research chapters print the bibliography on their own, and they may contain +acknowledgements that shouldn't be present in the middle of the thesis, so they +should be excluded. In other to insert research chapters into my thesis, I use +Org's =#+INCLUDE= derivative: + +#+begin_src org + #+INCLUDE: file.org +#+end_src + +In order to not include the some parts of the file, i.e., to exclude the title, +setupfile and headers, I narrow down the lines: + +#+begin_src org + # Include line 5 until the end of the file + #+INCLUDE: file.org :lines 5- +#+end_src + +In order to exclude parts of the file, I tag research chapter headings that are +only meant for publication with a =:journal:= tag (such as the bibliography or +acknowledgements). This way they are automatically excluded from the thesis (see +the =#+EXCLUDE_TAGS:= derivative in the /thesis.org/ file). Also, I could have +thesis specific content in the /research.org/ document tagged with =:thesis:=, +and it would be excluded in the /research.org/ export, but I currently don't +have any. + +Now, the most important piece of advice I can give anyone is to *learn how to +use tags*, =EXCLUDE_TAGS= and the org-plus-contributions =ignore= tag. With the +=ignore= tag we separate the structuring of the text as a physical document from +the structuring of the text as a semantic unity. This allows an extremely fine +control over pieces of text to include into another document. For example, in a +research chapter written with the =elsarticle= class, the abstract has to be +included in the Frontmatter. By tagging a headline as follows: + +#+begin_src org + ** Abstract :ignore: +#+end_src + +I can write the research abstract in it's own heading, pretend that the heading +itself does not exist (so it does not trigger =/begin{document}=), only its +contents, and then include the contents in the thesis in an arbitrary location: + +#+begin_src org + # in thesis.org + #+INCLUDE: "research.org::*Abstract" :only-contents t +#+end_src + +The =:ignore:= tag is one of the best Org mode features, in my opinion. It's +key to my workflow, and a shame to see it's not a part of Org core, but rather a +contribution to be found in /ox-extra.el/. To activate it, add the following to +your /init/: + +#+BEGIN_src emacs-lisp +(require 'ox-extra) +(ox-extras-activate '(ignore-headlines)) +#+END_src + +The realisation that it's possible to have such fine control over where to +include or exclude pieces of text opens the door to all sort of interesting +experiments: putting figures and captions directly into beamer or org-reveal +presentations, creating conference posters, writing blog posts, etc. + +**** Keep track of references + +For backwards compatibility I still use Mendeley to track literature. I export +bibtex files for each research project individually, and also a master bibtex +for use in the thesis. These documents are saved to =~/Papers/bibtex/=, but for +the research chapters, I keep local copies under +=./ref/Publications-research.bib=.\\ To insert citations, I use [[https://github.com/jkitchin/org-ref][org-ref.]] It's +documentation says it all. After setting up local bibliography files with the +derivative =#+BIBLIOGRAPHY=, press =C-c ]= to see a list of publications and +insert them in place. I also prefer to have =parencite= citations instead of +=cite=, because they work nicely with BibLaTeX. My setup for org-ref: + +#+begin_src emacs-lisp +(with-eval-after-load 'org-ref ;; see org-ref for use of these variables + (setq org-ref-default-bibliography '("~/Papers/bibtex/Publications.bib") + org-ref-pdf-directory "~/Papers/MendeleyDesktop/" + org-ref-get-pdf-filename-function 'org-ref-get-mendeley-filename + bibtex-completion-pdf-field "file" org-latex-prefer-user-labels t + org-ref-default-citation-link "parencite" + ;; bibtex-dialect 'biblatex + ) + + (defun org-ref-open-pdf-at-point-in-emacs () + "Open the pdf for bibtex key under point if it exists." + (interactive) + (let* ((results (org-ref-get-bibtex-key-and-file)) + (key (car results)) + (pdf-file (funcall org-ref-get-pdf-filename-function key))) + (if (file-exists-p pdf-file) + (find-file-other-window pdf-file) + (message "no pdf found for %s" key)))) + + ;; https://github.com/jkitchin/org-ref/issues/597 + (defun org-ref-grep-pdf (&optional _candidate) + "Search pdf files of marked CANDIDATEs." + (interactive) + (let ((keys (helm-marked-candidates)) + (get-pdf-function org-ref-get-pdf-filename-function)) + (helm-do-pdfgrep-1 + (-remove (lambda (pdf) (string= pdf "")) + (mapcar (lambda (key) (funcall get-pdf-function key)) + keys))))) + + (helm-add-action-to-source "Grep PDF" 'org-ref-grep-pdf helm-source-bibtex 1) + + (setq helm-bibtex-map (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "C-s") (lambda () (interactive) (helm-run-after-exit 'org-ref-grep-pdf))) + map)) + (push `(keymap . ,helm-bibtex-map) helm-source-bibtex) + + (setq org-ref-helm-user-candidates + '(("Open in Emacs" . org-ref-open-pdf-at-point-in-emacs)))) +#+end_src + +**** Include and reference figures + +For each research project I keep a =./media= directory, where all my figures +live. You can include figures in Org mode by using the following syntax: + +#+begin_src org + #+NAME: figurename + #+CAPTION: This is a figure caption + [[path_to_figure][link_description]] +#+end_src + +Currently there is a bug in the ELPA version of Org mode, such that relative +paths to figures in =#+INCLUDE= 'd files aren't adapted with respect to the +including file, so the latex export cannot find them. I've [[https://code.orgmode.org/bzg/org-mode/commit/d81a1d088c74e605c99e90a2835c55df5144f43e][submitted a fix]] +which should land in the next release of Org. + +**** Version control documents + +[[https://magit.vc/][Magit]]. I thought about having the research chapters as git submodules in a +thesis git project directory, but I currently don't. This would allow me to +always have the thesis code in a saved state, even if I further work on my +research chapters to answer to reviewers questions. + +**** Support for sharing with my supervisor + +Unfortunately, my supervisor likes to write comments in Mic. Word. I give in +that sharing your writing with colleagues is a fundamental part of +research.\\ Fortunately, [[https://github.com/jkitchin/scimax/blob/master/ox-word.el][ox-word]] export via Pandoc & LaTeX is capable of +creating nice looking, structured Word files which I send to my supervisor. I +then manually work through each comment step by step, though I'm looking for a +way to improve this part of my workflow. I think the Emacs community is missing +a minor mode to track Word document changes from within Org Mode. There are some +ideas laying around on how to implement it [[https://lists.gnu.org/archive/html/emacs-orgmode/2015-06/msg00246.html][hidden deep in the mailing list]], or +in [[https://emacs.stackexchange.com/questions/34923/merging-changes-to-from-docx-files-into-org-files][this Emacs Exchange thread]]. + +I may update this post with more information later. + +**** Extended search facilities + +By extended search facilities I mean the ability to quickly search for +information in references, and to keep notes linked to the literature. For +searching I make use of [[https://github.com/jkitchin/org-ref/issues/597][org-ref + pdfgrep]], as shown in my org-ref setup. For +notes linked to documents I've recently started to use [[https://github.com/weirdNox/org-noter][Org-noter.]] + +**** Simple syntax for tables and equations + +Org tables are a pleasure to work with. The following: + +#+BEGIN_EXAMPLE +| a | b | c | +|---+---+---| +| 1 | 2 | 3 | +#+END_EXAMPLE + +Turns into: + +| a | b | c | +|-----+-----+-----| +| 1 | 2 | 3 | + +Equations can be written in LaTeX: + +#+BEGIN_EXAMPLE +\frac{d \vec{M} (t)}{dt} = \vec{M} (t) \times \gamma \vec{B} (t) +#+END_EXAMPLE + +will become /omitted/ + +**** Support within a proper text editor + +No need to talk about the synergy of using Emacs to edit text. I personally +started using Spacemacs without Evil mode, because I find it aesthetically +pleasing and because it offers great support for the languages I use the most, +and excellent integration with Helm and Org.\\ The following configurations make +the Org editing experience a bit nicer, in my opinion: + +#+BEGIN_src emacs-lisp +;; Writegood https://github.com/bnbeckwith/writegood-mode +(add-hook 'org-mode-hook 'writegood-mode) + +;; https://github.com/cadadr/elisp/blob/master/org-variable-pitch.el +(use-package org-variable-pitch + :load-path "~/Elisp") +(add-hook 'org-mode-hook 'org-variable-pitch-minor-mode) + +(setq visual-fill-column-width 120 visual-fill-column-center-text t) +(add-hook 'org-mode-hook 'visual-line-mode) + +;; https://github.com/joostkremers/visual-fill-column +(add-hook 'org-mode-hook 'visual-fill-column-mode) +(add-hook 'org-mode-hook 'org-display-inline-images) + +;; I have a modified version of the following: +;; https://github.com/lepisma/rogue/blob/master/config.el +(load-file "~/Projects/rogue/config.el") +(add-hook 'org-mode-hook '(lambda () (setq-local line-spacing 5))) + +;; Aesthetical enhancements. +(setq org-fontify-quote-and-verse-blocks t + org-hide-macro-markers t + org-fontify-whole-heading-line t + org-fontify-done-headline t + org-hide-emphasis-markers t) +#+END_src + +**** Shortcuts to reach my files and build the thesis + +I have a hydra (defined in Spacemacs as a transient-state) to move between my +Thesis files: + +#+begin_src emacs-lisp +;; Spacemacs hydra. +(spacemacs|define-transient-state + thesis-menu + :title "Ph.D. Thesis Menu" + :doc " +^Main Files^ ^Chapters^ ^Actions^ +^^^^^^^^------------------------------------------- +_m_: Thesis _1_: Research 1 _o_: Open Thesis.pdf externally +_t_: Title page _2_: Research 2 _c_: Async compile file +_i_: Introduction _3_: Research 3 _a_: things +_s_: thesis.setup _4_: Research 4 ^ ^ +" + :bindings + ("a" things :exit t) + ("m" (find-file "~/thesis/thesis.org") :exit t) + ("t" (find-file + "~/thesis/titlepage.org") :exit t) + ("s" (find-file + "~/thesis/thesis.setup") :exit t) + ("i" (find-file + "~/thesis/intro/intro.org") :exit t) + ("1" (find-file + "~/thesis/ch1/research.org") :exit t) + ("2" (find-file + "~/thesis/ch2/research.org") :exit t) + ("3" (find-file + "~/thesis/ch3/research.org") :exit t) + ("4" (find-file + "~/thesis/ch4/research.org") :exit t) + ("o" (shell-command "open + ~/thesis/thesis.pdf" :exit t)) + ("c" (org-latex-export-to-pdf :async t) + :exit t)) + +(global-set-key (kbd "H-t") 'spacemacs/thesis-menu-transient-state/body) +#+end_src +** Gnus and notmuch + +Currently working: notmuch for nnmaildir backend. However, I also have a local +nnimap-backend, which uses Maildir format locally. It would be nice to have +this working with notmuch as well. + +Relevant functions: +- ~nnir-compose-result~ :: Goes over the results of notmuch (stored in the + buffer ~*nnir*~ (with an additional leading space) and decides which lines + to keep; +- ~nnir-notmuch-remove-prefix~ :: a server-local variable to decide what to + remove from the lines in ~*nnir*~. + +** Summary of Search and Replace Commands in Emacs :NOTE: +[2016-08-13 Sat 17:50] + +http://www.omps.in/blog/2016/01/20/day-10-search-and-replace-using-regex/