3. Using a Configuration File
Prev |  | Next

## 3. Using a Configuration File

In the preceding example, the desired output style for `doc1.xml` was the same as what xmlformat produces by default. But what if the default style is not what you want? In that case, you must tell xmlformat how to handle your document. This is at once both the weakness and strength of xmlformat. The weakness is that it is extra work to instruct xmlformat how you want it to format a document. The strength is that it's possible to do so. Other XML formatters do not require any extra work, but that's because they are not configurable.

Suppose `doc2.xml` looks like this:

    <example><title>Compiling and Running a Program</title>
    <para>To compile and run the program,
    use the following commands, where
    <replaceable>source-file</replaceable>
    is the name of the source file:</para><screen>
    <userinput>cc</userinput> <replaceable>source-file</replaceable>
    <userinput>./a.out</userinput>
    </screen>
    </example>

That's ugly, and you want it to rewrite it like this:

    <example>

    <title>Compiling and Running a Program</title>

    <para>
     To compile and run the program, use the following commands,
     where <replaceable>source-file</replaceable> is the name of
     the source file:
    </para>

    <screen>
    <userinput>cc</userinput> <replaceable>source-file</replaceable>
    <userinput>./a.out</userinput>
    </screen>

    </example>

The key characteristics of this rewrite are as follows:

- Child elements of the `<example>` element are separated by blank lines, but not indented within it.

- The text inside the `<para>` element is reformatted, adjusted to 60 characters per line and indented.

- The contents of the `<screen>` element are left alone.

Unfortunately, if you run `doc2.xml` through xmlformat, it comes out like this:

    <example>
     <title>Compiling and Running a Program</title>
     <para>To compile and run the program,
    use the following commands, where
    <replaceable>source-file</replaceable>
    is the name of the source file:</para>
     <screen>
      <userinput>cc</userinput>
      <replaceable>source-file</replaceable>
      <userinput>./a.out</userinput>
     </screen>
    </example>

This output is unsuitable. Among the offenses committed by xmlformat, two are most notable:

- The text of the `<para>` element has been left alone, not reformatted.

- The `<screen>` element content has been reformatted, not left intact.

In these respects, it appears that xmlformat has done exactly the opposite of what was wanted! Furthermore, had you used the `-i` option to reformat the file in place without using `-b` to make a backup, at this point you would have a file containing a `<screen>` element that you'd have to fix up by hand to restore it to its original condition.

What a worthless, worthless program!

The rewriting of the `<screen>` element points to an important lesson: Before trusting xmlformat with your documents, it's best to run some tests and tune your configuration as necessary to make sure it will produce the results you want. Otherwise, you may produce changes that affect the integrity of your documents. This is particularly true when they contain elements such as `<screen>` or `<programlisting>` that should be copied verbatim, without change.

Configuring xmlformat amounts to writing a configuration file that instructs it what to do. For `doc2.xml`, that means telling xmlformat to leave the `<screen>` element alone, to normalize the text of the paragraph to fill lines and wrap them to a given length, and to put blank lines around sub-elements of the `<example>` element.

Let's begin by creating a very basic configuration file. What should we call it? xmlformat can read configuration settings from a file named on the command line with a `-f` or `--config-file` option. This means you can name the file whatever you want. However, if you put the settings in a file named `xmlformat.conf` in the current directory, xmlformat will read the file automatically. That's an easier approach, because you won't need to use a command-line option to specify the configuration file. So create a file named `xmlformat.conf` that contains the following two lines:

    screen
      format = verbatim

These lines specify that `<screen>` elements should be formatted as verbatim elements. That is, xmlformat should reproduce their content in the output exactly as it appears in the input, without modification. The first line must begin in column 1 (no preceding spaces or tabs). The second line must begin with at least one space or tab. Presence or absence of whitespace is how xmlformat distinguish the names of elements to be formatted from the instructions that indicate how to format them.

After creating `xmlformat.conf`, run xmlformat again to process `doc2.xml`. It reads the newly created configuration file and produces this result:

    <example>
     <title>Compiling and Running a Program</title>
     <para>To compile and run the program,
    use the following commands, where
    <replaceable>source-file</replaceable>
    is the name of the source file:</para>
    <screen>
    <userinput>cc</userinput> <replaceable>source-file</replaceable>
    <userinput>./a.out</userinput>
    </screen>
    </example>

That's a little better: xmlformat has not destroyed the `<screen>` element by reformatting it. But problems remain: The paragraph content has not been reformatted, and there are no blank lines between sub-elements.

Let's take care of the paragraph next. To set up its formatting, add a section to `xmlformat.conf` for `<para>` elements:

    para
      format = block
      normalize = yes
      wrap-length = 60
      subindent = 1

    screen
      format = verbatim

The order of sections in the configuration file doesn't matter. Put them in the order that makes most sense to you. The order of option lines under the initial section line doesn't matter, either.

The first two options in the `para` section specify that the `<para>` element is a block element, and that text within it should be normalized. Turning on the `normalize` option tells xmlformat that it's okay to reformat the text within the element. This means that runs of whitespace within the text are collapsed to single spaces, and that whitespace at the beginning and end of the text can be adjusted (typically to put the text on different lines than the element's opening and closing tags). Enabling normalization also allows you to perform text line-wrapping and indenting. The `wrap-length` option specifies the maximum number of characters per line, and `subindent` specifies the indenting of text and sub-elements, relative to the element's own tags. Note that when xmlformat performs line-wrapping, it includes the currently prevailing indent as part of the line length. (For example, if the prevailing indent is 20 spaces and `wrap-length` value is `60`, lines will contain at most 40 characters following the indentation.)

After adding the `para` section to `xmlformat.conf`, xmlformat produces this result:

    <example>
     <title>Compiling and Running a Program</title>
     <para>
      To compile and run the program, use the following
      commands, where
      <replaceable>source-file</replaceable>
      is the name of the source file:
     </para>
    <screen>
    <userinput>cc</userinput> <replaceable>source-file</replaceable>
    <userinput>./a.out</userinput>
    </screen>
    </example>

The paragraph now is wrapped and indented. However, it doesn't seem to be wrapped quite correctly, because the `<replaceable>` element actually would fit on the previous line. This happens because no formatting options were specified for `<replaceable>` in the configuration file. As a result, it is treated as having the default element type of `block`, using the default behavior that block elements are written out beginning on a new line.

To fix this problem, we should configure `<replaceable>` as an inline element. That will cause it to be formatted inline with the other text (and thus line-wrapped along with it). Modify the configuration file to include a `replaceable` section: this:

    para
      format = block
      normalize = yes
      wrap-length = 60
      subindent = 1

    replaceable
      format = inline

    screen
      format = verbatim

The resulting output after making this change is as follows:

    <example>
     <title>Compiling and Running a Program</title>
     <para>
      To compile and run the program, use the following
      commands, where <replaceable>source-file</replaceable> is
      the name of the source file:
     </para>
    <screen>
    <userinput>cc</userinput> <replaceable>source-file</replaceable>
    <userinput>./a.out</userinput>
    </screen>
    </example>

We're getting close now. All we need to do is space out the `<example>` child elements with a blank line in between. Sub-element spacing is controlled by three formatting properties:

- `entry-break` controls spacing after the opening tag of an element (that is, the spacing upon entry into the element's content).

- `element-break` controls the spacing between sub-elements.

- `exit-break` controls spacing before the closing tag of an element (that is, the spacing upon exit from the element's content).

The value for each of these formatting options should be an integer indicating the number of newlines to write. A value of `1` causes one newline, which acts simply to break to the next line. To get a blank line, the break value needs to be `2`. Modify the configuration file by adding a section for `<example>` elements:

    example
      format = block
      entry-break = 2
      element-break = 2
      exit-break = 2
      subindent = 0

    para
      format = block
      normalize = yes
      wrap-length = 60
      subindent = 1

    replaceable
      format = inline

    screen
      format = verbatim

The resulting output is:

    <example>

    <title>Compiling and Running a Program</title>

    <para>
     To compile and run the program, use the following commands,
     where <replaceable>source-file</replaceable> is the name of
     the source file:
    </para>

    <screen>
    <userinput>cc</userinput> <replaceable>source-file</replaceable>
    <userinput>./a.out</userinput>
    </screen>

    </example>

We're done!

You may be thinking, "Wow, that's a lot of messing around just to format that tiny little document." That's true. However, the effort of setting up configuration files tends to be "reusable," in the sense that you can use the same file to format multiple documents that all should be written using the same style. Also, if you have different projects requiring different styles, it tends to be easiest to begin setting up the configuration file for one project by beginning with a copy of the file from another project.

Prev |  | Next
2. Formatting a Document | Home | 4. Discovering "Inherited" Formatting Options