> ## Documentation Index
> Fetch the complete documentation index at: https://helpdocs.gavel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Formatting Dates, Numbers, and Text

> Apply date display formats, currency and number formatting, case transforms, and special number patterns like SSNs to variables in document templates.

```text theme={null}
The {{ ordinal_number(DateVariable.day, use_word=False) }} day of {{ format_date(DateVariable, format='MMMM yyyy') }}
```

Output: *The 15th day of January 2025*

### Converting text to a date

If you are importing data from another system (such as Clio) where the date field arrives as plain text rather than a date type, use `as_datetime()` with `strftime` to convert it:

```text theme={null}
{{ as_datetime(variable).strftime("%B %d, %Y") }}
```

Use `%-d` instead of `%d` to suppress the leading zero (e.g., "January 3" instead of "January 03").

### Formatting dates using Calculations (Invisible Logic)

You can also format a date variable through Calculations. Create a new Text variable, select your date variable as the source, choose **Format Date** as the operation, and enter the format code. The resulting text variable can then be referenced anywhere in your document with `\{\{ FormattedDateVariable \}\}`.

***

## Calculating dates

These functions derive new date values from existing ones — useful for deadlines, notice periods, and age calculations.

<AccordionGroup>
  <Accordion title="Age or years elapsed from a date to today">
    ```text theme={null}
    {{ (date_difference(starting=DateVariable).years|int) }}
    ```
  </Accordion>

  <Accordion title="Years between two specific dates">
    ```text theme={null}
    {{ (date_difference(starting=StartDate, ending=EndDate).years|int) }}
    ```
  </Accordion>

  <Accordion title="Months between two dates">
    ```text theme={null}
    {{ (relative_date_difference(starting=StartDate, ending=EndDate).months) }}
    ```
  </Accordion>

  <Accordion title="Add or subtract calendar days, months, or years">
    ```text theme={null}
    {{ format_date( (DateVariable) + date_interval(years=2) ) }}
    ```

    Replace `years` with `months`, `days`, or `weeks`. Use `-` instead of `+` to go back in time.
  </Accordion>

  <Accordion title="Add or subtract business days">
    ```text theme={null}
    {{ format_date( (DateVariable) + date_interval(bus_days=10) ) }}
    ```
  </Accordion>

  <Accordion title="Next or prior business day">
    ```text theme={null}
    {{ next_business_day(DateVariable) }}
    {{ prior_business_day(DateVariable) }}
    ```
  </Accordion>

  <Accordion title="Last day of a month">
    ```text theme={null}
    {{ last_day_of_month(DateVariable) }}
    ```

    To extract just the day number (e.g., 30):

    ```text theme={null}
    {{ format_date(last_day_of_month(DateVariable), format='dd') }}
    ```
  </Accordion>
</AccordionGroup>

***

## Formatting numbers

Use a **Number** question type for decimal values and an **Integer** question type for whole numbers. Apply the functions below in your document template.

<Note>
  If you use a Number question type, decimal points display by default. If you use an Integer question type, you get a whole number.
</Note>

### Standard number formats

| Output example                    | Syntax                                             |
| --------------------------------- | -------------------------------------------------- |
| \$100,000.00                      | `\{\{ currency(variablename) \}\}`                 |
| 100000 *(no commas, no decimals)* | `\{\{ Decimals0NoCommas(variablename) \}\}`        |
| 100,000.00                        | `\{\{ Decimals2Commas(variablename) \}\}`          |
| 100,000                           | `\{\{ Decimals0Commas(variablename) \}\}`          |
| Custom decimals with commas       | `\{\{ format_decimal(variablename, 2) \}\}`        |
| Custom decimals without commas    | `\{\{ format_decimal(variablename, 2, False) \}\}` |

Replace the `2` in `format_decimal` with the number of decimal places you want.

### Ordinal numbers

Write a number as an ordinal (1st, 2nd, 10th, etc.):

```text theme={null}
{{ ordinal_number(variablename) }}
```

By default, first through ninth are written out as words (first, second, ... ninth). To use numerals throughout:

```text theme={null}
{{ ordinal_number(variablename, use_word=False) }}
```

### Numbers written as words

Convert a number to its written-out English form (recommended with the Integer question type):

```text theme={null}
{{ numbers_to_words(variablename) }}
```

Output: *One Hundred Thousand*

### International number formatting

```text theme={null}
{{ format_number_eu(variablename) }}
```

Output: *1.000.000,00* (European convention — periods as thousand separators, comma as decimal)

For Canadian French formatting:

```text theme={null}
{{ "{:,.2f} $".format(variablename).replace(",", " ").replace(".", ",") }}
```

Output: *1 000 000,00\$*

### Rounding in document templates

Round down (floor) to two decimal places:

```text theme={null}
{{ (variable)|round(2, 'floor') }}
```

Round up (ceiling) to two decimal places:

```text theme={null}
{{ (variable)|round(2, 'ceil') }}
```

When combining rounding with other number formatting, place the rounding call *inside* the parentheses:

```text theme={null}
{{ "{:,.0f}".format(variablename|round(0,'ceil')) }}
```

***

## Formatting special numbers

Use `number_custom()` to force specific punctuation patterns on any number. Have the client enter the value as a **Number** question type, then apply the mask in your template using `n` for each digit position.

<Tabs>
  <Tab title="Phone numbers">
    ```text theme={null}
    {{ number_custom(variablename, "(nnn) nnn-nnnn") }}
    ```

    Output: *(555) 555-5555*

    ```text theme={null}
    {{ number_custom(variablename, "nnn-nnn-nnnn") }}
    ```

    Output: *555-555-5555*
  </Tab>

  <Tab title="Social Security Numbers">
    SSN with dashes:

    ```text theme={null}
    {{ number_custom(variablename, "nnn-nn-nnnn") }}
    ```

    Output: *123-45-6789*

    SSN with first five digits masked:

    ```text theme={null}
    {{ number_custom(variablename, "XXX-XX-nnnn") }}
    ```

    Output: *XXX-XX-6789*
  </Tab>

  <Tab title="EINs">
    ```text theme={null}
    {{ number_custom(variablename, "nn-nnnnnn") }}
    ```

    Output: *12-3456789*
  </Tab>
</Tabs>

***

## Formatting words

These functions control capitalization and text transforms. If you want the output to match exactly what the client typed, you do not need any of the functions below.

### Case transforms

| Output example                           | Syntax                               |                                            |
| ---------------------------------------- | ------------------------------------ | ------------------------------------------ |
| APPLE *(all caps)*                       | \`\{\{ variablename                  | upper }}`or`\{\{ variablename.upper() }}\` |
| Apple And Pear *(title case)*            | `\{\{ title_case(variablename) \}\}` |                                            |
| Apple and pear *(capitalize first only)* | `\{\{ capitalize(variablename) \}\}` |                                            |
| apple *(all lowercase)*                  | \`\{\{ variablename                  | lower }}`or`\{\{ variablename.lower() }}\` |

### Articles and plurals

Add "a" or "an" before a variable automatically:

```text theme={null}
{{ indefinite_article(variablename) }}
```

Output: *An apple* / *A pear*

Pluralize a noun based on a count variable:

```text theme={null}
{{ quantity_noun(variablename, "apple") }}
```

Where `variablename` is an Integer. Output: *1 apple* / *3 apples*

### Punctuation

Add a trailing period only when the text does not already end with one (useful for company names):

```text theme={null}
{{ fix_punctuation(variablename) }}
```

### Verb conjugation

To conjugate a verb based on whether one person, multiple people, or a third-party singular is acting:

1. Create a multiple-choice question with variable name `conjugation` and choices: `1sg`, `3sg`, `pl`.
2. Use this syntax in your template (replacing `allege` with your verb):

```text theme={null}
{{ verb_present('allege', conjugation) }}
```

Output: *allege* (1sg), *alleges* (3sg), or *allege* (pl).

Alternatively, use basic conditional logic:

```text theme={null}
allege{% if singular %}s{% endif %}
```

***

## Formatting text area questions

Text area variables require special handling to preserve line breaks in the output.

| Goal                      | Syntax                                                                                             |                           |
| ------------------------- | -------------------------------------------------------------------------------------------------- | ------------------------- |
| Preserve line breaks      | \`\{\{ variablename                                                                                | manual\_line\_breaks }}\` |
| Output as a numbered list | `\{%p for line in VariableName.split("\n") %\}\{\{ loop.index \}\}. \{\{ line \}\}\{%p endfor %\}` |                           |
| Output as a bulleted list | `\{%p for line in VariableName.split("\n") %\}- \{\{ line \}\}\{%p endfor %\}`                     |                           |
| Join lines with commas    | `\{\{ commalist(VariableName.split("\\n"), "<__str__()>", "") \}\}`                                |                           |

The comma-list format is useful when a client enters a multi-line address and you need to output it inline, such as: *Jane Doe, 123 Main Street, Minneapolis, MN 55436*.

***

## Formatting Multi-Select questions

Multi-Select questions have several output formats you can use in Word document templates.

**As a bulleted list:**

```text theme={null}
{% for item in variablename.true_values() %}
- {{ item }}
{% endfor %}
```

**Count the number of selections:**

```text theme={null}
{{ variablename.number() }}
```

**Conditional on number of selections:**

```text theme={null}
{% if variablename.number() > 2 %}You chose more than 2!{% endif %}
```

**Preserve the order you defined (non-alphabetical):**

```text theme={null}
{% for key, value in variablename.elements.items() if value %}{{ key }} {% endfor %}
```

***

## Accepting or rejecting variables in Gavel Blueprint

When you upload a document to **Gavel Blueprint**, the AI identifies variable placeholders in your template and suggests questions for each one. You review these suggestions and either accept or reject each proposed variable.

<Steps>
  <Step title="Review variables in the sidebar">
    After uploading your document, scroll through the content or use the variable sidebar. Blueprint highlights each location where it detected a variable.
  </Step>

  <Step title="Accept or reject each variable">
    Accept variables that correspond to genuine client-provided data. Reject any that Blueprint identified incorrectly — for example, static text it mistook for a placeholder.
  </Step>

  <Step title="Generate the draft workflow">
    Once you have reviewed all variables, click **Draft Workflow**. Gavel generates a first draft of the workflow, including all accepted variables as questions. You can then edit question wording, types, and order in the builder, and use the Word add-in or PDF Tagger to fine-tune the template markup.
  </Step>
</Steps>

<Tip>
  You can edit all question details — wording, type, variable name — after the workflow is generated. There is no need to get every detail perfect during the Blueprint review step.
</Tip>
