Automatically capitalize or uppercase or expand keywords in Emacs using Abbrev Mode

I like that SQL Mode in Emacs comes with an interactive mode that I could execute a query in a buffer to a client buffer similar to how I could execute R code using ESS. However, I don’t think SQL mode is that great at formatting SQL code (eg, indenting). I guess I could live with manual indenting and selecting in multiple lines (preceded by a comma).

I typically write code in lower cases, but I think the SQL convention is to use upper cases for keywords like SELECT, FROM, WHERE, etc. This can be done using Abbrev Mode in Emacs. Add the following to your init file:

;; stop asking whether to save newly added abbrev when quitting emacs
(setq save-abbrevs nil)
;; turn on abbrev mode globally
(setq-default abbrev-mode t)

Now, open a SQL file (/tmp/test.sql). Type SELECT, then C-x a l and type select. This saves the abbreviation for the current major mode (SQL mode). Now, when you type select then <space>, the keyword will be capitalized. Continue doing the same for other keywords. Now, use the write-abbrev-file command to save the abbreviations to ~/.emacs.d/abbrev_defs so it can be saved and usable in future Emacs sessions.

To define many keywords all at once, edit the abbrev_defs directly. For example, I used this list of SQL keywords and relied on Emacs macros to add them to my abbrev_defs file. My abbreviation table for SQL mode is as follows:

(define-abbrev-table 'sql-mode-abbrev-table
(mapcar #'(lambda (v) (list v (upcase v) nil 1))
'("absolute" "action" "add" "after" "all" "allocate" "alter" "and" "any" "are" "array" "as" "asc" "asensitive" "assertion" "asymmetric" "at" "atomic" "authorization" "avg" "before" "begin" "between" "bigint" "binary" "bit" "bitlength" "blob" "boolean" "both" "breadth" "by" "call" "called" "cascade" "cascaded" "case" "cast" "catalog" "char" "char_length" "character" "character_length" "check" "clob" "close" "coalesce" "collate" "collation" "column" "commit" "condition" "connect" "connection" "constraint" "constraints" "constructor" "contains" "continue" "convert" "corresponding" "count" "create" "cross" "cube" "current" "current_date" "current_default_transform_group" "current_path" "current_role" "current_time" "current_timestamp" "current_transform_group_for_type" "current_user" "cursor" "cycle" "data" "date" "day" "deallocate" "dec" "decimal" "declare" "default" "deferrable" "deferred" "delete" "depth" "deref" "desc" "describe" "descriptor" "deterministic" "diagnostics" "disconnect" "distinct" "do" "domain" "double" "drop" "dynamic" "each" "element" "else" "elseif" "end" "equals" "escape" "except" "exception" "exec" "execute" "exists" "exit" "external" "extract" "false" "fetch" "filter" "first" "float" "for" "foreign" "found" "free" "from" "full" "function" "general" "get" "global" "go" "goto" "grant" "group" "grouping" "handler" "having" "hold" "hour" "identity" "if" "immediate" "in" "indicator" "initially" "inner" "inout" "input" "insensitive" "insert" "int" "integer" "intersect" "interval" "into" "is" "isolation" "iterate" "join" "key" "language" "large" "last" "lateral" "leading" "leave" "left" "level" "like" "local" "localtime" "localtimestamp" "locator" "loop" "lower" "map" "match" "map" "member" "merge" "method" "min" "minute" "modifies" "module" "month" "multiset" "names" "national" "natural" "nchar" "nclob" "new" "next" "no" "none" "not" "null" "nullif" "numeric" "object" "octet_length" "of" "old" "on" "only" "open" "option" "or" "order" "ordinality" "out" "outer" "output" "over" "overlaps" "pad" "parameter" "partial" "partition" "path" "position" "precision" "prepare" "preserve" "primary" "prior" "privileges" "procedure" "public" "range" "read" "reads" "real" "recursive" "ref" "references" "referencing" "relative" "release" "repeat" "resignal" "restrict" "result" "return" "returns" "revoke" "right" "role" "rollback" "rollup" "routine" "row" "rows" "savepoint" "schema" "scope" "scroll" "search" "second" "section" "select" "sensitive" "session" "session_user" "set" "sets" "signal" "similar" "size" "smallint" "some" "space" "specific" "specifictype" "sql" "sqlcode" "sqlerror" "sqlexception" "sqlstate" "sqlwarning" "start" "state" "static" "submultiset" "substring" "sum" "symmetric" "system" "system_user" "table" "tablesample" "temporary" "then" "time" "timestamp" "timezone_hour" "timezone_minute" "to" "trailing" "transaction" "translate" "translation" "treat" "trigger" "trim" "true" "under" "undo" "union" "unique" "unknown" "unnest" "until" "update" "upper" "usage" "user" "using" "value" "values" "varchar" "varying" "view" "when" "whenever" "where" "while" "window" "with" "within" "without" "work" "write" "year" "zone")
))

Emacs 24 crashing when launched with Synapse and an emacsclient window is closed

I’m currently using Emacs 24 (pre-release) installed from this repository on Ubuntu 11.04. An error (crash: segmentation fault) that arose after moving from Emacs 23 to Emacs 24 is as follow (could stem from the pre-release repository; might not be the case if I compile from source).

I launch emacs via Synapse. I start the daemon server (M-x server-start). Then, I launch text files from Nautilus via my emacs.sh script:

#! /bin/sh
## exec emacsclient --alternate-editor="emacs" -c "$@" ## not using this since I use DeskTop AND set server-on in .emacs...sometimes DeskTop would ask a question when accessing a lock session, and emacs will hang at the question
## taken from comments section at http://draptik.wordpress.com/2009/10/23/emacsclient-usage-on-a-gnulinux-system/

# ## following doesn't work for emacs 24, only 23 # emacsclient -e '(gnuserv-done-function)' 2>/dev/null ## suppress the stderr message # if [ "$?" -ne "0" ]; then ## http://steve-parker.org/sh/exitcodes.shtml # emacs "$@" # else # emacsclient -c "$@" # fi exec emacsclient --alternate-editor="emacs" -c "$@"

When I do C-x # to close the emacsclient window, the entire emacs program crashes. This does not happen when I launch files from the terminal; it only happens when I launch files using the script (or just the emacsclient command) using Nautilus. I even launched an unadulterated emacs session via emacs -q and this still happens.

My current solution is to launch my first emacs instance via the default Gnome “launch application” (Alt F2).

S5 Reloaded themes with Sigma’s emacs org-mode method

In the past, I’ve described the benefits of a slide show based on html. I used to prefer the html5 method over S5, but after some use, I’ve come to realize that the html5 method (at least the one described here) isn’t ready for prime time yet. The display of the slides can get screwy. For example, the current slide might not be centered correctly. Therefore, I’m going to recommend the S5 system for html slide shows for now.

For use with Emacs org-mode, use Sigma’s method. Why? It is easier to change themes compared to Eric Schulte’s method (the latter method currently does not support a change in themes I think). In addition, it is compatible with the very good looking S5 Reloaded themes.

To change themes in the original S5 archive and have it work with emacs org-mode, copy ui/default/slides.js to ui/i18n/slides.js. To get S5 Reloaded themes to work, add jquery.js and org-slides.js from Sigma’s archive (in ui) into S5 Reloaded’s ui directory. Also, change /default/ to the desired location (theme) in S5.org from Sigma’s archive.

Literature

Despite the availability of softwares such as Mendeley, Zotero, and JabRef, I like to store my papers (pdf files) and citation information (bib files) using a directory stucture, enter notes into a text file (org-mode), view notes and bibliographic information using a single file, cite references in LaTeX from a single bib file, and manage papers in Emacs using dired. I choose to manage my references using the bib format because it is the de facto standard in academia (at least in my field), and hence, is easily exported from the publisher’s website. In addition, I write all my papers using LaTeX for which I utilize bibtex whenever a reference is made; if I were to write papers using another program that utilizes a different format for bibliographies, I can easily convert the bib files using bibutils.

This post was originally motivated by this post which outlines a method to manage papers in emacs and org-mode. However, the workflow did not fit me particularly well, and so I came up with a setup and workflow of my own. I’ve been using this workflow for the last half a year and never got around to outlining it until the recent org-bibtex discussion reminded me to do so. I will first describe my setup and then its usage. I then end with some tips on starting your academic paper library and other thoughts. It is assumed that papers are available in pdf format. All filenames used throughout should not contain spaces, just to be safe.

Setup

The base directory for the research papers I download and their corresponding bib files is ~/Documents/Literature. In this base directory, I have a folder scripts for storing scripts that help me manage the files. I also have the files books.bib and software.bib for storing citation information for books and software. The main files, bibliography.bib and literature.org are generated and updated using scripts and hence, are set to be non-writable by me in order to avoid manual editing that will be lost when the next update occurs.

I split my papers into subjects or categories according to directories in the base directory such as ./EstimatingEquations, ./Survival/, etc. In each of the subject directory, I have a category.org file that assists with structuring the literature.org file. An example of the category.org file:

* Estimating Equations :EstimatingEquations:

Place the following scripts in your script directory, ./scripts/.

LitNotes.sh:

#! /bin/bash

## template notes.org for a folder with bib.bib file

if [ -f bib.bib ]
then
    if [ -s notes.org ] ## check if filesize is greater than 0 if it exists; FALSE if it does not exsist
    then
        echo "./notes.org has content (file size greater than zero.)!" && exit 1
    else
        ## http://stackoverflow.com/questions/5162808/help-with-regex-extracting-text
        author=$(sed -n '/^[[:blank:]]*author[[:blank:]]*=[[:blank:]]*{/ {s///; s/}[^}]*$//p}' bib.bib)
        title=$(sed -n '/^[[:blank:]]*title[[:blank:]]*=[[:blank:]]*{/ {s///; s/}[^}]*$//p}' bib.bib)
        year=$(sed -n '/^[[:blank:]]*year[[:blank:]]*=[[:blank:]]*{/ {s///; s/}[^}]*$//p}' bib.bib)
        echo "** $author ($year) $title 
*** Notes
" > notes.org
    fi
else
    echo "No bib.bib in current directory." && exit 1
fi

# ## following used on inside each category folder, eg, ./Survival; remember to edit tags in this script
# for directory in `ls -p | grep "/"`
# do
#     cd "$directory"
#     ##pwd
#     ##[ -f notes.org ] && echo "yes"
#     if [ -f notes.org ];
#     then
#         ## http://stackoverflow.com/questions/5162808/help-with-regex-extracting-text
#         author=$(sed -n '/^[[:blank:]]*author[[:blank:]]*=[[:blank:]]*{/ {s///; s/}[^}]*$//p}' bib.bib)
#         title=$(sed -n '/^[[:blank:]]*title[[:blank:]]*=[[:blank:]]*{/ {s///; s/}[^}]*$//p}' bib.bib)
#         year=$(sed -n '/^[[:blank:]]*year[[:blank:]]*=[[:blank:]]*{/ {s///; s/}[^}]*$//p}' bib.bib)
#         ##author=$(sed -n '/author *=/{s/^[^{]*{\([^,]*\),.*$/\1/;s/} *$//p}' ./bib.bib) ## does not work well because there could be commas in author
#         echo "** $author ($year) $title :Survival:
# *** Notes
# " ##> notes.org
#     fi
#     cd ..
# done

LitCreateDir.sh:

#! /bin/bash

## arguments are pdf files

for file in "$@"
do
bn=`basename "$file"`
NameNoExt=${bn%.*} ## no extension
Ext=${bn/*./} ## extension http://www.linuxforums.org/forum/programming-scripting/128625-how-get-file-extension-without-dot.html
if [ `echo $Ext | tr [:upper:] [:lower:] ` = "pdf" ] ## only do pdf files
then
mkdir "$NameNoExt"
mv "$file" "$NameNoExt/"
touch "$NameNoExt/bib.bib"
touch "$NameNoExt/notes.org"
if [ -f "$NameNoExt.bib" ] ## file exists?
then
mv -f "$NameNoExt.bib" "$NameNoExt/bib.bib"
cd "$NameNoExt"
LitNotes.sh
cd ..
fi
fi
done

LitUpdate.sh:

#! /bin/bash

basedir="$HOME/Documents/Literature"
bibfile="$basedir/bibliography.bib"
litfile="$basedir/literature.org"

## delete old files
cd $basedir
rm -f $bibfile $litfile

## create $bibfile
find ./ -iname "*.bib" -print0 | xargs -0 cat > /tmp/bibliography.bib ## -0, some folders have "'" in name; *.bib and not just bib.bib to get books.bib as well
mv /tmp/bibliography.bib ./
# find ./ -iname "*.bib" -print0 > bibfiles.txt
# xargs -0 cat < bibfiles.txt > $bibfile
## books
##cat books.bib >> $bibfile ## above should already pick up books


## create $litfile
echo "#+title: Literature
#+author: YOUR NAME HERE
#+email: YOUR EMAIL HERE
" >> $litfile
for directory in `ls -p | grep "/"` ## directories in Literature
do
cd "$directory"
if [ -f category.org ]
then
cat category.org >> $litfile
##find ./ -iname "notes.org" -print0 | xargs -0 cat >> $litfile ## need to add in links to paper, location, bib, notes
for notes in `find ./ -iname "notes.org"`
do
fullpath=`readlink -f "$notes"`
##fullpath=`realpath "$notes"` ## http://www.commandlinefu.com/commands/view/7999/get-the-absolute-path-of-a-file?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+Command-line-fu+%28Command-Line-Fu%29&utm_content=Google+Reader
paperdir=`dirname "$fullpath"` ## directory name of directory with notes.org
pdf=`find "$paperdir" -iname "*.pdf"`
# cat "$notes" >> $litfile
# echo "*** [[file:$pdf][paper]] [[file:$paperdir/][location]] [[file:$paperdir/bib.bib][bib]] [[file:$paperdir/notes.org][notes]]" >> $litfile
head -n1 "$notes" >> $litfile
echo "*** [[file:$pdf][paper]] [[file:$paperdir/][location]] [[file:$paperdir/bib.bib][bib]] [[file:$paperdir/notes.org][notes]]" >> $litfile
sed '1 d' "$notes" >> $litfile
done
fi
cd ..
done

## make file read-only, so I have to manually go to the individual files to edit
chmod ugo=r $litfile $bibfile

Place the following in your emacs init file:

;; Literature
(defun dired-literature-create-directory-from-pdf ()
(interactive)
(save-window-excursion
(dired-do-async-shell-command
"$HOME/Documents/Literature/scripts/LitCreateDir.sh" current-prefix-arg
(dired-get-marked-files t current-prefix-arg))))
(define-key dired-mode-map (kbd "s-l d") 'dired-literature-create-directory-from-pdf)

(defun literature-update ()
(interactive)
(shell-command "LitUpdate.sh")
)
(global-set-key (kbd "s-l u") 'literature-update)

Usage

I recommend the pdf file be named AuthorYearTitle.pdf to be consistent across all papers. The Title of course should be short and descriptive. Whenever I download a pdf paper, I make it MANDATORY that I also download the corresponding bib file (too many times did I have to cite a paper I thought I’d never cite). Nearly all publishers can export to bib, including JSTOR. If the publishing site doesn’t have this feature, I recommend googling the article in Google Scholar and exporting the bib file from the search results via “Export to BibTeX” (needs to be turned on in the Google Scholar settings); if this too isn’t available, then I will write my own bib file manually. Name this file AuthorYearTitle.bib, identically the same as the pdf file except the file extension (this is crucial for the scripts to work). I usually find myself visiting the downloaded bib file and editing it according to my preference. For example, I don’t like to have leading spaces in each line and I want each tag (e.g., journal) to be encapsulated by curly braces and end with a comma, even if it is the last tag. Also, make sure that there is at least one empty line at the end of the bib file; more on this in the “Other Thoughts” section.

Suppose I downloaded these files in /tmp. In emacs, I will use dired to cut and paste these two files into the subject directory that it belongs to; for example, ./Survival. In dired, I will move the cursor to the pdf file and hit s-l d (d for directory); for multiple papers downloaded and moved at the same time, just mark the pdf files first before running s-l d. This will create a directory AuthorYearTitle in ./Survival for each marked paper, move the corresponding pdf and bib files into the newly created directory, and generate a templated notes.org whose content will be generated from the tags in the bib file:

** Author (Year) Title
*** Notes

Things learned and notes regarding the content of the paper is meant to be typed into notes.org file so that I can review my thoughts later (and not have to necessarily re-read a paper to see what I learned).

Why do I store each paper in its own directory? I want the paper, bib file, and my notes to be self-contained in a single entity, and a directory is the best way to achieve this goal. That way, I can move (to a new category?) or copy (send to a colleague?) the paper with all the information intact.

After downloading new papers or moving papers around into a different (new?) categroy, running s-l u updates my bibliography.bib and literature.org file. All bib files (papers, books, and software) are concatenated into a single bibliography.bib file so that a single \bibliography{$HOME/Documents/Literature/bibliography.bib} can be inserted in all my LaTeX files that make use of references. All category.org and notes.org files are concatenated into a single literature.org file to create a single “library” where I can view all the available information; the paper, location, bib, and notes file can also be opened using C-c o (org-mode link). Since it is a text file, all the power of emacs (and other tools) can be used on this file: ordinary searches, regex searches, etc. This way, I can search my thoughts (via notes) to find or trace ideas back to a paper. Here is a snippet of what a generated literature.org file looks like:

#+title: Literature
#+author: MY NAME
#+email: MY EMAIL

* Estimating Equations :EstimatingEquations:
** White, Halbert (1982) Maximum Likelihood Estimation of Misspecified Models :EstimatingEquations:
*** [[file:/home/vinh/Documents/Literature/EstimatingEquations/White1982MLEMisspecifiedModels/White1982MLEMisspecifiedModels.pdf][paper]] [[file:/home/vinh/Documents/Literature/EstimatingEquations/White1982MLEMisspecifiedModels/][location]] [[file:/home/vinh/Documents/Literature/EstimatingEquations/White1982MLEMisspecifiedModels/bib.bib][bib]] [[file:/home/vinh/Documents/Literature/EstimatingEquations/White1982MLEMisspecifiedModels/notes.org][notes]]
*** Notes

** Whitney K. Newey and Daniel McFadden (1994) Chapter 36 Large sample estimation and hypothesis testing
*** [[file:/home/vinh/Documents/Literature/EstimatingEquations/NeweyMcFadden1994LargeSampleEstimationTesting/NeweyMcFadden1994LargeSampleEstimationTesting.pdf][paper]] [[file:/home/vinh/Documents/Literature/EstimatingEquations/NeweyMcFadden1994LargeSampleEstimationTesting/][location]] [[file:/home/vinh/Documents/Literature/EstimatingEquations/NeweyMcFadden1994LargeSampleEstimationTesting/bib.bib][bib]] [[file:/home/vinh/Documents/Literature/EstimatingEquations/NeweyMcFadden1994LargeSampleEstimationTesting/notes.org][notes]]
*** Notes

** Cox, D. R. (1993) Unbiased Estimating Equations Derived from Statistics that are Functions of a Parameter
*** [[file:/home/vinh/Documents/Literature/EstimatingEquations/Cox1993UnbiasedEstEqDerived/Cox1993UnbiasedEstEqDerived.pdf][paper]] [[file:/home/vinh/Documents/Literature/EstimatingEquations/Cox1993UnbiasedEstEqDerived/][location]] [[file:/home/vinh/Documents/Literature/EstimatingEquations/Cox1993UnbiasedEstEqDerived/bib.bib][bib]] [[file:/home/vinh/Documents/Literature/EstimatingEquations/Cox1993UnbiasedEstEqDerived/notes.org][notes]]
*** Notes

...

* Genetics :Genetics:
** French, Benjamin and Lumley, Thomas and Monks, Stephanie A. and Rice, Kenneth M. and Hindorff, Lucia A. and Reiner, Alexander P. and Psaty, Bruce M. (2006) Simple estimates of haplotype relative risks in case-control data
*** [[file:/home/vinh/Documents/Literature/Genetics/FrenchLumley+Others2006HaplotypesRelativeRisk/FrenchLumley+Others2006HaplotypesRelativeRisk.pdf][paper]] [[file:/home/vinh/Documents/Literature/Genetics/FrenchLumley+Others2006HaplotypesRelativeRisk/][location]] [[file:/home/vinh/Documents/Literature/Genetics/FrenchLumley+Others2006HaplotypesRelativeRisk/bib.bib][bib]] [[file:/home/vinh/Documents/Literature/Genetics/FrenchLumley+Others2006HaplotypesRelativeRisk/notes.org][notes]]
*** Notes

** Follmann, Dean and Proschan, Michael and Leifer, Eric (2003) Multiple Outputation: Inference for Complex Clustered Data by Averaging Analyses from Independent Data
*** [[file:/home/vinh/Documents/Literature/Genetics/FollmanProschanLeifer2003MultipleOutputation/FollmanProschanLeifer2003MultipleOutputation.pdf][paper]] [[file:/home/vinh/Documents/Literature/Genetics/FollmanProschanLeifer2003MultipleOutputation/][location]] [[file:/home/vinh/Documents/Literature/Genetics/FollmanProschanLeifer2003MultipleOutputation/bib.bib][bib]] [[file:/home/vinh/Documents/Literature/Genetics/FollmanProschanLeifer2003MultipleOutputation/notes.org][notes]]
*** Notes

** Lin, D.Y. and Zeng, D. and Millikan, R. (2005) Maximum likelihood estimation of haplotype effects and haplotype-environment interactions in association studies
*** [[file:/home/vinh/Documents/Literature/Genetics/LinZengMillikan2005MLEHaplotype/LinZengMillikan2005MLEHaplotype.pdf][paper]] [[file:/home/vinh/Documents/Literature/Genetics/LinZengMillikan2005MLEHaplotype/][location]] [[file:/home/vinh/Documents/Literature/Genetics/LinZengMillikan2005MLEHaplotype/bib.bib][bib]] [[file:/home/vinh/Documents/Literature/Genetics/LinZengMillikan2005MLEHaplotype/notes.org][notes]]
*** Notes

** Lin, DY and Zeng, D. (2006) Likelihood-based inference on haplotype effects in genetic association studies
*** [[file:/home/vinh/Documents/Literature/Genetics/LinZeng2006LikelihoodInferenceHaplotype/LinZeng2006LikelihoodInferenceHaplotype.pdf][paper]] [[file:/home/vinh/Documents/Literature/Genetics/LinZeng2006LikelihoodInferenceHaplotype/][location]] [[file:/home/vinh/Documents/Literature/Genetics/LinZeng2006LikelihoodInferenceHaplotype/bib.bib][bib]] [[file:/home/vinh/Documents/Literature/Genetics/LinZeng2006LikelihoodInferenceHaplotype/notes.org][notes]]
*** Notes

...

Note that the update process can take seconds or more due to the concatenation. My library is ever-growing so it will only get longer and longer to update. I’m not sure if I can ever speed up this process (let me know if you have ideas).

After running the update process, reftex-reset-mode should be run in an opened LaTeX file if you want to make use of the most current information with RefTeX.

I make use of emacs’s bookmark capabalities (C-x r b) to visit these files easily in emacs.

Getting started

Most researchers have their downloaded pdf files in one location or multiple locations (category). To get started, I recommend spending time to rename the files according to AuthorYearTitle.pdf, and downloading or creating a separate bib file for each paper. Then place the files into their category directories (create category.org as well). In emacs dired, mark all the pdf files in each category, run s-l d to generate a self-contained directory for each paper. After this is done on all the categories, run s-l u to update. The file bibliography.bib can now be used in your LaTeX documents. The file literature.org can be now be used as an all in one library.

Other thoughts

Each bib file should have at least one empty line at the end of the file or things may go wrong in the bibliography.bib file; this paper is concatenated from multiple files, and multiple lines could be joined into one line if the newline character isn’t present at the end of the file.

I also have a bibliography.tex file to generate a pdf file with all my papers:

\documentclass{article}
\usepackage{fullpage}
\usepackage{natbib}

\begin{document}

\cite{*}
\bibliographystyle{apa}
\bibliography{bibliography}

\end{document}

One thing I would like to be able to do is edit the literature.org file (notes portion) directly and have the changes reflected in the individual notes.org files. I haven’t thought of a process to do this well. It would be nice to view multiple files in a single buffer as if the buffer is showing a single file so that when I edit a portion of the buffer, it actually is a different file depending on its location.

I’m not sure if anyone will find my workflow useful, but I just wanted to document it for the masses.

Ignore errors when executing a command in emacs with condition-case

Suppose you want to execute a command in your emacs init file, but this command sometimes return an error. For example, you ask emacs to open a file for you, but the file doesn’t exist. When an error occurs, the rest of the init will not be loaded. Once can make use of the condition-case command to ignore the error. The following is an example:

 <pre class="example">(condition-case nil

(wg-load “~/.emacs.d/workgroups-save”) ;; ignore errors from this command (error nil))

Some custom emacs keybindings for LaTeX to assist in the writing process

Here are some habits I think will assist in the writing of LaTeX documents:

  1. Always encapsulate your superscripts and subscripts with curly braces, even if they consist only of 1 characters. For example, it should x_{1} rather than x_1. The reason is that lot’s of time, I go back to changing my subscripts, and I often use a command like replace-string in emacs to help do it for the entire document. If I change the subscript from 1 character to multiple characters, thing gets messed up. For example, x_1 to x_i1 where it should really be x_{i1}. Using curly braces just help prevent things from going wrong and having to go back to the errors.
  2. As mentioned on this post, it is best to keep each sentence on its own line to facilitate version controlling the document.

To help with these two tasks, I’ve binded my “.”, “\^”, and “_” keys to smart functions that will do what I want. Pressing the keys again will go back to the plain character.

 <pre class="example">;; following for latex, adapted from ess-smart-underscore

;; can also be implemented using sequential command http://www.emacswiki.org/emacs/SequentialCommand (defun tex-smart-underscore () “Smart \”\” key: insert \”{}\”. If the underscore key is pressed a second time, \”{}\” is removed and replaced by the underscore.” (interactive) (let ((assign-len (length “{“))) (if (and (>= (point) (+ assign-len (point-min))) ;check that we can move back (save-excursion (backward-char assign-len) (looking-at “{}”))) ;; If we are currently looking at ess-S-assign, replace it with _ (progn (forward-char) (delete-backward-char (+ 1 assign-len)) (insert ““)) (delete-horizontal-space) (insert “_{}”) (backward-char))))

(defun tex-smart-caret () “Smart \”\^\” key: insert \”\^{}\”. If the caret key is pressed a second time, \”\^{}\” is removed and replaced by the caret.” (interactive) (let ((assign-len (length “\^{“))) (if (and (>= (point) (+ assign-len (point-min))) ;check that we can move back (save-excursion (backward-char assign-len) (looking-at “\\^{}”))) ;; looking-at reads regexp, so need to escape the caret character ;; If we are currently looking at ess-S-assign, replace it with \^ (progn (forward-char) (delete-backward-char (+ 1 assign-len)) (insert “\^”)) (delete-horizontal-space) (insert “\^{}”) (backward-char))))

(defun tex-smart-period () “Smart \”.\” key: insert \”. \n\”. If the period key is pressed a second time, \”. \n\” is removed and replaced by the period.” (interactive) (let ((assign-len (length “. %%\n”))) (if (and (>= (point) (+ assign-len (point-min))) ;check that we can move back (save-excursion (backward-char assign-len) (looking-at “\. %%”))) ;; If we are currently looking at ess-S-assign, replace it with _ (progn (delete-backward-char assign-len) (insert “.”)) (delete-horizontal-space) (insert “. %%\n”))))

;; http://stackoverflow.com/questions/5500035/set-custom-keybinding-for-specific-emacs-mode ;; eval-after-load didn’t fix this for me ;; http://www.emacswiki.org/emacs/LaTeX (add-hook ‘LaTeX-mode-hook (lambda () (define-key LaTeX-mode-map (kbd “_”) ‘tex-smart-underscore) (define-key LaTeX-mode-map (kbd “\^”) ‘tex-smart-caret) (define-key LaTeX-mode-map (kbd “.”) ‘tex-smart-period) ) )

Non-LaTeX presentations using org-mode – S5 and HTML5 slides

I recently had frustrations with presentations written using MS Powerpoint; I’m not even going to mention KeyNote as it is only available on a Mac. LibreOffice is my WYSIWYG editor on my Linux machine for writing quick and nicely formatted content. I also have MS Office installed on my machine using WINE. I sometimes use Google Docs for presentation when I have to collaborate. Most of the times, viewing MS-generated files on LibreOffice suffices. When it doesn’t work well, I opt for MS Office. However, I recently had to open a powerpoint presentation with an audio link. It didn’t play on LibreOffice and it didn’t play on my WINE MS Office. I started thinking about a possible route for presentation files that are self-contained and cross-platform. PDF comes to mind first, but to do so would mean I have to use Beamer to generate the slides or to use Adobe Acrobat to create the slides. I don’t want to do either as I’m referring to the scenario of creating quick slides.

HTML came to my mind next. I recalled S5. I remember this post which outlines how one could export to S5 using org-mode. I tried it out finally and things work nicely. This tutorial also mentions an alternative method to generate S5 presentations in org-mode based on the org-export-as-s5 function. Hopefully it will be integrated in the MASTER branch of org-mode soon. To embed audio or video, just paste the html code an html chunk, linking the file multimedia file in the current directory. Now the directory could be transferred to any computer and viewed.

I also stumbled on this link, which allows me to export org files to HTML5 slides. I think the latest file is here, with instructions on how to set up in the comments.

With the S5 and HTML5 slides exporting methods in org-mode, now I can make cross-platform presentations very easily using org-mode. I will probably use the HTML5 method as it doesn’t come with any dependencies like the ui directory from S5.

emacs keybindings in xpdf and xdvi

I’ve been using xpdf and xdvi for reading documents I’ve downloaded or my LaTeX-generated documents on the laptop more and more these days due to their speed. The one thing I require (desire) in all programs I use on a day to day basis, especially when I have to navigate the file, is to have emacs keybindings.

To do so for the two readers, first, add the following to ~/.Xresources:

 <pre class="src src-sh">! look<span style="color: #00ffff;"> in</span> man xdvi

xdvi.mainTranslations: #override Ctrlv: down-or-next()n Altv: up-or-previous()n Alt Shift <: goto-page(1)n Alt Shift >: goto-page()n Ctrlf: right(0.015)n Ctrlb: left(0.015)n Ctrln: down(0.015)n Ctrlp: up(0.015)n l: right(0.015)n h: left(0.015)n j: down(0.015)n k: up(0.015)n Ctrls: find()n xdvigeometry: 1350×700 xdvishrinkFactor: 4

! look in man xpdf and xpdfrc; ~/.xpdfrc xpdfgeometry: 1350×700 xpdfinitialZoom: width

Also, create and add the following to ~/.xpdfrc:

 <pre class="src src-sh">initialZoom width

continuousView yes bind ctrl-v any pageDown bind alt-v any pageUp bind alt-shift-< any gotoPage(1) bind alt-shift-> any gotoLastPage bind ctrl-n any scrollDown(16) bind ctrl-p any scrollUp(16) bind ctrl-f any scrollRight(16) bind ctrl-b any scrollLeft(16) bind h any scrollLeft(16) bind l any scrollRight(16) bind k any scrollUp(16) bind j any scrollDown(16) bind ctrl-s any find

Now I can at least navigate the file with emacs keybindings.

I would also like to get this to work on ghostview (for postscript files) or djview (for djvu files), but have yet to find out how to do so on these programs (or found programs for these formats that allow custom keybindings). I’ve written about using emacs’ doc-view to view all my files, but it can be sub-optimal:

  • the conversion process on large files can take a long time,
  • no “continuous” view mode,
  • searching the text does not highlight the text,
  • and the file doesn’t update when the dvi or pdf file is updated (or have a keybinding to update) for use with LaTeX (editing and updating files). UPDsATE: actually, you can refresh using the r keybinding; it works quite fast and stays on the same page you are on.

Please do let me know if you know how to make custom keybindings on ghostview or djview (or similar, fast programs). Also let me know if I am not aware of any features in doc-view that would make my life easier. Thanks!

escreen instead of elscreen for screen-like features in emacs

I’ve been using elscreen for screen-like features in emacs the last couple of years. However, I have a few complaints. Elscreen has issues when used with emacsclient -c: a new frame might not be created from the -c argument, which messes up my current screen in emacs, and the “Opening Server Files Always in a New Frame” tip on this did not resolve this issue perfectly with elscreen. Also, when used with emacs’ Desktop mode, I get an error when launching emacs with an Rnw file (Rweave, or Sweave) is in the file list; the launch actually does not load all files, and I have to exit and delete my desktop file (which I’ll lose the list of files).

I discovered escreen from this post a long time ago, and thought escreen was pretty lightweight and worked pretty well. However, I never switched to it because it didn’t have “tabs” for me to know which screen I was at. I didn’t realize the very same post had customizations that would show which screen you are at. I’ve copied his customizations, and added a few more of my own, which I’ll list here:

 <pre class="example">;; escreen is simpler than elscreen...but elscreen spawns new 0-9 set of screens for a new frame whereas escreen does not

;; it is better than elscreen because: elscreen has issues when using with emacsclient -c (does not always create new frame, messes up existing frame); in escreen, each screen has its own ring of recently visited files (good!) ;; http://blog.tapoueh.org/news.dim.html#%20Escreen%20integration ;; http://www.splode.com/~friedman/software/emacs-lisp/#ui (load “escreen”) (escreen-install) (setq escreen-prefix-char “\C-z”) ;; http://www.macs.hw.ac.uk/~hwloidl/cool-el.html (global-set-key escreen-prefix-char ‘escreen-prefix) ;; add C-\ l to list screens with emphase for current one (defun escreen-get-active-screen-numbers-with-emphasis () “what the name says” (interactive) (let ((escreens (escreen-get-active-screen-numbers)) (emphased “”))

(dolist (s escreens) (setq emphased (concat emphased (if (= escreen-current-screen-number s) (propertize (number-to-string s) ;;’face ‘custom-variable-tag) ” “) ‘face ‘info-title-3) ;;’face ‘font-lock-warning-face) ;;’face ‘secondary-selection) (number-to-string s)) ” “))) (message “escreen: active screens: %s” emphased)))

(global-set-key (kbd “C-\ l”) ‘escreen-get-active-screen-numbers-with-emphasis)

(defun escreen-goto-last-screen-dim () (interactive) (escreen-goto-last-screen) (escreen-get-active-screen-numbers-with-emphasis))

(defun escreen-goto-prev-screen-dim (&optional n) (interactive “p”) (escreen-goto-prev-screen n) (escreen-get-active-screen-numbers-with-emphasis))

(defun escreen-goto-next-screen-dim (&optional n) (interactive “p”) (escreen-goto-next-screen n) (escreen-get-active-screen-numbers-with-emphasis))

(define-key escreen-map escreen-prefix-char ‘escreen-goto-last-screen-dim)

(defun escreen-create-screen-dim () (interactive) (escreen-create-screen) (escreen-get-active-screen-numbers-with-emphasis))

(defun escreen-kill-screen-dim () (interactive) (escreen-kill-screen) (escreen-get-active-screen-numbers-with-emphasis))

(add-hook ‘escreen-goto-screen-hook ‘escreen-get-active-screen-numbers-with-emphasis)

(define-key escreen-map “c” ‘escreen-create-screen-dim) (define-key escreen-map “k” ‘escreen-kill-screen-dim)

;; (global-set-key (kbd “C-]”) ‘escreen-goto-next-screen) ;; (keyboard-translate ?\C-[ ?\H-[) ;; (global-set-key (kbd “H-[“) ‘escreen-goto-prev-screen) (global-set-key (kbd “C-]”) ‘escreen-goto-next-screen-dim) (keyboard-translate ?\C-[ ?\H-[) (global-set-key (kbd “H-[“) ‘escreen-goto-prev-screen-dim)

Whenever I create/kill/visit a screen, the minibuffer will always show the list of screens available, with emphasis on the current screen. I like escreen because it does not have the issues I listed before with elscreen. Also, in escreen, each screen has its own ring of recently visited files, so that if I move to a different screen and edit a buffer, move back to my original screen, kill the buffer, the recent buffer from the other screen will not be the default screen on this current screen.

I like escreen!