Thunderbird shortcuts

posted Feb 8, 2019, 1:48 PM by Juan Jose Garcia-Ripoll

Mozilla Thunderbird
Thunderbird is a commonly used mail client that works on many platforms. It is a bit heavy and requires quite a lot of mouse use, as many graphical programs nowadays, but you can configure it to work better with a few keystrokes.

In order to follow these steps, please download first the add-on Dorando-keyconfig You can then configure Dorando with keybindings, adding the ones you find more suitable, and renaming the ones that are less standard. I list below the ones I use and change, just to remember that in my own machines.
  1. Navigate messages in a 'vim' fashion. You can reassign the "Previous > Message" or "Next > Message" to K and J, so that Thunderbird behaves just like vimium on Firefox.
  2. Zoom in and out conversations. I assign '+' and '-' to 'Conversation > Expand...' and 'Conversation > Contract'.
  3. Jump to specific folders. Right-click on the folder you want to use to find out its URI, the unique identifier or address that is used to find it. Then create a new keybinding with a code like the following one.
    var uri="imap://**the address of your folder**"
    for (i in gFolderTreeView._enumerateFolders) {
      var folder = gFolderTreeView._enumerateFolders[i]
      if (folder.URI==uri) {

  4. Archive email to specific folder. Find the URI of the destination folder and assign the following Javascript to the code you desire.
    MsgMoveMessage(MailUtils.getFolderForURI("imap://***@***/**URI to your folder**"))

  5. Save all attachments. Assign the following Javascript to Ctrl+Shift+S to save all the attachments in an email. It will open a dialogue to find a folder

Launch Jupyter notebooks automatically in Windows

posted Jan 26, 2019, 1:08 PM by Juan Jose Garcia-Ripoll   [ updated Jan 26, 2019, 1:09 PM ]

In latest editions of Anaconda, the installation wisely hides Python from the global path, but this also means that there are no good file associations for Python files or Jupyter notebooks.

One solution out there is nbopen. This utility launches one server and tries to reuse it with further notebooks. I have tried in the past, but it does not work if you want to work with notebooks in multiple directories. Somehow the tight permissions of Jupyter forbid it to access directories that are not inside the folder where it was initially started.

The only alternative that I have found is to build my own AutoHotKey script, which I can associate to *.ipynb files. This post documents how to do it. I assume that you have installed Miniconda for your own user and that the installation is located under %USERPROFILE%\Miniconda3
  1. Install AutoHotKey, a wonderful extension to map keys and build general scripts for Windows.
  2. Create and save the following script as start-jupyter-notebook.ahk
    EnvGet, home, USERPROFILE
    EnvGet, windir, windir
    If (%0% > 0) {
        loop, %1%
        file = %A_LoopFileFullPath%
        SplitPath, file, filename, directory
        filename := """" filename """"
    } Else {
        file := ""
        directory := home
    miniconda := home "\Miniconda3"
    activate  := miniconda "\Scripts\activate.bat"
    command   := activate " " miniconda " && echo Working at directory && cd && jupyter notebook " filename
    Run, %windir%\system32\cmd.exe /c "%command%", %directory%, min

  3. Run the AutoHotKey compiler to convert it into an executable. I like to associate it with the Jupyter notebooks icon because then this icon is used by File Explorer. I call the executable "Open with Jupyter.exe" because it looks nice when I install it in the Start pane. The command line below one single line, sorry if it looks garbled:
    "%ProgramFiles%\AutoHotkey\Compiler\Ahk2Exe.exe" /in start-jupyter-notebook.ahk /out "Open with Jupyter.exe" /icon %USERPROFILE%\Miniconda3\Menu\jupyter.ico

  4. Open the properties for any Jupyter notebook (Right-click and select Properties) and click on "Change" to select the program that opens the notebooks. You may need to select "More programs" and use the explorer to find your compiled script.
The script will launch one server every time it is invoked. You can open futher files from within Jupyter using File -> Open in the Jupyter notebook menu.

When you are done, you can either kill the command line window with the Jupyter notebook or quit the server from the browser. For the latter, use File -> Open to open the Jupyter file browser and then click on Quit. You can then safely close all browser tabs.

A CSS stylesheet for exporting org-mode files

posted Apr 29, 2018, 1:49 PM by Juan Jose Garcia-Ripoll   [ updated Apr 30, 2018, 2:17 AM ]

I have been writing a big document using org-mode, exporting it to HTML and using the browser to generate a PDF from it. It looks pretty nice, similar to what I achieved with Word on an earlier version, and faster to write.

 * CSS for org-mode document. Save with name style.css and include with
 * #+HTML_HEAD: <link rel="stylesheet" type="text/css" href="style.css" />
 * It should be placed on the same directory as the HTML that is exported.
 * Print options

@page {
    margin: 2.54cm;
    size: A4;
    /* Page numbers, does not really work on most browsers. */
    @bottom-right {
        padding-right: 20px;
        content: "Page " counter(page);

@media print {
    body {
        font-size: 11pt;
    h2, h3, h4, h5 {
        page-break-after: avoid;
    #table-of-contents {
        /* Page break after table of contents */
        page-break-after: always;
        margin-top: 2em;
        line-height: 1.5em;
        width: 80%;
        height: 40%;
        margin: auto auto;
    #table-of-contents > h2 {
        text-align: center;
        margin-top: 4em;
    .figure {
        /* Figure stays together with caption */
        page-break-inside: avoid;

 * For ordinary browsing
@media screen {
    footer {
        display: none;
    body {
        font-size: 12pt;
        margin-left: 2em;
        margin-right: 2em;
        max-width: 50em;
    #table-of-contents {
        margin-top: 2em;

 * Common format
body {
    font-family: Calibri;
    line-height: 1.2;

h1, h2, h3, h4, h5, h6 {
    margin-top: 0;
    margin-bottom: 6pt;

h2 {
    font-size: 1.3;
    text-transform: uppercase;

h1 {
    font-size: 1.6;
    font-variant: small-caps;

p {
    text-align: justify;

.figure > p {
    font-style: italic;

a:link, a:visited {
    text-decoration: none;
} {
    text-align: left;

/* Mark external links with an icon. */
a[href^="https://"]:after {
    content: '\2021'; /*'\1F5D7';*/
    font-style: roman;

A sample file would be:
#+TITLE: Sample org file
#+STARTUP: inlineimages
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="style.css" />

* First heading
* Second heading
** Subheading 1
** Subheading 2

#+caption: Some fancy figure
#+attr_html: :width 50%

The file can be simply exported using Ctrl-c Ctrl-e and then pressing 'h' followed by 'o' (HTML and Open in browser). Afterwards, printing can be done from the browser.

Edit: an example with output PDF is attached to this page.

Hope this is useful for you.

My .emacs configuration

posted Apr 9, 2018, 10:46 AM by Juan Jose Garcia-Ripoll   [ updated Apr 9, 2018, 1:06 PM ]

In case you like peeking into other people's configuration file or learn how to configure Emacs in Windows, here is my last set of settings.

Note: this relies on a personal fork of shackle to have LaTeX pop-up windows be automatically closed when they are no longer used (AucTeX kills the buffer with errors but shackle does not close the window which showed the errors)
;;; -*- mode: emacs-lisp; -*-
;;; Different computers have different customizations due to
;;; monitor screen sizes, resolutions, etc.
(defun tic (&optional n)
  (print (list n (get-internal-run-time))))

;;; All our files will be located under a Dropbox common folder
;;; whose location may shift between computers. Also, fonts
;;; screen resolutions, etc, may vary.
(setq dropbox "~/Dropbox/Library/")
(setq dropbox-elpa "~/Dropbox/Library/Emacs/elpa-25")
(cond ((string= system-name "DEUTSCH")
       (setq juanjo:text-font-family "Noto Serif"
	     juanjo:text-font-height 110
	     juanjo:text-line-spacing 0.3
	     juanjo:margin 2))
      ((string= system-name "DESKTOP-HDKKLFG")
       (setq juanjo:text-font-height 140
	     juanjo:text-font-family "Vollkorn"
	     juanjo:text-line-spacing 0.0
	     juanjo:margin 1)
       (setq juanjo:text-font-family "Noto Serif"
	     juanjo:text-font-height 120
	     juanjo:text-line-spacing 0.3
	     juanjo:margin 2))
       (setq juanjo:text-font-family "DejaVu Serif"
	     juanjo:text-line-spacing 0.3
	     juanjo:text-font-height 110
	     juanjo:margin 1)))

(let ((custom-file (expand-file-name "dot.custom.el" dropbox)))
  (when (file-exists-p custom-file)
    (load custom-file)))

;;; Change to home directory. When using emacs.exe from Chocolatey,
;;; Emacs tends to start from the location of the shim executable.
(cd "~/")

(require 'package)
(setq package-user-dir dropbox-elpa)
(add-to-list 'package-archives '("melpa" . ""))
(add-to-list 'package-archives '("melpa-stable" . ""))
;;(package-refresh-contents t)

;;; Lazy package management with postponed initialization, automatic
;;; installation of those packages.
(unless (package-installed-p 'use-package)
  (package-install 'use-package))
(require 'use-package)

;;; Persistence

;; Remember from session to session all the commands introduced
;; in the minibuffer, files opened, etc.
(setq savehist-file (expand-file-name "Emacs/dot.history" dropbox))
(savehist-mode 1)

;;; Emacs quirks

;;; Do not use tabs when editing files
(setq-default indent-tabs-mode nil)
(setq tab-width 4)

;;; Make tabs indent first, then complete
(setq-default tab-always-indent 'complete)

;;; Remove yes-or-no questions, defaulting to single-keystroke
(fset 'yes-or-no-p 'y-or-n-p)

;;; Remove text from *scratch* buffer
(setq initial-scratch-message nil)

;;; Do not disable commands
(setq disabled-command-function nil)
;;(put 'downcase-region 'disabled nil)
;;(put 'scroll-left 'disabled nil)

;; Visual appearance:
;; My preferred fonts for text and coding. I store them
;; as variables because they are used in buffer-local
;; customizations.
(setq code-face '(:family "Source Code Pro" :foundry "outline"
			  :slant normal :weight normal :height 98 :width normal)
      text-face `(:family ,juanjo:text-font-family :foundry "outline"
			  :slant normal :weight normal
			  :height ,juanjo:text-font-height :width normal)
      bold-text-face (plist-put (copy-sequence text-face) :weight 'bold))
(apply 'set-face-attribute 'default nil code-face)
;; Darker background, softer coloring
(load "~/Dropbox/Library/Emacs/mycarthy-theme.el")
(load-theme 'mycarthy)
;; No blinking cursor
(blink-cursor-mode -1)
;; No fringe bars on both sides
(fringe-mode 0)
;; No continuation character on truncate-line mode
(set-display-table-slot standard-display-table 0 ?\ )

;;; Text editing with proportional fonts, good interline spacing
;;; and window margins.
(defun juanjo:text-mode-hooks ()
  ;; Some more spacing between lines
  (setq-local line-spacing juanjo:text-line-spacing)
  ;; Wrap around words
  (visual-line-mode +1)
  ;; Text modes should have proportional fonts
  (buffer-face-set text-face)
  (setq left-margin-width juanjo:margin
	right-margin-width juanjo:margin)
(add-hook 'text-mode-hook 'juanjo:text-mode-hooks)

;; Placement of windows
(use-package shackle
  :load-path "~/Dropbox/Library/Emacs/local/shackle/"
  :commands shackle-mode
  (setq shackle-rules
	'(("\\*TeX.*\\*" :regexp t :autoclose t :align below :size 10)
	  ("\\*.*Help\\*" :regexp t :autoclose t :align below :size 10)))
  (setq shackle-default-rule '(:select t)))


;;; My convenience bindings

;;; Delete whole buffer
(defun mps-clear-all ()
  (delete-region (point-min) (line-end-position 0)))
(global-set-key [?\C-x ?\C-u] 'mps-clear-all)

;; (add-to-list 'load-path (concat dropbox "Emacs/fakecygpty/"))
;; (require 'fakecygpty)
;; (fakecygpty-activate)
;; (setq fakecygpty-ignored-program-regexps '("[cC][mM][dD]" "[cC][mM][dD][pP][rR][oO][xX][yY]"))
;; ;; We need to force using fakecygpty with tramp
;; (eval-after-load "tramp"
;;     '(progn
;;        (add-to-list 'tramp-methods
;;                     (mapcar
;;                      (lambda (x)
;;                        (cond
;;                         ((equal x "sshx") "cygssh")
;;                         ((eq (car x) 'tramp-login-program)
;; 			 (list 'tramp-login-program "fakecygpty ssh"))
;;                         (t x)))
;;                      (assoc "sshx" tramp-methods)))
;;        (setq tramp-default-method "cygssh")))

;;; LaTeX with AucTeX

;; TeXcount setup for TeXcount version 2.3 and later
(defun juanjo:texcount ()
    ((this-file (buffer-file-name))
     (enc-str (symbol-name buffer-file-coding-system))
       ((string-match "utf-8" enc-str) "-utf8")
       ((string-match "latin" enc-str) "-latin1")
      ;; Windows screwes this for me
      (append '("LANG=") process-environment))
	(with-current-buffer standard-output
	  (call-process "texcount" nil t nil "-0" enc-opt this-file))))
    (message word-count)

(use-package latex
  :defer t
  :mode ("\\.tex\\'" . latex-mode)
  (:map LaTeX-mode-map
	("C-c l" . TeX-error-overview)
        ("C-c w" . juanjo:textcount))

  ;; Minor changes to the LaTeX mode
  (add-hook 'LaTeX-mode-hook 'juanjo:latex-hooks)
  (add-hook 'LaTeX-mode-hook 'turn-on-reftex)
  (add-hook 'LaTeX-mode-hook 'juanjo:latex-hooks)
  (add-hook 'LaTeX-mode-hook 'flyspell-mode)

  (setq TeX-PDF-mode t
	TeX-save-query nil
	TeX-source-correlate-mode t
	TeX-source-correlate-method 'synctex
	;; Tell SumatraPDF to open the current PDF file, indicating
	;; which is the source file and line number (used by synctex)
	;; and provide a valid command line to edit at the desired
	;; location of a source file that is linked in the PDF.
	'(("Sumatra PDF"
	   ("\"SumatraPDF.exe\" -reuse-instance "
	    "-inverse-search \"emacsclientw.exe +%%l \\\"%%f\\\"\" "
	    (mode-io-correlate " -forward-search %a %n ")
	    " %o")))
	'(((output-dvi style-pstricks) "dvips and start")
	  (output-dvi "Yap")
	  (output-pdf "Sumatra PDF")
	  (output-html "start"))
	;; Open TeX error list after compilation
	;; and show all warnings
	TeX-error-overview-open-after-TeX-run t
	TeX-debug-warnings t)
  ;; Replace viewer with SumatraPDF
  (assq-delete-all 'output-pdf TeX-view-program-selection)
  (add-to-list 'TeX-view-program-selection
	       '(output-pdf "Sumatra PDF"))

  ) ; use-package latex

;; Hook into font-latex to reduce the size of some section,
;; chapter, subscript and superscript fonts
(use-package font-latex
  :defer t
  (set-face-attribute 'font-latex-subscript-face nil :height 0.6)
  (set-face-attribute 'font-latex-superscript-face nil :height 0.6)
  ;; I do not like large fonts for the sections, chapters, etc
  (let ((height (round (* 1.1 juanjo:text-font-height))))
    (dolist (face '(font-latex-sectioning-0-face
      (apply 'set-face-attribute face nil
	     (plist-put (copy-sequence bold-text-face)
			:height height))))

(use-package reftex
  :defer t
  :commands turn-on-reftex
  (setq reftex-plug-into-AUCTeX t
	;; RefTeX list of sections, labels and figures shows as
	;; vertical bar to the left of the window.
	reftex-toc-split-windows-horizontally t
	;; RefTeX table of contents does not indicate which
	;; sections are in which files.
	reftex-toc-include-file-boundaries nil))

(use-package latex-extra
  :defer t
  :ensure t
  :commands latex-extra-mode
  (:map LaTeX-mode-map 
	("M-" . latex/next-section-same-level)
	("M-" . latex/previous-section-same-level))
  (add-hook 'LaTeX-mode-hook (lambda () (latex-extra-mode) (auto-fill-mode -1)))
  ;; Do not override AucTex's font commands
  (setq latex/override-font-map nil))

(defun delatexify ()
    (goto-char 0)
    (replace-string "{\'\i}" "í")
    (replace-string "\\'o" "ó")
    (replace-string "\\'a" "á")
    (replace-string "\\'e" "é")
    (replace-string "\\'u" "ú")
    (replace-string "\\\"a" "ä")
    (replace-string "\\\"o" "ö")))

(defun juanjo:html-mode-hooks()
  ;; Wrap around words
  (visual-line-mode +1)
  ;; Text modes should have proportional fonts
  (buffer-face-set code-face))

(add-hook 'html-mode-hook 'juanjo:html-mode-hooks)

;; Dictionaries, languages and encodings
;; Use hunspell.exe for automatic spell checking. Available
;; from Chocolately as choco install hunspell
(use-package flyspell
  :defer t
  (("" . ispell-word)
   ("C-S-" . flyspell-mode)
   ("C-M-" . flyspell-buffer)
   ("C-" . flyspell-check-previous-highlighted-word)
   ("M-" . flyspell-check-next-highlighted-word))
  (setenv "DICTPATH" "c:\\ProgramData\\chocolatey\\lib\\hunspell.portable\\tools\\share\\hunspell\\")
  (setenv "DICTIONARY" "c:\\ProgramData\\chocolatey\\lib\\hunspell.portable\\tools\\bin\\..\\share\\hunspell\\en_US")
  (setq ispell-program-name "c:\\ProgramData\\chocolatey\\bin\\hunspell.exe"
	;; Save dictionary in common location
	ispell-extra-args `("-p" ,(expand-file-name "hunspell" dropbox))
	;; Save dictionary without asking
	ispell-silently-savep t
	;; Do not issue warnings for all wrong words
	flyspell-issue-message-flag nil)

  (defun flyspell-check-next-highlighted-word ()
    "Custom function to spell check next highlighted word"

  (ispell-change-dictionary "en_US" t)

  ) ; use-package flyspell

;;; Encoding for everything
(prefer-coding-system 'utf-8-unix)

;;; Convenience keybindings for Greek letters
  (global-set-key (kbd "C-x C-g a") "α")
  (global-set-key (kbd "C-x C-g b") "β")
  (global-set-key (kbd "C-x C-g g") "γ")
  (global-set-key (kbd "C-x C-g d") "δ")
  (global-set-key (kbd "C-x C-g ep") "ε")
  (global-set-key (kbd "C-x C-g z") "ζ")
  (global-set-key (kbd "C-x C-g et") "η")
  (global-set-key (kbd "C-x C-g Th") "θ")
  (global-set-key (kbd "C-x C-g i") "ι")
  (global-set-key (kbd "C-x C-g í") "ί")
  (global-set-key (kbd "C-x C-g k") "κ")
  (global-set-key (kbd "C-x C-g l") "λ")
  (global-set-key (kbd "C-x C-g m") "μ")
  (global-set-key (kbd "C-x C-g n") "ν")
  (global-set-key (kbd "C-x C-g xi") "ξ")
  (global-set-key (kbd "C-x C-g o") "ο")
  (global-set-key (kbd "C-x C-g ó") "ό")
  (global-set-key (kbd "C-x C-g pi") "π")
  (global-set-key (kbd "C-x C-g r") "ρ")
  (global-set-key (kbd "C-x C-g fs") "ς")
  (global-set-key (kbd "C-x C-g s") "σ")
  (global-set-key (kbd "C-x C-g t") "τ")
  (global-set-key (kbd "C-x C-g y") "υ")
  (global-set-key (kbd "C-x C-g ý") "ύ")
  (global-set-key (kbd "C-x C-g ph") "φ")
  (global-set-key (kbd "C-x C-g chi") "φ")
  (global-set-key (kbd "C-x C-g ps") "ψ")
  (global-set-key (kbd "C-x C-g w") "ω"))

;; Windows and unix-like shells
(defun cygwin-shell ()
  "Run cygwin bash in shell mode."
  (let ((explicit-shell-file-name "bash")
	(explicit-bash-args '("-i")))
    (call-interactively 'shell)))

(defun wunix-shell ()
  "Run Windows' bash in shell mode."
  (let ((explicit-shell-file-name "cmd.exe")
	(explicit-cmd.exe-args '("/C" "c:\\Windows\\WinSxS\\amd64_microsoft-windows-lxss-bash_31bf3856ad364e35_10.0.16299.15_none_62878a822db68b25\\bash.exe" "-i")))
    (call-interactively 'shell)))

(defun visual-studio-2017-x84-shell ()
  "Run Windows shell with Visual Studio environment."
  (let ((explicit-shell-file-name "cmd.exe")
	(explicit-cmd.exe-args '("/k" "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat")))

(setq tramp-default-method "ssh")

(defun browser-sync ()
  "Starts a browser-sync script if it exists in this directory"
  (start-process "browser-sync" "*browser-sync*" (expand-file-name "debug.cmd")))

;; Email, web and other services

(use-package wunderlist
  :defer t
  (setq wl-folders-file "~/Dropbox/Library/dot.folders"

        ;; SMTP server for mail posting. Default: nil
        wl-smtp-posting-server ""
        wl-smtp-posting-port 465
        wl-smtp-posting-user "xxxxx"
        wl-smtp-authenticate-type "plain"
        wl-smtp-connection-type 'ssl
        wl-from ""
        smtp-fqdn ""

        elmo-imap4-default-user "xxxxx"
        elmo-imap4-default-server ""
        elmo-imap4-default-port 993
        elmo-imap4-default-authenticate-type 'clear
        elmo-imap4-default-stream-type 'ssl

        ;; Location of archives
        elmo-archive-folder-path "~/Dropbox/Mail/"

        ;; Location of MH and Maildir folders
        elmo-localdir-folder-path "~/Dropbox/Mail/"
        elmo-maildir-folder-path "~/Dropbox/Mail/"

        wl-message-id-domain ""
        wl-from "Juan Jose Garcia-Ripoll "

        wl-stay-folder-window t
        wl-folder-window-width 25
        wl-folder-use-frame nil

        wl-message-ignored-field-list '("^.*")
        wl-message-visible-field-list '("^From:" "^To:" "^Cc:" "^Date:" "^Subject:")
        wl-message-sort-field-list wl-message-visible-field-list
        wl-summary-default-sort-spec 'date
        wl-message-window-size '(1 . 3)

  (if (boundp 'mail-user-agent)
      (setq mail-user-agent 'wl-user-agent))
  (if (fboundp 'define-mail-user-agent)

  ) ; use-package wunderlist

;;; Auto completion with IDO

(use-package ido
  :ensure t
  :init  (setq ido-enable-flex-matching t
               ido-ignore-extensions t
               ido-use-virtual-buffers t
               ido-everywhere t)
  (ido-mode 1)
  (ido-everywhere 1)
  (add-to-list 'completion-ignored-extensions ".pyc"))

(use-package flx-ido
   :ensure t
   :init (setq ido-enable-flex-matching t
               ido-use-faces nil)
   :config (flx-ido-mode 1))

;;; Version control

(use-package magit
  :defer t
  :ensure t

Custom skin for Jupyter notebooks

posted Apr 4, 2018, 7:28 AM by Juan Jose Garcia-Ripoll   [ updated Apr 4, 2018, 7:29 AM ]

This is going to be a brief entry. Essentially: I have reading problems, which together with the strain induced by bad quality monitors (wish all were as good as the tiny screen of my Surface Pro), force me to look for ways to improve the quality of text I have to read on screen.

One problem for me as of late are Jupyter notebooks. Their default look in Windows involves narrow lines, bright background and sometimes too broad coding fonts, plus wasted space around prompts, line numbers, etc.

Fortunately, it seems you can customize the look of notebooks by touching one file. Follow these steps:
  1. Guess the location of Jupyter's configuration. For that open a command line and type jupyter --config-dir That should output a directory such as E:\home\JuanJose\.jupyter
  2. Create a file in that directory. More precisely, for my example, it will be E:\home\JuanJose\.jupyter\custom\custom.css
  3. Enter some CSS styles in that file. I copy my own below.
The effects should be visible once you reload the notebook, even if a session is open.

 * Comment out the following line if you have installed
 * the following fonts:
 *   - Source Code Pro,
 *   - Vollkorn,
@import url('');
@import url('');
#notebook, div#notebook {
    font-family: 'Vollkorn', 'DejaVu Serif', 'Palatino Linotype', serif;
    font-size: 16px;
    line-height: 1.5;
h1,h2,h3,h4,h5,h6 {
    font-family: 'Palatino Linotype';
body {
    font-family: 'Verdana', 'Arial', sans-serif;
body, #notebook-container, body > #header, .btn-default {
    background-color: rgb(252,251,251);
li, .MathJax_Display {
    margin-bottom: 6px;
code, kbd, pre, samp, .CodeMirror {
    font-family: Source Code Pro;
    font-size: 12px;
pre {
    font-size: 11px;
.prompt {
    font-family: Arial;
    font-size: 11px;
    min-width: 6em;
.input-prompt {
    color: rgb(108, 119, 188);
.output-prompt {
    color: rgb(205, 129, 106);

Some screenshots of my new skin, with Windows Edge and Google Chrome. Windows Edge tends to increase the perceived weight of characters, which is not too bad in my case.

Converting Mathematica to Python

posted Sep 19, 2017, 3:46 AM by Juan Jose Garcia-Ripoll   [ updated Sep 19, 2017, 3:51 AM ]

I like Mathematica for working with symbolic expressions. I find that there are no free software alternatives that achieve its power in the tasks of solving complex integrals, working with limits, and helping me make sense of sophisticated differential equations. Until that is solved, I will find the need to export Mathematica expressions to other software that is more efficient on the numerical computing side. Or which simply does good plots in a less verbose way.

I have created a simple Mathematica notebook which you can download here (see attachment below). The notebook uses Mathematica's pattern matching to build a sophisticated parsing routine that converts Mathematica expressions to Python code.

See for instance the following examples which detect addition, division and exponentiation, and convert those to strings, either directly, or using wrappers that automate the case of binary operators and unitary expressions:

ToPython2[a_ - b_] := ToPythonOp["-", a, b]
ToPython2[a_/b_] := ToPythonOp["/", a, b]
ToPython2[a_^2] := "(" <> PythonWrap[a] <> "**2)"
ToPython2[a_^b_] := PythonWrap[ToPythonOp["**", a, b]]

The actual implementation makes use of ugly hacks, such as defining its own square root function (which accepts negative real arguments), or parenthesising more than needed, but it is fully functional and works nicely for my own purposes. For instance, the following complex Mathematica expression

is converted to 13 lines of Python code:


    def mysqrt(x): return np.sqrt((1.+0j)*x)


Ussing Cygwin's ssh-agent in Windows

posted Sep 29, 2016, 6:45 AM by Juan Jose Garcia-Ripoll   [ updated Oct 9, 2016, 3:40 AM ]

When you want to log in to a Unix machine or some other kind of server, one of the favourite protocols is SSH. In public key authentication, you can generate a pair of keys, a private one called id_rsa and a public one These keys are usually stored in your HOME directory, with sufficient permissions so that no one can read the private key.

Unfortunately this may not always be the case. I have had machines that have been hacked, or I sometimes like to store my private-public key pairs in some backup device which may be in a not too secure location (for instance Dropbox). Under those circumstances it is useful to store the private key with a password, the so called "passphrase". Then, whenever you want to log-in to another machine using SSH you only have to type the passphrase.

ssh-agent is a program that stores your public and private keys in memories. Using it, you only have to introduce the passphrase once at the beginning of your session. It is convenient, it works under Linux but Windows does not have it built in.

Step 1: install ssh and ssh-agent

Your first stop for these programs in Windows will be cygwin. Get it from I use the 64-bit version, which works fine enough. After installation I recommend the following two changes:
  1. Edit the PATH environment variable to include the directory c:/cygwin64 or c:/cygwin depending on the version you chose.
  2. Create a HOME environment variable pointing to your favorite directory. I normally rely on the Windows one %HOMEDRIVE%%HOMEPATH%
Both changes together have the nice side effect that you can use SSH from anywhere, including Windows terminals.

Step 2: Create your public and private keys

Open a terminal and type
ssh-keygen -t rsa
and enter a long password as your passphrase. The longer the better. I usually rely on stupid sentences, like "the cow jumped over the 27th wall street", which have no meaning but have enough entropy and are easy to remember.

Step 3: Ensure ssh-agent is run when you log in

Press Windows key + R (both keys simultaneously) and enter shell:startup This will open a folder where you can create programs that run at boot time. Click with the right button and create a new "Text document". Enter the following text and save it with the name "run-ssh-agent.cmd" Note the different extension!
@echo off
rem Start ssh-agent in the background. It will not be closed
start /b ssh-agent > %HOME%\.ssh-agent-env
echo We need to ask you the password with which the SSH key is encoded
echo After that we will update the environment variable so that you
echo do not need to enter it again
bash -c ". ~/.ssh-agent-env; setx SSH_AUTH_SOCK "$SSH_AUTH_SOCK"; setx SSH_AGENT_PID "$SSH_AGENT_PID"; ssh-add"

This step is quite critical because it is on charge of starting the agent that keeps the passwords in the background, decoding the SSH keys with the password you provide and notifying the whole of the system (via the environment variables SSH_AUTH_SOCK and SSH_AGENT_PID) that the SSH keys are available for use.

Step 4: Configure cygwin to use ssh-agent

Edit your profile file ~/.bash_profile and add the following lines at the end
if [ -z "$SSH_AUTH_SOCK" -a -x "$SSHAGENT" ]; then
    if test -f ~/.ssh-agent-env; then
eval `cat ~/.ssh-agent-env`
trap "kill $SSH_AGENT_PID" 0

Step 5: Optional - Configure Emacs to use cygwin SSH

This is tricky. The problem is that Cygwin's SSH expect to be run from a Cygwin or MS-DOS terminal and does not like to run from within Emacs. There is a simple solution for this, which involves installing a package called fakecygpty from github (

Step 6: Optional - Configure Emacs to use ssh-agent

I added the following function to my .emacs file (see here for configuration details) to read the location of ssh-agent and pass it to other functions, such as ssh or tramp.
(let ((filePath "~/.ssh-agent-env"))
    (insert-file-contents filePath)
    (let (ssh-auth-sock ssh-agent-pid)
      (and (progn
    (goto-char (point-min))
    (re-search-forward "SSH_AUTH_SOCK=\\([^;]*\\)" nil t))
  (setq ssh-auth-sock (match-string 1))
    (goto-char (point-min))
    (re-search-forward "SSH_AGENT_PID=\\([^;]*\\)" nil t))
  (setq ssh-agent-pid (match-string 1))
  (setenv "SSH_AUTH_SOCK" ssh-auth-sock)
  (setenv "SSH_AGENT_PID" ssh-agent-pid)))))

Hacking BibTeX

posted Sep 12, 2016, 6:52 AM by Juan Jose Garcia-Ripoll   [ updated Sep 12, 2016, 6:52 AM ]

I needed to use the Cambridge LaTeX style for books, which is very pretty and compact, but I wanted to produce PDF's where clicking on the title of articles or books would open a browser with that paper. See for example the blue text below, which links to the Physical Review A article

This is a trick that I used in my own thesis, as well as with other people's thesis as well. The trick is very simple. In this case I copied the cambridgeauthordate.bst file into cambridgeauthordateurl.bst and enlarged the list of allowed fields to include URL

  { address
  { label extra.label sort.label }

and then I edited the section that starts with FUNCTION { format.title ... so that it read

FUNCTION {format.title}
{ title empty$
    { "" }
    { URL empty$
      { title }
      { "\href{" URL * "}{" * title * "}" * }

Save the file and include it with \bibliographystyle{cambridgeauthordateurl} Notice how the sixth line simply concatenates, using the postfix operator *, five different strings into the final text that forms the title.

Extracting images from PDFs with Inkscape

posted Aug 30, 2016, 3:51 AM by Juan Jose Garcia-Ripoll   [ updated Aug 30, 2016, 3:55 AM ]

My work as a scientist and also as an occasional outreach communicator has put me in a situation where I need to extract graphical material from publications and other documents. The two alternatives I normally found were
  1. Go to a webpage and pray for a high-resolution image that can be used. In many journals this is rarely the case. Bandwidth considerations force the journals to place mediocre size pictures that are sometimes ok for presentations, unless you really use a good projector or a big screen. In most cases they are not ready for printed reproduction.
  2. Use the PDF of a publication and capture a screenshot. You would typically open the document in Acrobat, zooming in until the region you are interested in fills the screen, and then use the "screenshot" or "camera" icon to capture that region. This normally improves the quality of the resulting image, but it is still limited by the resolution of your screen!
I have rediscovered a third method that was probably invented by one of my PhD students. The idea is to open the PDF as if it was a drawing, using some vector graphic program, of which I recommend and detail Inkscape. This is a drawing program which is available for Windows, Mac and Linux, and which is very powerful -perhaps too powerful for many much simpler designs.

Recent versions of Inkscape can open a wide variety of formats, including PDFs. The workflow I would therefore suggest to you is the following one

  1. Open Inkscape and press Ctrl-O to open the PDF you want to work with. In the import window you should select "import via Poppler". Make also sure you select the page where the resource you wish to copy lives
  2. Once the page is imported, you can begin editing. Start by selecting "Ungroup" by clicking with the right button on top of the imported page. After this, all elements will be editable and you will be able to strip down the image to your desired minimum. Notice below how I deleted several portions of text.

  3. Finally, save the image in your desired format. I normally use SVG for archival and PDF to embed in other publications.
Two final remarks: First, make use you have the rights for a fair use of the image. I assume that in talks giving credit is enough, while in publications you would have to contact the journal. Second, beware of how you build images for your paper! This way of proceding can reveal hacks in your images, text that is underlying your original plots, etc. Just a warning. Curious PhD students may have a lot of fun with your work otherwise.

Focused work

posted Aug 8, 2016, 8:16 AM by Juan Jose Garcia-Ripoll   [ updated Aug 8, 2016, 8:29 AM ]

I must confess I have become a bit obsessed with the amount of distraction that I get at work. I am not talking about social media, but handling of multiple bureaucratic lines of action, competing for funding, taking care of people's projects, interaction with students, etc. This has been more damaging or at least more obvious in the light of specific projects that I wanted to accomplish, such as for instance, completing my lectures notes. As a kind of escape I have ended up reading quite a lot of self-help literature around organization and other ideas. What follows is an excerpt of the things I have found useful from various sources I do not remember or do not dare to cite. Well, maybe "Deep Work" by Cal Newport is an acceptable reference, specially due to its connection to academia, but in many other cases they were less respectable sources that, despite everybody's warning, still contained some bits of wisdom. Here they go in a very disorganized way. At the very least they will give you an idea of why I behave how I do in the last months.

General ideas

  • Acting by reacting: we work on an input-output based activity
    • We react to emails, which cause interruptions and change our workflow. Reacting immediately to email is a way of letting other people sort our priorities. Allocating email-only time and moving those tasks to a to-do list to be considered in the appropriate slots frees our time for our own priorities. This is an example in a broader category of problems that could be sorted out with minimal organization.
    • Allocating bureaucracy-first time causes a disruption of work because we are left in the busy mode of reacting to lists of tasks. The impact of this on creativity cannot be underrated. Decision fatigue is a real issue.
  • Choices:
    • Be more selective on the topics, tasks and projects you embark on. Measure cost of those projects, but do not be too short-sighted: some projects are long-term investments, while some others seem short-term wins but the load outweighs the rewards.
    • Clearly separate projects and tasks which originate outside from your own priorities. There are unavoidable things that have to be carried on for your own curriculum, job position, collaboration network, etc. Find stable slots of time that you allocate for those tasks and concentrate them in that area of your day.
    • Be clear about your priorities when interacting with other people. Casual commitments on your side may be taken as more serious collaborations that may complicate your life, or vice versa. Do not embark on more tasks or projects than you can handle or, as they say, do not bite more than you can safely swallow.
  • Strategies:
    • Find a personal time for your own projects, ideas, crafts, but above all, also for thinking and planning what you want to do. My personal ideal day based on may different guidelines
      • 8:00-8:30 Plan of the day. Minimal note-taking and revision of to-do lists, separating tasks in different time slots.
      • 8:30-10:00 Creative stuff. This is early time where most people and interruptions still did not have time to appear.
      • 10:00-10:30 Coffee and email. Answer if brief, sort out to other time-slots if possible.
      • 10:30-13:00 Bureaucracy and non-creative stuff. This is the time where you may get most interruptions, specially from administration.
      • 13:00-14:00 Lunch break.
      • 14:00-15:00 Work time.
      • 15:00-15:30 Email verification to gather reactions from previous period. Try to sort out task for further days. Do not answer emails today.
      • 16:00-17:30 Easy work time.
      • 17:30- Go home and disconnect.
    • Minimize the number of projects you work on simultaneously and ideally devote each day to a single project. Note that here I refer to projects as opposed to bureaucracy or externally induced tasks, which may be unfortunately more abundant. Define your day with the project you wanted to do, not with the 10:30-13:00 period above.
    • Decide each day what you want to do at the beginning of the day, not along the way. If possible, integrate that decision taking along or at the end of a well defined morning ritual, such as coffee, brief exercising, journalling, etc.
    • Minimize external inputs in the early part of the day, at least until the first email break. News checking, social networks, etc., all these things hijack your time and your willpower to structure the day decreases dramatically.
    • Try to be as predictable as possible, both for yourself and your coworkers. It is better if you constrain interaction and discussions to a certain part of the day, ideally from 10:30 to lunch time or at the end of the day. In the first case because it is already a period where interruptions are already frequent, and in the second case because productivity decreases along the day and discussions are usually less taxing than other tasks.
  • Avoid redundancies and interruptions:
    • Group similar tasks: have a paper or notepad to write down reactions that appear along your work, such as
      • Emails that have to be sent
      • Things to be delivered or picked up
      • Documents to print, read, etc
    • Delay those tasks to the appropriate time slots. For instance, if you are working on your projects and you realize it would be nice to send an email to somebody about the idea you just had, note it down on the to-do and continue working on your project.
    • Grouping is relevant because you may realize that many things are related. For instance, if you are writing a project that coordinates with different partners, you may want to ask them about certain bits of information. If you note down those questions, you may find that along the day similar questions pop up and you only have to send each partner one email, instead of one message for each question. Remember: email is not the same as chatting.
    • Grouping might also be useful in other parts of your leisure time: reading news, TV time, internet browsing, shopping, etc. For instance, it is better to have a time for scanning a few news sources than having Twitter + BBC News open all day on your desktop. Separate different activities clearly with small “rituals” like stretching, taking a coffee, walking, etc. Make the change more dramatic between work-time and leisure-time.
  • Be efficient in your communications: this is very important.
    • Ask precise questions, with suitable alternatives and anticipate reactions. Examples:
      • “Shall we meet in your office tomorrow or on Wednesday at 3pm? If this is not possible, suggest two or three alternative times.”
      • “Dear X, I need your bank account information -- Bank name, address, number account, IBAN and SWIFT -- as well as your personal information -- scan (jpeg or pdf) of ID, address and recent CV --. Please provide all the information in a single email before …”
    • Let people explicitly know that you are not 24/7. Include in your email signature a statement about the usual times where you can react to email, suggesting a phone call only for urgent matters. But do not provide personal phones to the general public: most things are not that urgent.


  • All the ideas above are more easily implementable the less you depend on others’ expectations, to avoid saying “bosses”. If you work in a rigid structure, or you have permanent input on tasks and projects from higher instances, it might help to apply the ideas above to giving structure to that interaction. For instance, you could:
    • Ask your supervisor or boss to make your list of projects better defined or more “sequential”, as opposed to working in many topics in parallel.
    • Try to allocate periodic interaction with your colleagues or supervisor in well defined slots of time. This periodicity and definition will also benefit the persons you interact with.
    • Make those meetings as efficient as possible, bringing well defined ideas or questions to the meeting and defining also the expectations of that meeting: is it a report, a brainstorming session, are you needing help?
    • Be proactive. Do not work on act-by-reaction mode or expect supervision on the external topics. You do not want to suffer back the friction that this causes on others.
  • You will find resistance, bear with it.
    • People will expect 24/7 availability, in particular through email, which paradoxically is the least resilient method of communication. The breaks indicated above are designed to break these expectations, but if this does not work, talk to the offended party and clarify your motivation.
    • You will yourself expect 24/7 availability. Nothing truly horrible happens if you do not answer an email in the weekend. Or probably in a week. And if it happens, either it is because of bad planning, or you should be willing to pay the price for a more organized and independent life.

1-10 of 27