Org Emacs Project Template
Table of Contents
1 What is it?
Defines a create_orgMode_project
bash script to quickly generate an OrgMode project structure.
createOrgProject MyProject
1.1 Features
The framework provides some functionalities like:
- org publish configuration
- bibliography file with its configuration
- pdf export configuration luaTeX + biber + minted (utf8 support)
- org templates (also org protocol) configuration
2 Quick starter
2.1 Emacs init.el
configuration
To use the project (template) simply run this code.
Note: if you want to use this configure in a regular basis, simply add
this function to your Emacs init.el
2.1.1 Required packages
(require 'project) (require 'org-ref) (require 'htmlize)
2.1.2 my-new-project-configuration
function
(defun my-new-project-configuration () "Sets my-project-root as root project directory and load my-project-root/setup/setup.el project configuration file " (interactive) (setq my-project-root (expand-file-name (car (project-roots (project-current))))) (if my-project-root (let ((my-project-setup-file (concat my-project-root "setup/setup.el"))) (if (file-exists-p my-project-setup-file) (load my-project-setup-file nil t t nil) (error "Project %s setup file not found" my-project-setup-file))) (error "Project root dir not found (missing .git ?)")))
Its role is to found the project root (= the directory containing the
.git directory) and to load the project configuration
setup/setup.el
.
2.2 New project creation
Use the provided shell script:
createorgproject MyProject
Please note that by default, this script will never overwrite
anything. If to want to overwrite, use the -f
option.
Important: if you just created a fresh new project be sure that there
is a .git
directory as it is used to locate the project root. If you
simply want to do a quick test you can do
cd MyProject echo >> .git
as an alternative.
Once that the script has been run you can use Emacs as usual:
emacs MyProject/page_example.org &
Then load your project configuration M-x my-new-project-configuration
Then you can do whatever you want, for instance publish your project with C-c C-e P p and visit the generated pages:
firefox MyProject/index.html
Note: you can also try C-c C-e l o to check PDF exports.
3 Project structure
:header-args: :mkdirp yes
3.1 project root
Create files at project root
3.1.1 theindex_org
This file includes the generated index
#+CALL: Setup() #+TITLE: Index #+CALL: HomeUp() #+INCLUDE: "theindex.inc"
3.1.2 todo.org
#+CALL: Setup() #+TITLE: TODO list #+CALL: HomeUp()
3.1.3 journal.org
#+CALL: Setup() #+TITLE: Journal #+CALL: HomeUp()
3.1.4 www_links.org
#+CALL: Setup() #+TITLE: External web links #+CALL: HomeUp()
3.2 setup/
This directory contains the configuration files.
3.2.1 setup/library-of-babel.org
This file contains function definitions, that are loaded with org-babel-lob-ingest
.
- The
Setup()
command
<-The
#+CALL: Setup()
has to be set at the beginning of your org file (see: file:example/example.org).The latex package verbatim is required by the bibliography trick in
Bibliography()
to support both html and pdf export.The minted package is used for code listings
#+NAME: Setup #+BEGIN_SRC emacs-lisp :results drawer (concat "#+OPTIONS: H:3 toc:t num:t \\n:nil ::t |:t ^:{} -:t f:t *:t tex:t d:t tags:not-in-toc \n" "#+PROPERTY: header-args :mkdirp yes \n" "#+HTML_HEAD_EXTRA: <style type=\"text/css\"> blockquote {background:#EEEEEE; padding: 3px 13px} </style> \n" "#+HTML_HEAD_EXTRA: <style type=\"text/css\"> pre {background:#EEEEEE; padding: 3px 13px} </style> \n" "#+LATEX_HEADER: \\usepackage[backend=biber, bibencoding=utf8 ]{biblatex}\n" "#+LATEX_HEADER: \\usepackage{verbatim}\n" "#+LATEX_HEADER: \\usepackage{minted}\n" "#+LATEX_HEADER: \\hypersetup{colorlinks=true}\n" "#+LATEX_HEADER: \\addbibresource{" my-project-root "bibliography/bibliography.bib}\n" "#+BEGIN_EXPORT latex \n" "% from: https://github.com/SublimeText/LaTeXTools/issues/657#issuecomment-188188632 \n" "\\renewcommand{\\MintedPygmentize}{/usr/bin/pygmentize} \n" "\\definecolor{bg}{rgb}{0.95,0.95,0.95} \n" "\\setminted{bgcolor=bg} \n" "\\setminted{fontsize=\\footnotesize} \n" "\\setminted{breaklines} \n" "\\setminted{breakautoindent=false} \n" "\\setminted{mathescape} \n" "\\setminted{xleftmargin=0pt} \n" "#+END_EXPORT \n" ) #+END_SRC
- The
Bibliography()
command
The
#+CALL: Bibliography()
has to be set where you want to insert your bilbliography (see: file:example/example.org).#+NAME: Bibliography #+BEGIN_SRC emacs-lisp :results drawer (concat "#+BEGIN_EXPORT latex\n\\printbibliography\n" "\\begin{comment}\n#+END_EXPORT\n" "bibliography:" my-project-root "bibliography/bibliography.bib\n" "#+BEGIN_EXPORT latex\n\\end{comment}\n#+END_EXPORT\n") #+END_SRC
- Automatic Home/Up
This one took me some time and I still do not understand why I must use relative path for links
#+NAME: HomeUp #+BEGIN_SRC emacs-lisp :results drawer (let* ((my-project-root (expand-file-name (car (project-roots (project-current))))) (my-buffer-dir (expand-file-name (file-name-directory buffer-file-name))) (my-up (expand-file-name (concat my-buffer-dir "../index.org"))) (my-home (expand-file-name (concat my-project-root "index.org"))) (my-can-go-up (string< my-project-root my-buffer-dir)) ) (concat "#+begin_export latex\n\\begin{comment}\n#+end_export\n" (if (file-exists-p my-home) (format "[[file:%s][*HOME*]] " (file-relative-name my-home my-buffer-dir))) (if (and my-can-go-up (file-exists-p my-up)) (format "[[file:%s][*UP*]] " (file-relative-name my-up my-buffer-dir))) "\n#+begin_export latex\n\\end{comment}\n#+end_export\n" ) ) #+END_SRC
3.2.2 setup/setup.el
This file contains code executed by the my-new-project-configuration
function. At this point there is only one variable my-project-root
containing the project root.
- Configuration message
Print a message
;; Configuration message (message (format "Configuring %s" my-project-root))
- Use
minted
for listings
See
Setup()
;; use =minted= for listings (setq org-latex-listings 'minted)
- Load
library-of-babel.org
<-;; Load =library-of-babel.org= (org-babel-lob-ingest (concat my-project-root "setup/library-of-babel.org"))
See:
library-of-babel.org
org-publish-project-alist
definition
The first task is to define how to publish the project:
;; =org-publish-project-alist= definition (setq my-publish-dir (concat my-project-root "docs")) (defun my-org-publish-sitemap (title list) "Create my own index.org instead of the default one" (concat "#+CALL: Setup()\n" "#+INCLUDE: \"setup/index_preamble.org\"\n" "#+OPTIONS: toc:nil\n\n" "* My Sitemap\n\n" (org-list-to-org list) "\n\n")) (setq org-publish-project-alist `( ("My_Project_Name-org-files", :base-directory ,my-project-root :base-extension "org" :recursive t :publishing-directory ,my-publish-dir :publishing-function org-html-publish-to-html :sitemap-function my-org-publish-sitemap :htmlize-source t :sitemap-sort-files anti-chronologically :exclude "setup/*\\|docs/*\\|subprojects/*" ;; Generates theindex.org + inc files :makeindex t ;; Creates index.org, calls my-org-publish-sitemap to fill it :auto-sitemap t :sitemap-filename "index.org" ) ("My_Project_Name-data-files", :base-directory ,my-project-root :base-extension "nb\\|?pp\\|png" :recursive t :publishing-directory ,my-publish-dir :publishing-function org-publish-attachment :exclude "setup/*\\|docs/*\\|subprojects/*" ) ;; Main ("My_Project_Name", :components ("My_Project_Name-org-files" "My_Project_Name-data-files") ) ) )
- Feed
org-agenda-files
with org files
Then we use the
find
command to feed theorg-agenda-files
variable:(setq org-agenda-files (split-string (shell-command-to-string (format "find \"$(cd %s; pwd)\" -name '*.org' ! -name 'index.org' ! -name 'agenda.org' ! -name '.#*' ! -path './setup/*'" my-project-root) )))
- Some captures with their files
CAVEAT: these files, "www_links.org", "journal.org", "todo.org" must exist.
(setq my-www-links-filename (concat my-project-root "www_links.org")) (setq my-journal-filename (concat my-project-root "journal.org")) (setq my-todo-filename (concat my-project-root "todo.org")) (setq-default org-display-custom-times t) (setq org-time-stamp-custom-formats '("<%a %b %e %Y>" . "<%a %b %e %Y %H:%M>")) (setq org-capture-templates `( ("A" "Agenda/Meeting" entry (file+headline "~/GitLab/PVBibliography/agenda.org" "Agenda") "* %^{Title?} %^G\n:PROPERTIES:\n:Created: %U\n:END:\n\n%?" :empty-lines 1 :create t ) ("K" "Log Time" entry (file+datetree "~/GitLab/PVBibliography/activity.org" "Activity") "* %U - %^{Activity} :TIME:" ) ;;---------------- ("t" "Todo" entry (file+olp+datetree ,my-todo-filename) "* TODO %^{Title?} [/] %^G\n:PROPERTIES:\n:Created: %U\n:END:\n\n - [ ] %?" :empty-lines 1 :create t ) ("T" "Todo with file link" entry (file+olp+datetree ,my-todo-filename) "* TODO %^{Title|%f} [/] %^G\n:PROPERTIES:\n:Created: %U\n:END:\n\nBack link: %a\n\n#+BEGIN_QUOTE\n%i\n#+END_QUOTE\n\n - [ ] %?" :empty-lines 1 :create t ) ("j" "Journal" entry (file+olp+datetree ,my-journal-filename) "* %^{Title} %^G\n\n%?" :empty-lines 1 :create t ) ("J" "Journal with file link" entry (file+olp+datetree ,my-journal-filename) "* %^{Title|%f} %^G\n\nBack link: %a\n\n#+BEGIN_QUOTE\n%i\n#+END_QUOTE\n\n%?" :empty-lines 1 :create t ) ;; ;; See: https://github.com/sprig/org-capture-extension for further details ;; ("L" "Protocol Link" entry (file ,my-www-links-filename) "* [[%:link][%(transform-square-brackets-to-round-ones \"%:description\")]] \ %^G\n:PROPERTIES:\n:Created: %U\n:END:\n\n%?" :empty-lines 1 :create t ) ("p" "Protocol" entry (file ,my-www-links-filename) "* [[%:link][%(transform-square-brackets-to-round-ones \"%:description\")]] \ %^G\n:PROPERTIES:\n:Created: %U\n:END:\n#+BEGIN_QUOTE\n%i\n#+END_QUOTE\n\n%?" :empty-lines 1 :create t ) ))
- org-ref configuration
(setq my-bibtex-filename (concat my-project-root "bibliography/bibliography.bib")) (if (file-exists-p my-bibtex-filename) ;; If bibliography.bib exists (setq reftex-default-bibliography `(,my-bibtex-filename) bibtex-completion-notes-extension "-notes.org" bibtex-completion-notes-template-multiple-files "#+CALL: Setup()\n#+TITLE: ${author-or-editor} (${year}): ${title}\n\n* Personal Notes\n :PROPERTIES:\n :NOTER_DOCUMENT: ~/AnnotatedPDF/${=key=}.pdf\n :END:\n\n[[file:~/AnnotatedPDF/${=key=}.pdf][${title}]]\n" bibtex-completion-bibliography my-bibtex-filename bibtex-completion-library-path (file-name-directory my-bibtex-filename) bibtex-completion-notes-path (file-name-directory my-bibtex-filename) org-ref-default-bibliography `(,my-bibtex-filename) org-ref-pdf-directory (file-name-directory my-bibtex-filename) ) ;; otherwise unbound meaningless my-bibtex-filename (makunbound 'my-bibtex-filename) )
- PDF generation
;; defines how to generate the pdf file using lualatex + biber (setq org-latex-pdf-process '("lualatex -shell-escape -interaction nonstopmode -output-directory %o %f" "biber %b" "lualatex -shell-escape -interaction nonstopmode -output-directory %o %f" "lualatex -shell-escape -interaction nonstopmode -output-directory %o %f"))
3.2.3 setup/index_preamble.org
This is file included in sitemap.org. Note: no need for Setup()
,
it is already declared in the template.
#+TITLE: My_Project_Name # add what you want
3.3 bibliography/
This directory contains the bibliography.bib
file.
3.3.1 bibliography.bib
To be used as example here is our bibliography.bib
example file. I
found convenient to provide a directory and not only the
bibliography.bib
as I can annotate my reference here.
@book{dominik16_org_mode_ref_manual, author = {Dominik, C.}, title = {ORG MODE 9 REF MANUAL}, year = 2016, publisher = {ARTPOWER International PUB}, isbn = 9789888406852, } @Book{lewis00_gnu_emacs_lisp, author = {Lewis, Bil}, title = {The GNU Emacs Lisp reference manual : for Emacs Version 21, Revision 2.6, May 2000}, year = 2000, publisher = {Free Software Foundation}, address = {Boston, MA}, isbn = {978-1882114733}, }
3.4 example/
3.4.1 example/example.org
This is a page demo to check it works.
- File header
To be properly configured the org mode file can begin as follows:
#+CALL: Setup() #+TITLE: One example file #+CALL: HomeUp()
For explanations: https://emacs.stackexchange.com/q/58633/13563.
[ ]
another possibility is to use yasnippet
- Equation example
Check if equations are processed with mathjax
* An equation Do GitHub pages support equation rendering? \begin{equation*} \int \cos{x} dx = \sin{x} \end{equation*}
- A figure example
* A figure example file:./figures/sg_d1.png
- Code block example
We then add a code block to see that background is gray colored
* A code block example #+BEGIN_SRC cpp #include <iostream> int main() { std::cout << "Hello world!" << std:endl; return 0; } #+END_SRC
- Bibliographic reference example
* A bibliographic reference Test bibliography: cite:lewis00_gnu_emacs_lisp * Another section # put the bibliography here #+CALL: Bibliography()