Working with DITA Codeblocks in FrameMaker

When using a DITA <codeblock> element, the intent is for all of the code to be enclosed in a single <codeblock> element (to the extent that it makes sense). From time to time I see documents where each line is in a separate <codeblock>. While this may “work,” it’s not an idea way to operate. If the intent was to put single code lines in a <codeblock>, it would have been called “codeline”!

Here’s the one-line-per-codeblock approach (not ideal),
codeblocks-wrong

and here’s the recommended method.
codeblocks-right

If you’re using FrameMaker, this can happen without consciously realizing it. You may insert a <codeblock>, type the first line and press ENTER, then type the next line and press ENTER again. Each time you press ENTER, you’re creating a new <codeblock> element.

Another problem can happen when you copy and paste from a text file. You insert a <codeblock> then paste the code that you copied from the source file. It looks reasonable (except for the “end of paragraph” symbols), and you save the file and move on.
after-paste

The next time you open the file, the code is all messed up, it’s essentially all on one line that may wrap down the page. Not at all what you had intended!
reopen-after-paste

In order to properly format a <codeblock>, you need to end each line with a “forced return” (aka. “soft return” or “line break”); press the SHIFT+ENTER keys to get a new line. If you do this, your lines will be properly formatted and will remain as a single block of code.

The “trick” to pasting in content from another file is as follows:

  1. Insert the <codeblock> element, then place the insertion point inside the element and paste the code.
  2. Open the Find dialog and select the <codeblock> element.
  3. Enter “\p” as the Find text, and enter “\r” as the Change text.
  4. Select “Look in: Selection” and choose Change All.

before-replace

This is what you’ll see after replacing the end of paragraph (Pilcrow) symbols with forced returns.
after-replace

Does this code have tabs? It’s typically a good idea to replace tabs with spaces (not required, but a good practice). Use the same process to replace all tabs with 4 spaces (or whatever makes sense for your code).

  1. Open the Find dialog and select the <codeblock> element.
  2. Enter “\t” as the Find text, and enter “␣␣␣␣” (4 spaces) as the Change text.
  3. Select “Look in: Selection” and choose Change All.

Of course .. if you’re using FM11 or FM12, you can always just switch to the XML Code View and paste the code directly in there! As long as the code doesn’t include angle brackets, which you’ll need to manually replace with entities (&lt; and &gt;), and tabs, which you’ll need to replace with spaces, this option works great!

(Be aware that in FM11, the Code View feature has a problem with indented code lines. It’s likely that any indents will be lost if you flip between WYSIWYG and Code View. FM12 has fixed this problem.)

The techniques above work equally well for the other “preformatted” elements, <pre>, <msgblock>, and <screen>.

That all works fine with DITA 1.1 files, but if you’re using DITA 1.2, you can take advantage of the <coderef> element! A <coderef> is just what it sounds like, a reference to a code file. Essentially it’s a “conref” to a non-DITA file used for code samples. A <coderef> must be inserted into a <codeblock>, and if needed you can include multiple <coderef> elements in a <codeblock> or mix hard-coded text with a <coderef>, it’s up to you.

The default FrameMaker DITA support (in FM11 and FM12) doesn’t properly handle <coderef> elements, hopefully that will be fixed in an update to FM12. But if you are using DITA-FMx 2.0, you can use this feature. See the blog post Using Coderefs in DITA-FMx for details.

If you’re interested in the possibility of using syntax-based formatting in your code samples in FrameMaker, watch for the CodeFormatter plugin from Leximation. It’s currently in beta testing, but will be available soon. This is intended as a “publishing plugin” for the DITA-FMx book-build process (the formatting is applied when the book is built), but can be used as a stand-alone command or called from other scripting, so it can be used even if you’re not using DITA-FMx.