Chapter 2. DocBook and Subversion

Subversion is an open source version control system that keeps track of the changes you make to your book files.[1] Throughout the writing process, you can commit revised versions of the files to the repository with a log message, which will be associated with a revision number. Among other features, Subversion allows you to revert back to any older version of your files, as well as run diffs to easily compare versions. Subversion also supports multiple working copies of the same project, which means you can have many people collaborating on the same set of files simultaneously.

Using an O’Reilly Subversion Repository

Once you have spoken with your editor and decided that you are working on a book that needs to use the Subversion toolchain rather than Atlas, email the Tools group at . We will create an SVN repository for you on an O’Reilly server that contains book.xml and other files to use as a template for getting started. We will also set you up with a username and password. Here are some nice features of using an O’Reilly SVN repository:

  • It is easy to exchange files with your editor and coauthors for review.

  • It is easy for the O’Reilly Tools team to help you with any DocBook questions you may have along the way.

  • You can create PDF builds of your book each time you commit changes.

  • The files are stored in a safe and secure location that is backed up regularly.

  • You have the ability to view and merge changes from earlier versions of your book.

The repository URL for a standard O’Reilly book follows this structure:

https://prod.oreilly.com/internal/books/ISBN13/current/

Subversion Clients

You can choose your preferred SVN client, whether command-line or GUI. Here are some excellent free GUI clients:

A more comprehensive list can be found here. O’Reilly’s documentation generally refers to the command-line client, but the concepts and much of the vocabulary are the same across GUIs. For example, running svn update on the command line is analogous to right-clicking in an SCPlugin project directory and selecting Subversion Update.

Although you’re welcome to use any GUI client you like, please keep in mind that O’Reilly may not be able to provide support for all of them. You may need to rely on the program’s online documentation.

Subversion Primer

For in-depth information on the Subversion workflow and a command reference, see O’Reilly’s Version Control with Subversion (free to read online).

First, set up a directory on your local machine to serve as your local workspace for the project. You can name it anything you want. For example: ~/projects/my_book. Your working copy (or checkout) is your own private work area: Subversion will never incorporate other people’s changes, nor make your own changes available to others, until you explicitly tell it to do so.

The following steps outline a typical SVN workflow. Again, the examples refer to the command line, but you can run equivalent commands using any of the GUI clients.

Checkout (svn co)

Check out the files from the repository as follows (substituting the ISBN13 and your workspace filepath):

$ svn co https://prod.oreilly.com/internal/books/ISBN13/current 
~/projects/my_book

You need to run this command only once, when you first start a project. It will copy the book.xml and template files from the repo into your checkout. See “Organizing Your Files” for more information about the files you receive when you make your initial checkout.

After you do some amount of work that you want to preserve or share with others—say, you finish a chapter—commit those changes along with a short, descriptive log message. For example:

$ svn commit -m'finished draft of Chapter 1' ch01.xml

You don’t have to include the filename (ch01.xml here). If you leave it off, running svn commit will commit all the local modifications in your checkout—so make sure you really want to publish those changes. (If you make a mistake, previous versions can of course be recovered.) To find out which local files have modifications compared to the repo, run svn status -u. Here’s an example of the output:

$ svn status -u
M          245835   ch01.xml
     *     232767   ch04.xml
?                   images

The “M” means ch01.xml has local modifications; the “*” means a newer revision of ch04.xml exists on the server; and the “?” means images is not under version control. These are just a few of the possible indicators; http://svnbook.red-bean.com/en/1.0/re26.html has a complete list.

You can decide how frequently you want to commit. The more often you do, the easier it is to roll back to or recover specific previous versions.

Update (svn up)

Running svn up (aka svn update) brings changes from the repository into your working copy. You may first want to run svn status -u to see what kinds of changes will be incorporated (rather than blindly merging in changes), and then run svn up before starting to work on the files. This will ensure that your copies of the files reflect the most recent version in the repo.

It’s good practice to run svn up again before you commit. This should prevent any conflicts that could occur if other files have been added to the repo since you last updated.

Figure 2-1 and Figure 2-2 provide a visual overview of the workflow just described (where “me” is you, the author).

Setting up your workspace for a new project: checkout
Figure 2-1. Setting up your workspace for a new project: checkout
Ongoing SVN workflow: update and commit
Figure 2-2. Ongoing SVN workflow: update and commit

Add/delete/move/copy (svn add/svn rm/svn mv/svn cp)

These commands are useful for organizing files and directories in the repo. If you run them locally, they take effect only after you commit. For example:

$ svn add ch01.xml ch02.xml
A         ch01.xml
A         ch02.xml

The “A” output on the left indicates that the files have been scheduled for addition. If you’ve deleted files, you’ll see a “D” there; if you’ve modified files, you’ll see an “M”. (These letters are the same ones shown when you run svn status -u.)

If you decide, for example, that you don’t want to add ch01.xml after all, don’t commit—run svn revert ch01.xml to discard the scheduled addition.

Here’s an example of what happens when you commit after adding files:

$ svn commit -m'Adding Chapters 1 and 2 to the repo'
Adding         ch01.xml
Adding         ch02.xml
Committed revision 245451.

where “245451” is the revision number. You can find out the current revision number at any time using svn info.

Many SVN commands can be run server-side if you include repository URLs. Doing so results in an immediate commit (rather than scheduling an action for a later commit) and requires a commit message. Here’s an example of using a server-side svn mv to rename a chapter file:

$ svn mv -m'Renaming chapter2.xml to chapter3.xml' 
https://prod.oreilly.com/external/authors/books/ISBN13/current/chapter2.xml 
https://prod.oreilly.com/external/authors/books/ISBN13/current/chapter3.xml
Committed revision 245458.

Then svn up to see the change in your working copy. This command is equivalent to an svn cp followed by an svn rm.

If you try to svn rm, svn mv, or svn cp a file that exists in your checkout but was never added to the repo, you’ll get an error message like “svn: 'file' is not under version control”.

Other useful commands

svn info
svn log

See all commit log messages. Use with --limit # to limit the number of results.

svn diff

View changes in a file.

svn revert

Undo local edits.

The complete list of SVN commands is available here.

Conflicts

Because Subversion does not use a “locking” model of version control by default, it is possible for many people (such as coauthors and other collaborators) to have checkouts of the same repo and to work on them in parallel—which means is possible to have conflicts. For this reason, communicating with your collaborators is extremely important, as is remembering to commit and update your files. Conflicts can be resolved, but dealing with them can take time away from the writing of your book. It’s better to avoid them.

See Version Control with Subversion for more on resolving conflicts. If you run into trouble, contact .

Triggering PDF Builds of Your Book

The PDF builds are created with the same XSL-FO stylesheets that we use to typeset the final product that we send to the printer and sell as an online PDF. The build process for DocBook books creates PDFs from a valid book.xml file when commit messages include the right string (orm:commitpdf).

You can generate a fresh PDF of your book every time you commit changes to the SVN repository. To do so, run the following command (substituting your own message before the semicolon):

$ svn commit -m'Made some really important changes to Chapter 3; orm:commitpdf'

To get the PDF, just run svn up on your working copy about 5–10 minutes after committing your files. The PDF will be downloaded as pdf/book.xml.pdf in your working copy. If there are any problems in generating the PDF, you’ll instead get a .buildlog file in the pdf/ directory that lists the errors.

For PDF builds to work, the book.xml must be valid. If it is not valid, the PDF will fail to build. See “Validating Your XML”.

Some users have reported that the svn up will fail if the old book.xml.pdf is still open. Close the file and then svn up. Please contact with problems.

If you’re using a GUI client (see “Subversion Clients”), the process is the same as on the command line. You just need to add orm:commitpdf somewhere in your log message.

The text orm:commitpdf triggers the PDF build, and it can be used with any commit from your working copy, not just the book.xml file or a chapter file. So if you would like to generate a fresh PDF without making any changes to your book files, you can add a separate scratch file to the current directory (or a subdirectory) and just make modifications and commit the changes to it with the orm:commitpdf string.

Triggering PDF Builds of a Single Chapter

If instead of generating a PDF of the whole book when you commit changes, you’d prefer to generate a PDF of a single chapter, you can use the following command:

$ svn commit -m'Committing changes to Chapter 4; orm:chapterpdf id_for_chapter'

Here, the magic commit hook is orm:chapterpdf instead of orm:commitpdf. You’ll also need to include id_for_chapter, which is the value of the id attribute of the chapter in the XML file you want to create a PDF of.

A quick way to retrieve the id via the command line is:

$ grep "<chapter" ch04.xml
<chapter id="practice_1_automated_testing">
  <chapterinfo>

The string “orm:chapterpdf id_for_chapter” must appear at the end of your commit message for the commit hook to work.

Receiving Email Notifications When Committing

You can set up your O’Reilly SVN repository to send a notification anytime you or someone else (another author, your editor, the O’Reilly Tools team, etc.) commits. Email notifications are activated with an SVN property. You can request that the notification property be added by writing to , or you can just add it yourself:

That’s it. Notifications will now be sent to the addresses set in the orm:commitemails property every time a change is committed to the specified directory.

The orm:commitemails property is not recursive—i.e., it will apply only to the directory to which it’s applied, and not any subdirectories. So if you want email notifications on subdirectories (e.g., the pdf/ directory in current/), you’ll need to add the orm:commitemails property to those directories as well, using the steps above.

To turn off notifications, you can remove the orm:commitemails property as follows, and then commit:

$ svn pdel orm:commitemails

Web PDFs (Parallel PDF Builds)

By default, when you trigger a PDF build on your SVN repo with the orm:commitpdf string, our toolchain applies the XSL-FO stylesheets that we use for the print PDF. We use a separate set of stylesheets for the PDFs that we sell online (as part of the ebook bundles on oreilly.com and elsewhere), but you can trigger a build of that web PDF too. Some features of web PDFs include:

By enabling web-friendly PDF builds, you will be triggering the creation of two PDFs each time you use the orm:commitpdf string. Double the PDFs means double the time it will take for you to see your new PDFs. But even if you have a lot of content, you usually won’t have to wait longer than 15 minutes to receive both PDFs.

Adding the web PDF build is just a matter of adding an SVN property (similar to enabling email notifications). You can request that the property be added by writing to , or you can add it on your book directory yourself, as follows:

$ svn pset orm:parallel true .

Then commit. Once the SVN property is in place, you will receive a second PDF in your pdf/ directory (named book.xml.web.pdf) when you trigger a build using the orm:commitpdf string.

To turn off parallel PDF builds, you can remove the orm:parallel property as follows, and then commit:

$ svn pdel orm:parallel

Displaying Comments in Your PDF Builds

By default, text contained within XML comments (<!-- -->) or remark elements (see “Comments and Remarks”) will not be rendered in PDF builds. However, if you’d like to have this text displayed in your PDFs—for example, if you have comments for reviewers that you’d like to display in your PDFs during tech review—you can do so by setting the orm:draft SVN property on your book directory, as follows:

$ svn pset orm:draft remarks .

Then commit. Once the SVN property is in place, comments and remarks will be displayed in red for easy visibility.

To turn off this feature in PDF builds, you can remove the orm:draft property as follows, and then commit:

$ svn pdel orm:draft

Generating Timestamps in Your PDF Builds

To display a per-page, user-friendly timestamp on your PDFs, you can set the orm:timestamp SVN property on your book directory, as follows:

$ svn pset orm:timestamp true .

Then commit. Once the SVN property is in place, a timestamp will appear in the top-left corner of the PDFs you create. It looks something like this:

--------------
| 2010—03-05 |
|  11:05:43  |
--------------

To turn off the timestamp in PDF builds, just remove the orm:timestamp property, and then commit:

$ svn pdel orm:timestamp


[1] As mentioned in the previous chapter, we are transitioning most books over to Atlas (which works with git, not SVN). But the Subversion toolchain still exists for certain books that rely on the older stylesheets.