# How to Customize Row Separators in Outfancy Tables

> Learn how to customize row separators in outfancy tables by using the row_separator argument and controlling leading separators for enhanced table design.

- Repository: [Carlos A. Planchón/outfancy](https://github.com/carlosplanchon/outfancy)
- Tags: how-to-guide
- Published: 2026-02-26

---

**You can customize row separators in outfancy tables by passing a string to the `row_separator` argument of `Table.render()` and control whether a leading separator appears with `set_row_separator_before_table()`.**

The outfancy library provides flexible table formatting for terminal output. You can customize the row separators in outfancy tables to create visual boundaries between data rows or decorative borders that span the terminal width. This guide explains the specific mechanisms in [`outfancy/table.py`](https://github.com/carlosplanchon/outfancy/blob/main/outfancy/table.py) that control separator rendering.

## Using the `row_separator` Argument

The primary mechanism for customization is the **`row_separator`** parameter in the `Table.render()` method. Located at lines 259-266 in [`outfancy/table.py`](https://github.com/carlosplanchon/outfancy/blob/main/outfancy/table.py), this parameter accepts any string that will be drawn between each data row.

When you supply a custom separator, the internal **`check_row_separator`** method (lines 546-574) processes the string before rendering:

- If the string’s printed length is less than the terminal width, it repeats the pattern to fill the entire width.
- If the string exceeds the terminal width, it truncates the string to fit.
- If the argument is not a string or is `None`, the method returns `None` and no separator is rendered.

The **`printed_length`** utility from [`outfancy/widgets.py`](https://github.com/carlosplanchon/outfancy/blob/main/outfancy/widgets.py) handles width calculations, ensuring ANSI color codes do not skew the measurement.

## Controlling the Leading Separator Line

By default, outfancy prints a separator line above the first data row. You can toggle this behavior using the **`set_row_separator_before_table()`** method defined at lines 198-204 in [`outfancy/table.py`](https://github.com/carlosplanchon/outfancy/blob/main/outfancy/table.py).

This method sets the internal `row_separator_before_table` flag. During rendering, the **`generate_pre_table`** method (lines 1460-1470) checks this flag to determine whether to prepend the separator before the table body. Call `table.set_row_separator_before_table(False)` to suppress the leading line while keeping separators between rows.

## Complete Code Examples

```python
from outfancy.table import Table

# Sample data

data = [
    (1, "Alice", 23),
    (2, "Bob",   31),
    (3, "Carol", 27),
]

table = Table()

# 1️⃣ Default behaviour – a thin space separator (no visible line)

print("Default (no explicit row_separator):")
print(table.render(data))

# 2️⃣ Custom thin line using ASCII characters

print("\nCustom ASCII line separator:")
print(table.render(data, row_separator="─"))

# 3️⃣ Wide decorative separator (repeated to fill terminal width)

print("\nWide decorative separator (repeat to fill screen):")
print(table.render(data, row_separator="✦✦✦"))

# 4️⃣ Disable the leading separator line

print("\nNo leading separator line:")
table.set_row_separator_before_table(False)
print(table.render(data, row_separator="─"))

```

**Example 1** shows the default where `row_separator` is omitted, so no visual line appears between rows. **Example 2** supplies a single-character line that `check_row_separator` expands to the terminal width. **Example 3** demonstrates how multi-character patterns repeat to create decorative borders. **Example 4** uses `set_row_separator_before_table(False)` to remove the top border while retaining inter-row separators.

## Summary

- Pass a string to the `row_separator` argument in `Table.render()` to define custom line characters between rows.
- The `check_row_separator` method automatically expands short patterns to fill terminal width or truncates overflowing strings.
- Call `set_row_separator_before_table(False)` to remove the separator line that appears above the first data row.
- The core logic resides in [`outfancy/table.py`](https://github.com/carlosplanchon/outfancy/blob/main/outfancy/table.py), while [`outfancy/widgets.py`](https://github.com/carlosplanchon/outfancy/blob/main/outfancy/widgets.py) provides width calculation utilities that ignore ANSI codes.

## Frequently Asked Questions

### What happens if my row separator string is shorter than the terminal width?

The `check_row_separator` method in [`outfancy/table.py`](https://github.com/carlosplanchon/outfancy/blob/main/outfancy/table.py) automatically repeats your pattern until it spans the full terminal width. If your string contains ANSI color codes, the `printed_length` utility from [`outfancy/widgets.py`](https://github.com/carlosplanchon/outfancy/blob/main/outfancy/widgets.py) ensures only visible characters are measured during this expansion.

### Can I disable row separators completely?

Yes. Pass `row_separator=None` or simply omit the argument when calling `Table.render()`. The validation logic returns `None` for non-string values, which prevents `generate_pre_table` from inserting any separator lines between rows.

### How do I remove only the top separator line while keeping separators between rows?

Call `table.set_row_separator_before_table(False)` before rendering. This toggles the internal boolean flag that `generate_pre_table` checks at lines 1460-1470, suppressing the leading separator while preserving the lines that appear after each data row.

### Where is the row separator logic implemented in the outfancy source code?

According to the carlosplanchon/outfancy repository, the primary logic resides in [`outfancy/table.py`](https://github.com/carlosplanchon/outfancy/blob/main/outfancy/table.py). The `render()` method accepts the parameter at lines 259-266, `check_row_separator()` validates and formats the string at lines 546-574, and `generate_pre_table()` inserts the final separator at lines 1460-1470. Width calculations rely on helper functions defined in [`outfancy/widgets.py`](https://github.com/carlosplanchon/outfancy/blob/main/outfancy/widgets.py).