Previous Up Next

Chapter 12  Writing Documents Portable to PDF and HTML

12.1  Introduction

The concept of portability is often applied to software applications. For example, if an application can run on only one type of computer operating system, then the application is said not to be portable. Conversely, if an application can run on several types of operating system (such as Microsoft Windows, Apple Macintosh and Linux), then the application is said to be portable to those operating systems.

The concept of portability can also be applied to documents. It is possible to write a ".tex" file that can be processed by LaTeX to produce a PDF file, but cannot be processed by HeVeA to produce HTML. And vice versa. But, with a bit of planning and effort, it is often possible to write a ".tex" file that can be processed by LaTeX to produce a PDF file, and also can be processed by HeVeA to produce HTML. I say that such a document is portable to both PDF and HTML.

Previous chapters have discussed several ways in which Canthology simplifies the task of writing LaTeX documents that are portable to PDF and HTML. For example:

In this chapter, I start by discussing some additional LaTeX commands, defined in the canthology package, that help to increase the portability of documents.

Although Canthology protects users from several portability obstacles, it is impossible for Canthology to provide protection from every portability obstacle. For this reason, I finish this chapter by offering some advice on what you can do when you encounter a portability obstacle that is not by Canthology.

12.2  How to Define Labels in a Portable Way

Books about LaTeX typically show the \label command (Section 9.10.1) being used immediately after one of the following commands: \part, \chapter, \section, \subsection, \subsubsection, \paragraph, \subparagraph or \caption. When you convert your ".tex" document into a PDF file, the label is associated with the preceding command.

Unfortunately, HeVeA works slightly differently. When it converts your ".tex" document into HTML, the label is associated with whatever text follows it. To understand this distinction, consider the following:


\chapter{How it All Started}
\label{ch:started}
Once upon a time ...

Let’s assume another part of the document provides a cross reference to the ch:started label, and that a reader viewing the document on a computer screen clicks on that cross reference. If the document is in PDF format, then the PDF document viewer will jump to the chapter title, which is what we want. However, if the document is in HTML format, then the web browser will jump to the first line of text after the chapter title (that is, Once upon a time…) and the chapter’s title will be invisible, just above the top of the browser’s window, which is not what we want. This problem affects not just the \chapter command, but all commands after which you might place a \label command.

The HeVeA manual [6] recommends a workaround for this problem: place the \label command inside the parameter to the \chapter command. Using this workaround, the example would be rewritten as follows:


\chapter{\label{ch:started}How it All Started}
Once upon a time ...

That workaround results in cross references in the HTML version of a document working as they do in the PDF version of a document. However, this workaround is not without problems.

One obvious problem is that placing the \label command inside the \chapter command decreases readability of the ".tex" file.

Another potential drawback is that I don’t think LaTeX was designed with the expectation that a \label command would be placed inside a \chapter command, so this works by accident rather than by design. As such, it is possible that future modifications to LaTeX may cause this workaround to stop working.

Ideally, we want the \label command to appear after the \chapter command when using LaTeX, but to appear inside the \chapter command when using HeVeA. The canthology package facilitates this by defining a command called \lchapter (short for “labelled chapter”) that takes two parameters: a chapter title and its label. The ".sty" (that is, LaTeX) implementation of the canthology package defines this command as follows:


\newcommand{\lchapter}[2]{\chapter{#1}\label{#2}}

As you can see, that definition places the \label command after the \chapter command. In contrast, the ".hva" (that is, HeVeA) implementation of the canthology package defines the command so that the \label command is inside the \chapter command:


\newcommand{\lchapter}[2]{\chapter{\label{#2}#1}}

We can use \lchapter to rewrite the start-of-a-chapter example in a more portable way:


\lchapter{How it All Started}{ch:started}
Once upon a time...

The canthology package defines \lpart, \lsection, \lsubsection, \lsubsubsection, \lparagraph, \lsubparagraph and \lcaption in a similar way to \lchapter.

12.3  Avoid Using the \pageref Command

Consider the following sentence:


I discuss this in greater detail in
Section~\ref{sect:something} on
page~\pageref{sect:something}.

If you convert your document into PDF, then the above sentence may appear as:

I discuss this in greater detail in Section 2.6 on page 19.

However, if you convert your document into HTML, then two question marks will be used for the page number:

I discuss this in greater detail in Section 2.6 on page ??.

This happens because the concept of page numbers does not make sense in HTML. Thus, HeVeA implements the \pageref command to print two question marks in the hope that a proofreader will notice the problem in the generated HTML.

Thankfully, there is a simple technique that enables us to use \pageref when creating PDF documents and to avoid using it when creating HTML documents. This technique is to use \newcommand to define higher-level commands for typesetting cross references. The definition of these higher-level commands in the ".sty" implementation of a package can use the \pageref command, while the definition of the commands in the ".hva" implementation of a package avoids using the \pageref command.

In Section 9.10.2, I discussed shorthand commands such as \xsp and \xs for typesetting a cross reference to a section, with and without stating its page number. The definition of these commands in the ".sty" implementation of a package might be as follows:


\newcommand{\xs}[1]{Section~\ref{#1}}
\newcommand{\xsp}[1]{Section~\ref{#1} on
page~\pageref{#1}}

Their definitions in the ".hva" implementation of the same package might be:


\newcommand{\xs}[1]{Section~\ref{#1}}
\newcommand{\xsp}[1]{Section~\ref{#1}}

Using those definitions, the example sentence used earlier can be written (more compactly) as follows:


I discuss this in greater detail in \xsp{sect:something}.

That will be typeset in a PDF document as follows:

I discuss this in greater detail in Section 2.6 on page 19.

and will be typeset in a HTML document as follows:

I discuss this in greater detail in Section 2.6.

The ".sty" implementation of the canthology package defines the \xpp, \xap, \xcp, \xsp, \xfp and \xtp commands to make use of page numbers (via the \vref command of the varioref package). The ".hva" implementation of the canthology package defines those commands to not attempt to use page numbers.

12.4  The \ifthenelse Command

Among other things, the ifthen package [2] defines an \ifthenelse command that takes three parameters:


\ifthenelse{condition}{then-part}{else-part}

The \ifthenelse command evaluates the condition parameter. If this evaluates to true, then the text or statements in the then-part parameter are processed. Otherwise, the text or statements in the else-part parameter are processed.

The hevea package [6] defines a boolean variable called hevea. This variable is given the value true when a document is processed by the hevea command, but is given the value false when a document is processed by a LaTeX-related command such as latex or pdflatex.

The combination of the \ifthenelse command and the hevea boolean variable makes it possible to tailor the appearance or contents of a document for the output format (HTML or PDF). For example, an outline of the "titlepage-template-*.tex" files (Section 7.4) is shown below:


\ifthenelse{\boolean{hevea}}{
    ... % Typeset the title page for HTML format
}{
    ... % Typeset the title page for PDF format
}

In this way, a book can have its title page typeset one way in the PDF format of the book, and typeset another way in the HTML format.

You are likely to need to use the \ifthenelse command only rarely. However, for some niche tasks, such as typesetting the title page of a document, it can be invaluable.

12.5  Placement of Captions

A caption is a brief description that accompanies, for example, a photograph in a book or article. In some books, a caption appears above a figure. You can see an example of this in Figure 12.1.

Figure 12.1: A caption above a figure

In some other books, a caption appears below a figure. You can see an example of this is shown in Figure 12.2.

Figure 12.2: A caption below a figure

When a document is printed on paper, it is a subjective issue whether a caption looks better above or below a figure. However, if a document might be read on a computer screen, then it is better to put the caption above a figure. To understand why, let’s assume you are reading a document on a computer screen, and you click on a cross reference to a figure. The view on the screen may change to show the figure’s caption (that is, the linked-to text) at the very top of the screen.

Readers who have viewed HTML pages in a web browser should easily be able to visualise the issue I have described above. However, some readers may assume the issue does not apply to PDF documents because the PDF viewer they use shows an entire page of a document at a time. However, many PDF viewers have a menu option that enables you to view a document in one continuous (and scrollable) stream rather than a single page at a time. If a PDF viewer is in “continuous” viewing mode, then the issue I have described above will apply.

12.6  Dealing with Other Portability Problems

Sooner or later, you are likely to encounter a portability obstacle that is not handled by Canthology. Typically, you will notice that a particular command is processed one way by LaTeX, but processed a different way by HeVeA. Your instinct might be to wonder:

How can I make this command work the same way in HeVeA as it does in LaTeX?

However, it is often more productive to ask a different question:

That command (perhaps when combined with other commands) produces the desired result with LaTeX but, unfortunately, not with HeVeA. Might a different command (or sequence of commands) produce the desired result (or at least an acceptable result) with HeVeA?

If you can find such an alternative command (or sequence of commands), then that makes it possible to overcome the portability obstacle with the following:

  1. Create a new package, let’s call it example. Doing this is straightforward. Section 9.5 discusses how to create example.sty for use with LaTeX; and Section 10.6 discusses how to create a corresponding ".hva" version of a package for use with HeVeA.
  2. In example.sty, use \newcommand to define a command that achieves what you want in a way that is compatible with LaTeX.
  3. In example.hva, use \newcommand to define an identically-named command that achieves what you want in a way that is compatible with HeVeA.
  4. Now add the example package to the list of package names used by your document.

As an example, recall from Section 12.2 that placing a \label command after a \chapter command does what we want in LaTeX, but not in HeVeA. The way Canthology works around this portability problem is to implement a new command called \lchapter one way in canthology.sty and a different way in canthology.hva.

In fact, this approach is the primary tactic that Canthology uses to encapsulate portability obstacles. The canthology package defines over 30 commands, most of which are defined one way in canthology.sty and a different way in canthology.hva.


Previous Up Next