Skip to content

vincent-picaud/Project-Template-For-OrgMode

Repository files navigation

Org Emacs Project Template

Table of contents

What is it?

Defines a create_orgMode_project bash script to quickly generate an OrgMode project structure.

createOrgProject MyProject

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

Quick starter

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

Required packages

(require 'project)
(require 'org-ref)
(require 'htmlize)

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.

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.

Project structure

project root

Create files at project root

theindex_org

This file includes the generated index

#+CALL: Setup()
#+TITLE: Index
#+CALL: HomeUp()


#+INCLUDE: "theindex.inc"

todo.org

#+CALL: Setup()
#+TITLE: TODO list 
#+CALL: HomeUp()

journal.org

#+CALL: Setup()
#+TITLE: Journal
#+CALL: HomeUp()

www_links.org

#+CALL: Setup()
#+TITLE: External web links
#+CALL: HomeUp()

setup/

This directory contains the configuration files.

setup/library-of-babel.org

This file contains function definitions, that are loaded with =org-babel-lob-ingest=.

The Setup() command

[2020-05-23 Sat 12:07] <- Use minted for listings

The #+CALL: Setup() has to be set at the beginning of your org file (see: 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: 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

Export complete listing

<<setup/library-of-babel.org>>

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.

Use minted for listings

See =Setup()=

;; use =minted= for listings
(setq org-latex-listings 'minted)

Load library-of-babel.org

[2020-05-23 Sat 12:23] <- =setup/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 the org-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"))

Configuration message

Print a message

;; Configuration message
(message (format "Configuring %s" my-project-root))

Export complete file

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

bibliography/

This directory contains the =bibliography.bib= file.

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},
}

example/

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()

The complete example.org file

create_orgMode_project script

About

A project template generator I use for all projects I have to work on

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published