From: ······@gmail.com
Subject: Creating Next and Previous Navigation Bars with Emacs
Date: 
Message-ID: <1165050943.940489.266730@n67g2000cwd.googlegroups.com>
Creating Next and Previous Navigation Bars with Emacs

Xah Lee, 2006-11-29

This page show how emacs are employed in creating the Previous, Top,
Next chapter navigational button commonly found in htmlized books.

I have a lot of books in HTML form. Usually, they have files like
chap1.html, chap2.html, chap3.html ... etc.

Each file is a chapter of the book. And in each file, I need to place a
navigation bar, so that there's a Next Chapter and Previous Chapter
links at the bottom of each page.

Normally, this can be done by writing a short Python or Scheme shell
script. The script will open the file, parse the file name so that it
knows which chapter this file is. Then, the script will generate the
string like this:

<p>
<a href="chapter2.html">PREVIOUS</a>
<a href="index.html">TOP</a>
<a href="chapter4.html">NEXT</a>
</p>

For a example of a online book with Next/Previous navigation bar, see:
Flatland (novel).

For a person familiar with scripting languages, the job can be done in
about 20 minutes. Basically, your script will traverse a directory and
determine which files to process. For each file, your script will parse
the file name and generate the navigation bar string appropriate for
the file. Then, your script will open the file, insert the nav bar at
the appropriate place, then close the file. Your script will need do a
backup if you want it to be robust. With that, you'll also have to make
sure that the owner, group, permissions etc meta data are kept intact.

In the end, some simple script can end up taking twice or trice the
time you expected.

However, if you know elisp, you only need to write half of the code,
since the file selection, file opening and reading, backing up, saving,
etc are all part of the emacs environment. All you really need to write
is a elisp function that takes in a file name and returns the
navigation bar string. This significantly saves your time. As a added
benefit, you get to do this in a interactive, visual process. So,
errors are much reduced, and you don't have to worry about your code
making a mistake erasing parts of the file or missing some files, since
emacs has been debugged for more than a decade.

Here's how we do it with emacs.

First, mark the files you want to process in dired. Then, use
dired-do-query-replace-regexp to do a find and replace operation on a
particular string. For example, replace “<body>” with “<body>
navbar-string”.

The trick lies in your replacement string. You want to use a elisp
function that returns the appropriate nav bar for the chapter. (so that
the Next and Previous links are correct, according to what chapter the
current file is)

In emacs 22, there's a new feature that allows you to put a elisp
function as your replacement string. This is done by preceding your
elisp code with “ \, ”. So, if the function that returns the nav
bar string is called “navbar-str”, then in your replacement string
you can say “\,(navbar-str)”, and you are all set.

Here is the navbar-str function:

(defun navbar-str ()
  "Returns a navigation bar string with Prev and Next links based on
the current file name."
 (interactive)
(let (fname navbar-str chapter-num )
  (setq fname (file-name-nondirectory (buffer-file-name)) )
  (setq chapter-num (string-to-number (substring
(file-name-sans-extension fname) 4)))
  (setq navbar-str
        (concat "<div class=\"nav\">★ <a href=\"" "chap"
                (number-to-string (- chapter-num 1))
                ".html" "\">◀</a> <a href=\"index.html\">▲</a> <a
href=\"" "chap"
                (number-to-string (+ chapter-num 1))
                ".html" "\">▶</a> Flatland</div>"))
  navbar-str
  )
)

For a detailed tutorial on how to use the dired-do-query-replace-regexp
feature, see: Interactively Find and Replace String Patterns on
Multiple Files.
----
This post is archived at:
http://xahlee.org/emacs/nav-bar.html

  Xah
  ···@xahlee.org
∑ http://xahlee.org/