Skip to content

Using add_text with HTML formatting

Sandro Duarte edited this page Feb 16, 2026 · 1 revision

Using add_text with HTML formatting

add_text allows you to replace a placeholder with rich text content using basic HTML tags. Unlike add_field (which does plain text substitution), add_text parses HTML and converts it into ODF-formatted paragraphs.

Basic usage

report = ODFReport::Report.new("template.odt") do |r|
  r.add_text(:my_content, '<p>First paragraph</p><p>Second paragraph</p>')
end

The placeholder [MY_CONTENT] in your template will be replaced with two formatted paragraphs.

Supported HTML tags

Block-level elements

HTML tag ODF style applied Required template style
<p> (inherits from placeholder) none
<h1>, <h2> title yes
<blockquote><p>...</p></blockquote> quote yes
<p style="margin: ..."> quote yes

Inline elements

HTML tag ODF style applied Required template style
<strong> bold yes
<em> italic yes
<u> underline yes
<br> line break none

Template setup (important)

For inline formatting (<strong>, <em>, <u>) and paragraph styles (<h1>, <h2>, <blockquote>) to render correctly, your .odt template must define the corresponding character/paragraph styles. The parser generates ODF XML referencing these style names, but does not create the style definitions itself.

Step 1: Create character styles in your template

Open your template in LibreOffice Writer and create the following character styles (via menu View > Styles, then right-click on the character styles list and select New Style):

  • bold -- set font weight to Bold
  • italic -- set font style to Italic
  • underline -- set underlining to Single

The style names must match exactly (lowercase).

Step 2: Create paragraph styles (if using headings or blockquotes)

If you plan to use <h1>, <h2>, or <blockquote>, create these paragraph styles:

  • title -- configure as desired (e.g., larger font, bold)
  • quote -- configure as desired (e.g., indented, italic)

Step 3: Place your placeholder

In the template, type the placeholder (e.g., [MY_CONTENT]) inside a normal text paragraph. This paragraph node is used as the base template for each generated paragraph.

Examples

Simple paragraphs

r.add_text(:description, '<p>This is the first paragraph.</p><p>This is the second.</p>')

Inline formatting

r.add_text(:notes, '<p>This has <strong>bold</strong>, <em>italic</em>, and <u>underlined</u> text.</p>')

Headings and quotes

r.add_text(:article, <<-HTML)
  <h1>Article Title</h1>
  <p>Some introductory text.</p>
  <blockquote>
    <p>A quoted paragraph with <em>emphasis</em>.</p>
  </blockquote>
  <p>More regular text.</p>
HTML

Line breaks within a paragraph

r.add_text(:address, '<p>123 Main St<br>Suite 400<br>Springfield</p>')

Inside sections and tables

add_text works inside sections and tables, resolving values per collection item:

r.add_section("SC_ITEMS", @items) do |s|
  s.add_text(:item_description) { |item| item.html_description }
end

Troubleshooting

Formatting not applied: If your text appears but without bold/italic/underline, the most likely cause is that the required character styles are not defined in your template. Open the template in LibreOffice and verify that styles named exactly bold, italic, and underline exist.

Placeholder not replaced: Make sure the placeholder text (e.g., [MY_CONTENT]) is in a single text node. If you edit a placeholder in LibreOffice, it may split the text across multiple XML nodes. Delete the placeholder entirely and retype it.